aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/2864-drm-amdkfd-Implement-suspend-node-grace-period.patch
blob: 9cd486b1ce5b028dd266aab11b010adb31b5a9b4 (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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
From 9f91bb641d12975a65f051fd707fad68f1d11a30 Mon Sep 17 00:00:00 2001
From: Philip Cox <Philip.Cox@amd.com>
Date: Thu, 30 May 2019 09:50:59 -0400
Subject: [PATCH 2864/2940] drm/amdkfd: Implement suspend node grace period.

Add the grace period for the KFD debugger when suspending waves.

Change-Id: I63bd1a6f23194ce7abe3a9417ad1ccfe843f38c1
Signed-off-by: Philip Cox <Philip.Cox@amd.com>
---
 .../drm/amd/amdkfd/kfd_device_queue_manager.c | 73 +++++++++++++------
 .../drm/amd/amdkfd/kfd_device_queue_manager.h |  2 +
 .../gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c  |  3 +
 .../gpu/drm/amd/amdkfd/kfd_packet_manager.c   | 32 ++++++++
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |  2 +
 5 files changed, 91 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index fceb8fdf01b9..603672d63f22 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -45,10 +45,12 @@ static int set_pasid_vmid_mapping(struct device_queue_manager *dqm,
 
 static int execute_queues_cpsch(struct device_queue_manager *dqm,
 								enum kfd_unmap_queues_filter filter,
-								uint32_t filter_param);
+								uint32_t filter_param,
+								uint32_t grace_period);
 static int unmap_queues_cpsch(struct device_queue_manager *dqm,
 							  enum kfd_unmap_queues_filter filter,
-							  uint32_t filter_param);
+							  uint32_t filter_param,
+							  uint32_t grace_period);
 
 static int map_queues_cpsch(struct device_queue_manager *dqm);
 
@@ -541,7 +543,8 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
   /* Make sure the queue is unmapped before updating the MQD */
   if (dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) {
 	retval = unmap_queues_cpsch(dqm,
-								KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
+								KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
+								USE_DEFAULT_GRACE_PERIOD);
 	if (retval) {
 	  pr_err("unmap queue failed\n");
 	  goto out_unlock;
@@ -724,7 +727,8 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
   retval = execute_queues_cpsch(dqm,
 								qpd->is_debug ?
 								KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES :
-								KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
+								KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
+								USE_DEFAULT_GRACE_PERIOD);
 
 out:
   dqm_unlock(dqm);
@@ -842,7 +846,8 @@ static int restore_process_queues_cpsch(struct device_queue_manager *dqm,
 	dqm->queue_count++;
   }
   retval = execute_queues_cpsch(dqm,
-								KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
+								KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
+								USE_DEFAULT_GRACE_PERIOD);
   qpd->evicted = 0;
 out:
   dqm_unlock(dqm);
@@ -1139,7 +1144,8 @@ static int start_cpsch(struct device_queue_manager *dqm)
   dqm_lock(dqm);
   /* clear hang status when driver try to start the hw scheduler */
   dqm->is_hws_hang = false;
-  execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
+  execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
+					   USE_DEFAULT_GRACE_PERIOD);
   dqm_unlock(dqm);
 
   return 0;
@@ -1153,7 +1159,8 @@ static int start_cpsch(struct device_queue_manager *dqm)
 static int stop_cpsch(struct device_queue_manager *dqm)
 {
   dqm_lock(dqm);
-  unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
+  unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0,
+					 USE_DEFAULT_GRACE_PERIOD);
   dqm_unlock(dqm);
 
   kfd_gtt_sa_free(dqm->dev, dqm->fence_mem);
@@ -1185,7 +1192,8 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm,
   list_add(&kq->list, &qpd->priv_queue_list);
   dqm->queue_count++;
   qpd->is_debug = true;
-  execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
+  execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
+					   USE_DEFAULT_GRACE_PERIOD);
   dqm_unlock(dqm);
 
   return 0;
@@ -1199,7 +1207,8 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm,
   list_del(&kq->list);
   dqm->queue_count--;
   qpd->is_debug = false;
