aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2192-drm-amdgpu-Share-eviction-fence-with-KFD.patch
blob: 5a52804fca4a0e3db1632947784f286ea55fff11 (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
From b341257f6b08b128e92992cb903801b2086ec5d7 Mon Sep 17 00:00:00 2001
From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Date: Wed, 8 Nov 2017 15:36:47 -0500
Subject: [PATCH 2192/4131] drm/amdgpu: Share eviction fence with KFD

Currently, when TTM wants to evict a process BO,
dma_fence_ops.enable_signaling() calls KFD call back function
evict_and_restore_process(fence *eviction_fence) to prepare for
eviction. This function starts a worker thread that handles suspending
the process and signaling the eviction fence.

However, during suspend / resume, KFD cannot reliably depend on this
eviction sequence. This change is necessary to handle suspend / resume
sequence by KFD.

Change-Id: I342e64a4986225246d8fff21b9c96f2c844648ad
Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h       |  6 ++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |  7 +++++--
 drivers/gpu/drm/amd/amdkfd/kfd_device.c          | 11 ++++++++++-
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h            |  5 +++++
 drivers/gpu/drm/amd/amdkfd/kfd_process.c         |  6 ++++--
 drivers/gpu/drm/amd/include/kgd_kfd_interface.h  |  4 ++--
 6 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 0756fff..b4e26d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -143,7 +143,8 @@ int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem, struct mm_struct *mm);
 int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
 				uint32_t vmid, uint64_t gpu_addr,
 				uint32_t *ib_cmd, uint32_t ib_len);
-int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info);
+int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
+					    struct dma_fence **ef);
 struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void);
 struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void);
 struct kfd2kgd_calls *amdgpu_amdkfd_gfx_9_0_get_functions(void);
@@ -205,7 +206,8 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
 		struct kgd_dev *kgd, struct kgd_mem *mem, void *vm);
 
 int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
-					  void **process_info);
+					  void **process_info,
+					  struct dma_fence **ef);
 void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm);
 
 uint32_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 1ce6359..ec81a41 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1375,7 +1375,8 @@ static u64 get_vm_pd_gpu_offset(void *vm)
 }
 
 int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
-					  void **process_info)
+					  void **process_info,
+					  struct dma_fence **ef)
 {
 	int ret;
 	struct amdkfd_vm *new_vm;
@@ -1424,6 +1425,7 @@ int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
 				  amdgpu_amdkfd_restore_userptr_worker);
 
 		*process_info = info;
+		*ef = dma_fence_get(&info->eviction_fence->base);
 	}
 
 	new_vm->process_info = *process_info;
@@ -2274,7 +2276,7 @@ static void amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work)
  * 8.  Unreserve all BOs
  */
 
-int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info)
+int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
 {
 	struct amdgpu_bo_list_entry *pd_bo_list;
 	struct amdkfd_process_info *process_info = info;
@@ -2381,6 +2383,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info)
 	}
 	dma_fence_put(&process_info->eviction_fence->base);
 	process_info->eviction_fence = new_fence;
+	*ef = dma_fence_get(&new_fence->base);
 
 	/* Wait for validate to finish and attach new eviction fence */
 	list_for_each_entry(mem, &process_info->kfd_bo_list,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 3506e6b..3cf791b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -946,7 +946,7 @@ void kfd_restore_bo_worker(struct work_struct *work)
 	 */
 
 	p->last_restore_timestamp = get_jiffies_64();
-	ret = pdd->dev->kfd2kgd->restore_process_bos(p->process_info);
+	ret = pdd->dev->kfd2kgd->restore_process_bos(p->process_info, &p->ef);
 	if (ret) {
 		pr_info("Restore failed, try again after %d ms\n",
 			PROCESS_BACK_OFF_TIME_MS);
@@ -1050,6 +1050,15 @@ void kfd_evict_bo_worker(struct work_struct *work)
 	ret = quiesce_process_mm(p);
 	if (!ret) {
 		dma_fence_signal(eviction_work->quiesce_fence);
+		WARN_ONCE(eviction_work->quiesce_fence != p->ef,
+			 "Eviction fence mismatch\n");
+		dma_fence_put(p->ef);
+		/* TODO: quiesce_fence is same as kfd_process->ef. But
+		 * quiesce_fence is also used to avoid starting multiple
+		 * eviction work items. This might not be necessary and
+		 * one of the variables could be removed
+		 */
+		p->ef = NULL;
 		schedule_delayed_work(&p->restore_work,
 				msecs_to_jiffies(PROCESS_RESTORE_TIME_MS));
 	} else
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index e263c99..bfd8952 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -725,6 +725,11 @@ struct kfd_process {
 
 	/* Information used for memory eviction */
 	void *process_info;
+	/* Eviction fence that is attached to all the BOs of this process. The
+	 * fence will be triggered during eviction and new one will be created
+	 * during restore
+	 */
+	struct dma_fence *ef;
 
 	/* Work items for evicting and restoring BOs */
 	struct kfd_eviction_work eviction_work;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index f737e17..e8fe04e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -369,9 +369,11 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
 			kfd_flush_tlb(pdd->dev, p->pasid);
 
 		/* Destroy the GPUVM VM context */
-		if (pdd->vm)
+		if (pdd->vm) {
+			dma_fence_put(p->ef);
 			pdd->dev->kfd2kgd->destroy_process_vm(
 				pdd->dev->kgd, pdd->vm);
+		}
 		list_del(&pdd->per_device_list);
 
 		if (pdd->qpd.cwsr_pages) {
@@ -724,7 +726,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
 
 	/* Create the GPUVM context for this specific device */
 	if (dev->kfd2kgd->create_process_vm(dev->kgd, &pdd->vm,
-					&p->process_info)) {
+					&p->process_info, &p->ef)) {
 		pr_err("Failed to create process VM object\n");
 		goto err_create_pdd;
 	}
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
index 99213fb..877d966 100644
--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
@@ -267,7 +267,7 @@ struct kfd2kgd_calls {
 	uint32_t (*get_max_engine_clock_in_mhz)(struct kgd_dev *kgd);
 
 	int (*create_process_vm)(struct kgd_dev *kgd, void **vm,
-				 void **process_info);
+				 void **process_info, struct dma_fence **ef);
 	void (*destroy_process_vm)(struct kgd_dev *kgd, void *vm);
 
 	int (*create_process_gpumem)(struct kgd_dev *kgd, uint64_t va, size_t size, void *vm, struct kgd_mem **mem);
@@ -400,7 +400,7 @@ struct kfd2kgd_calls {
 	int (*get_tile_config)(struct kgd_dev *kgd,
 			struct tile_config *config);
 
-	int (*restore_process_bos)(void *process_info);
+	int (*restore_process_bos)(void *process_info, struct dma_fence **ef);
 	int (*copy_mem_to_mem)(struct kgd_dev *kgd, struct kgd_mem *src_mem,
 			uint64_t src_offset, struct kgd_mem *dst_mem,
 			uint64_t dest_offset, uint64_t size,
-- 
2.7.4