aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1306-drm-amdkfd-Flush-TLBs-after-syncing-with-page-table-.patch
blob: 7bc4f824d04946f3f899805fc6774c67522dd174 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
From 345235c63bec2de99e77fd8b7ec9084469f79785 Mon Sep 17 00:00:00 2001
From: Felix Kuehling <Felix.Kuehling@amd.com>
Date: Tue, 11 Jul 2017 17:57:48 -0400
Subject: [PATCH 1306/4131] drm/amdkfd: Flush TLBs after syncing with page
 table update

Flushing TLBs must happen after the page table update is completed
in memory. The helper function kfd_map_memory_to_gpu cannot be
used any more because sync needs to happen between map and flush.
Update all callers to implement the correct map, sync, flush
sequence and remove helper function.

Bug: SWDEV-126375

Change-Id: Iecf5972a87e4bae6ad68d06e0d0589c1a2755927
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 38 ++++++++++++++++----------------
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h    |  1 -
 drivers/gpu/drm/amd/amdkfd/kfd_process.c |  5 ++++-
 3 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index dbc3afd..814ad7f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -1301,23 +1301,6 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
 	return ret;
 }
 
-int kfd_map_memory_to_gpu(void *mem, struct kfd_process_device *pdd)
-{
-	int err;
-	struct kfd_dev *dev = pdd->dev;
-
-	err = dev->kfd2kgd->map_memory_to_gpu(
-		dev->kgd, (struct kgd_mem *) mem, pdd->vm);
-
-	/* Theoretically we don't need this flush. However, as there are
-	 * some bugs in our PTE handling for mapping and unmapping, we
-	 * need this flush to pass all the tests.
-	 */
-	kfd_flush_tlb(dev, pdd->process->pasid);
-
-	return err;
-}
-
 static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
 					struct kfd_process *p, void *data)
 {
@@ -1388,12 +1371,14 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
 				err = -EFAULT;
 				goto get_mem_obj_from_handle_failed;
 			}
-			err = kfd_map_memory_to_gpu(mem, peer_pdd);
+			err = peer->kfd2kgd->map_memory_to_gpu(
+				peer->kgd, (struct kgd_mem *)mem, peer_pdd->vm);
 			if (err != 0)
 				pr_err("Failed to map\n");
 		}
 	} else {
-		err = kfd_map_memory_to_gpu(mem, pdd);
+		err = dev->kfd2kgd->map_memory_to_gpu(
+			dev->kgd, (struct kgd_mem *)mem, pdd->vm);
 		if (err != 0)
 			pr_err("Failed to map\n");
 	}
@@ -1404,6 +1389,21 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
 		goto sync_memory_failed;
 	}
 
+	/* Flush TLBs after waiting for the page table updates to complete */
+	if (args->device_ids_array_size > 0) {
+		for (i = 0; i < num_dev; i++) {
+			peer = kfd_device_by_id(devices_arr[i]);
+			if (WARN_ON_ONCE(!peer))
+				continue;
+			peer_pdd = kfd_get_process_device_data(dev, p);
+			if (WARN_ON_ONCE(!peer_pdd))
+				continue;
+			kfd_flush_tlb(peer, p->pasid);
+		}
+	} else {
+		kfd_flush_tlb(dev, p->pasid);
+	}
+
 	if (args->device_ids_array_size > 0 && devices_arr)
 		kfree(devices_arr);
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index d8ab0a4..76c6fda 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -807,7 +807,6 @@ void run_rdma_free_callback(struct kfd_bo *buf_obj);
 struct kfd_process *kfd_lookup_process_by_pid(struct pid *pid);
 
 /* kfd dgpu memory */
-int kfd_map_memory_to_gpu(void *mem, struct kfd_process_device *pdd);
 int kfd_unmap_memory_from_gpu(void *mem, struct kfd_process_device *pdd);
 
 /* Process device data iterator */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index f5e2282..5770b1d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -132,7 +132,8 @@ static int kfd_process_alloc_gpuvm(struct kfd_process *p,
 	if (err)
 		goto err_alloc_mem;
 
-	err = kfd_map_memory_to_gpu(mem, pdd);
+	err = kdev->kfd2kgd->map_memory_to_gpu(
+				kdev->kgd, (struct kgd_mem *)mem, pdd->vm);
 	if (err)
 		goto err_map_mem;
 
@@ -143,6 +144,8 @@ static int kfd_process_alloc_gpuvm(struct kfd_process *p,
 		goto sync_memory_failed;
 	}
 
+	kfd_flush_tlb(kdev, p->pasid);
+
 	/* Create an obj handle so kfd_process_device_remove_obj_handle
 	 * will take care of the bo removal when the process finishes.
 	 * We do not need to take p->lock, because the process is just
-- 
2.7.4