-  execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
+  execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0,
+					   USE_DEFAULT_GRACE_PERIOD);
   /*
    * Unconditionally decrement this counter, regardless of the queue's
    * type.
@@ -1266,7 +1275,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
 	if (q->properties.is_active) {
 		dqm->queue_count++;
 		retval = execute_queues_cpsch(dqm,
-				KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
+				KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
+				USE_DEFAULT_GRACE_PERIOD);
 	}
 
 	if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
@@ -1361,7 +1371,8 @@ static int map_queues_cpsch(struct device_queue_manager *dqm)
 /* dqm->lock mutex has to be locked before calling this function */
 static int unmap_queues_cpsch(struct device_queue_manager *dqm,
 				enum kfd_unmap_queues_filter filter,
-				uint32_t filter_param)
+				uint32_t filter_param,
+				uint32_t grace_period)
 {
 	int retval = 0;
 
@@ -1373,6 +1384,12 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
 	pr_debug("Before destroying queues, sdma queue count is : %u, xgmi sdma queue count is : %u\n",
 		dqm->sdma_queue_count, dqm->xgmi_sdma_queue_count);
 
+	if (grace_period != USE_DEFAULT_GRACE_PERIOD) {
+		retval = pm_update_grace_period(&dqm->packets, grace_period);
+		if (retval)
+			return retval;
+	}
+
 	if (dqm->sdma_queue_count > 0 || dqm->xgmi_sdma_queue_count)
 		unmap_sdma_queues(dqm);
 
@@ -1380,7 +1397,6 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
 			filter, filter_param, false, 0);
 	if (retval)
 		return retval;
-
 	*dqm->fence_addr = KFD_FENCE_INIT;
 	pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr,
 				KFD_FENCE_COMPLETED);
@@ -1390,6 +1406,13 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
 	if (retval)
 		return retval;
 
+	/* We need to reset the grace period value for this device */
+	if (grace_period != USE_DEFAULT_GRACE_PERIOD) {
+		if (pm_update_grace_period(&dqm->packets,
+					USE_DEFAULT_GRACE_PERIOD))
+			pr_err("Failed to reset grace period\n");
+	}
+
 	pm_release_ib(&dqm->packets);
 	dqm->active_runlist = false;
 
@@ -1399,13 +1422,14 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
 /* dqm->lock mutex has to be locked before calling this function */
 static int execute_queues_cpsch(struct device_queue_manager *dqm,
 				enum kfd_unmap_queues_filter filter,
-				uint32_t filter_param)
+				uint32_t filter_param,
+				uint32_t grace_period)
 {
 	int retval;
 
 	if (dqm->is_hws_hang)
 		return -EIO;
-	retval = unmap_queues_cpsch(dqm, filter, filter_param);
+	retval = unmap_queues_cpsch(dqm, filter, filter_param, grace_period);
 	if (retval) {
 		pr_err("The cp might be in an unrecoverable state due to an unsuccessful queues preemption\n");
 		dqm->is_hws_hang = true;
@@ -1456,7 +1480,8 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
 	if (q->properties.is_active) {
 		dqm->queue_count--;
 		retval = execute_queues_cpsch(dqm,
-				KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
+				KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
+				USE_DEFAULT_GRACE_PERIOD);
 		if (retval == -ETIME)
 			qpd->reset_wavefronts = true;
 	}
@@ -1688,7 +1713,8 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
 		}
 	}
 
-	retval = execute_queues_cpsch(dqm, filter, 0);
+	retval = execute_queues_cpsch(dqm, filter, 0,
+			USE_DEFAULT_GRACE_PERIOD);
 	if ((!dqm->is_hws_hang) && (retval || qpd->reset_wavefronts)) {
 		pr_warn("Resetting wave fronts (cpsch) on dev %p\n", dqm->dev);
 		dbgdev_wave_reset_wavefronts(dqm->dev, qpd->pqm->process);
@@ -1939,7 +1965,8 @@ int reserve_debug_trap_vmid(struct device_queue_manager *dqm)
 		goto out_unlock;
 	}
 
-	r = unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
+	r = unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0,
+			USE_DEFAULT_GRACE_PERIOD);
 	if (r)
 		goto out_unlock;
 
@@ -1985,7 +2012,8 @@ int release_debug_trap_vmid(struct device_queue_manager *dqm)
 		goto out_unlock;
 	}
 
-	r = unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
+	r = unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0,
+			USE_DEFAULT_GRACE_PERIOD);
 	if (r)
 		goto out_unlock;
 
@@ -2116,7 +2144,8 @@ int suspend_queues(struct kfd_process *p,
 
 		if (queues_suspended_on_device) {
 			r = execute_queues_cpsch(dqm,
-				KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
+				KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
+				grace_period);
 			if (r) {
 				pr_err("Failed to suspend process queues.\n");
 				dqm_unlock(dqm);
@@ -2187,7 +2216,8 @@ int resume_queues(struct kfd_process *p,
 		if (queues_resumed_on_device) {
 			r = execute_queues_cpsch(dqm,
 					KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES,
-					0);
+					0,
+					USE_DEFAULT_GRACE_PERIOD);
 			if (r) {
 				pr_err("Failed to resume process queues\n");
 				dqm_unlock(dqm);
@@ -2290,7 +2320,8 @@ int dqm_debugfs_execute_queues(struct device_queue_manager *dqm)
 
 	dqm_lock(dqm);
 	dqm->active_runlist = true;
-	r = execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
+	r = execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0,
+			USE_DEFAULT_GRACE_PERIOD);
 	dqm_unlock(dqm);
 
 	return r;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index 90339e5a6fa9..fcab7ad80512 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -32,6 +32,8 @@
 #include "kfd_mqd_manager.h"
 
 
+#define USE_DEFAULT_GRACE_PERIOD 0xffffffff
+
 struct device_process_node {
 	struct qcm_process_device *qpd;
 	struct list_head list;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c
index 9da582786657..d315f4dc2f8d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_v9.c
@@ -223,6 +223,9 @@ static int pm_set_grace_period_v9(struct packet_manager *pm,
 			&reg_offset,
 			&reg_data);
 
+	if (grace_period == USE_DEFAULT_GRACE_PERIOD)
+		reg_data = pm->dqm->wait_times;
+
 	packet = (struct pm4_mec_write_data_mmio *)buffer;
 	memset(buffer, 0, sizeof(struct pm4_mec_write_data_mmio));
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
index ccf6b2310316..73b93286af3b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
@@ -369,6 +369,38 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
 	return retval;
 }
 
+int pm_update_grace_period(struct packet_manager *pm, uint32_t grace_period)
+{
+	int retval = 0;
+	uint32_t *buffer, size;
+
+	size = pm->pmf->set_grace_period_size;
+
+	mutex_lock(&pm->lock);
+
+	if (size) {
+		pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
+			size / sizeof(uint32_t),
+			(unsigned int **)&buffer);
+
+		if (!buffer) {
+			pr_err("Failed to allocate buffer on kernel queue\n");
+			retval = -ENOMEM;
+			goto out;
+		}
+
+		retval = pm->pmf->set_grace_period(pm, buffer, grace_period);
+		if (!retval)
+			pm->priv_queue->ops.submit_packet(pm->priv_queue);
+		else
+			pm->priv_queue->ops.rollback_packet(pm->priv_queue);
+	}
+
+out:
+	mutex_unlock(&pm->lock);
+	return retval;
+}
+
 int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
 			enum kfd_unmap_queues_filter filter,
 			uint32_t filter_param, bool reset,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index afbe9b3d7fda..b227f3b2ba9c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1112,6 +1112,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
 
 void pm_release_ib(struct packet_manager *pm);
 
+int pm_update_grace_period(struct packet_manager *pm, uint32_t grace_period);
+
 /* Following PM funcs can be shared among VI and AI */
 unsigned int pm_build_pm4_header(unsigned int opcode, size_t packet_size);
 int pm_set_resources_vi(struct packet_manager *pm, uint32_t *buffer,
-- 
2.17.1