xref: /linux/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c (revision deb879faa9d2f327ac5c079d9d1a1747b79260e3)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2024 Intel Corporation
4  */
5 
6 #include <drm/drm_managed.h>
7 
8 #include "regs/xe_guc_regs.h"
9 
10 #include "abi/guc_actions_sriov_abi.h"
11 #include "xe_bo.h"
12 #include "xe_ggtt.h"
13 #include "xe_gt.h"
14 #include "xe_gt_sriov_pf.h"
15 #include "xe_gt_sriov_pf_config.h"
16 #include "xe_gt_sriov_pf_control.h"
17 #include "xe_gt_sriov_pf_helpers.h"
18 #include "xe_gt_sriov_pf_migration.h"
19 #include "xe_gt_sriov_printk.h"
20 #include "xe_guc.h"
21 #include "xe_guc_buf.h"
22 #include "xe_guc_ct.h"
23 #include "xe_migrate.h"
24 #include "xe_mmio.h"
25 #include "xe_sriov.h"
26 #include "xe_sriov_packet.h"
27 #include "xe_sriov_packet_types.h"
28 #include "xe_sriov_pf_migration.h"
29 
30 #define XE_GT_SRIOV_PF_MIGRATION_RING_SIZE 5
31 
pf_pick_gt_migration(struct xe_gt * gt,unsigned int vfid)32 static struct xe_gt_sriov_migration_data *pf_pick_gt_migration(struct xe_gt *gt, unsigned int vfid)
33 {
34 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
35 	xe_gt_assert(gt, vfid != PFID);
36 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
37 
38 	return &gt->sriov.pf.vfs[vfid].migration;
39 }
40 
pf_dump_mig_data(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data,const char * what)41 static void pf_dump_mig_data(struct xe_gt *gt, unsigned int vfid,
42 			     struct xe_sriov_packet *data,
43 			     const char *what)
44 {
45 	if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) {
46 		struct drm_printer p = xe_gt_dbg_printer(gt);
47 
48 		drm_printf(&p, "VF%u %s (%llu bytes)\n", vfid, what, data->hdr.size);
49 		drm_print_hex_dump(&p, "mig_hdr:  ", (void *)&data->hdr, sizeof(data->hdr));
50 		drm_print_hex_dump(&p, "mig_data: ", data->vaddr, min(SZ_64, data->hdr.size));
51 	}
52 }
53 
pf_migration_ggtt_size(struct xe_gt * gt,unsigned int vfid)54 static ssize_t pf_migration_ggtt_size(struct xe_gt *gt, unsigned int vfid)
55 {
56 	if (!xe_gt_is_main_type(gt))
57 		return 0;
58 
59 	return xe_gt_sriov_pf_config_ggtt_save(gt, vfid, NULL, 0);
60 }
61 
pf_save_vf_ggtt_mig_data(struct xe_gt * gt,unsigned int vfid)62 static int pf_save_vf_ggtt_mig_data(struct xe_gt *gt, unsigned int vfid)
63 {
64 	struct xe_sriov_packet *data;
65 	size_t size;
66 	int ret;
67 
68 	size = pf_migration_ggtt_size(gt, vfid);
69 	xe_gt_assert(gt, size);
70 
71 	data = xe_sriov_packet_alloc(gt_to_xe(gt));
72 	if (!data)
73 		return -ENOMEM;
74 
75 	ret = xe_sriov_packet_init(data, gt->tile->id, gt->info.id,
76 				   XE_SRIOV_PACKET_TYPE_GGTT, 0, size);
77 	if (ret)
78 		goto fail;
79 
80 	ret = xe_gt_sriov_pf_config_ggtt_save(gt, vfid, data->vaddr, size);
81 	if (ret)
82 		goto fail;
83 
84 	pf_dump_mig_data(gt, vfid, data, "GGTT data save");
85 
86 	ret = xe_gt_sriov_pf_migration_save_produce(gt, vfid, data);
87 	if (ret)
88 		goto fail;
89 
90 	return 0;
91 
92 fail:
93 	xe_sriov_packet_free(data);
94 	xe_gt_sriov_err(gt, "Failed to save VF%u GGTT data (%pe)\n", vfid, ERR_PTR(ret));
95 	return ret;
96 }
97 
pf_restore_vf_ggtt_mig_data(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)98 static int pf_restore_vf_ggtt_mig_data(struct xe_gt *gt, unsigned int vfid,
99 				       struct xe_sriov_packet *data)
100 {
101 	int ret;
102 
103 	pf_dump_mig_data(gt, vfid, data, "GGTT data restore");
104 
105 	ret = xe_gt_sriov_pf_config_ggtt_restore(gt, vfid, data->vaddr, data->hdr.size);
106 	if (ret) {
107 		xe_gt_sriov_err(gt, "Failed to restore VF%u GGTT data (%pe)\n",
108 				vfid, ERR_PTR(ret));
109 		return ret;
110 	}
111 
112 	return 0;
113 }
114 
115 /**
116  * xe_gt_sriov_pf_migration_ggtt_save() - Save VF GGTT migration data.
117  * @gt: the &xe_gt
118  * @vfid: the VF identifier (can't be 0)
119  *
120  * This function is for PF only.
121  *
122  * Return: 0 on success or a negative error code on failure.
123  */
xe_gt_sriov_pf_migration_ggtt_save(struct xe_gt * gt,unsigned int vfid)124 int xe_gt_sriov_pf_migration_ggtt_save(struct xe_gt *gt, unsigned int vfid)
125 {
126 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
127 	xe_gt_assert(gt, vfid != PFID);
128 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
129 
130 	return pf_save_vf_ggtt_mig_data(gt, vfid);
131 }
132 
133 /**
134  * xe_gt_sriov_pf_migration_ggtt_restore() - Restore VF GGTT migration data.
135  * @gt: the &xe_gt
136  * @vfid: the VF identifier (can't be 0)
137  * @data: the &xe_sriov_packet containing migration data
138  *
139  * This function is for PF only.
140  *
141  * Return: 0 on success or a negative error code on failure.
142  */
xe_gt_sriov_pf_migration_ggtt_restore(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)143 int xe_gt_sriov_pf_migration_ggtt_restore(struct xe_gt *gt, unsigned int vfid,
144 					  struct xe_sriov_packet *data)
145 {
146 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
147 	xe_gt_assert(gt, vfid != PFID);
148 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
149 
150 	return pf_restore_vf_ggtt_mig_data(gt, vfid, data);
151 }
152 
153 /* Return: number of dwords saved/restored/required or a negative error code on failure */
guc_action_vf_save_restore(struct xe_guc * guc,u32 vfid,u32 opcode,u64 addr,u32 ndwords)154 static int guc_action_vf_save_restore(struct xe_guc *guc, u32 vfid, u32 opcode,
155 				      u64 addr, u32 ndwords)
156 {
157 	u32 request[PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_LEN] = {
158 		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
159 		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
160 		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_PF2GUC_SAVE_RESTORE_VF) |
161 		FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_0_OPCODE, opcode),
162 		FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_1_VFID, vfid),
163 		FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_2_ADDR_LO, lower_32_bits(addr)),
164 		FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_3_ADDR_HI, upper_32_bits(addr)),
165 		FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_4_SIZE, ndwords),
166 	};
167 
168 	return xe_guc_ct_send_block(&guc->ct, request, ARRAY_SIZE(request));
169 }
170 
171 /* Return: size of the state in dwords or a negative error code on failure */
pf_send_guc_query_vf_mig_data_size(struct xe_gt * gt,unsigned int vfid)172 static int pf_send_guc_query_vf_mig_data_size(struct xe_gt *gt, unsigned int vfid)
173 {
174 	int ret;
175 
176 	ret = guc_action_vf_save_restore(&gt->uc.guc, vfid, GUC_PF_OPCODE_VF_SAVE, 0, 0);
177 	return ret ?: -ENODATA;
178 }
179 
180 /* Return: number of state dwords saved or a negative error code on failure */
pf_send_guc_save_vf_mig_data(struct xe_gt * gt,unsigned int vfid,void * dst,size_t size)181 static int pf_send_guc_save_vf_mig_data(struct xe_gt *gt, unsigned int vfid,
182 					void *dst, size_t size)
183 {
184 	const int ndwords = size / sizeof(u32);
185 	struct xe_guc *guc = &gt->uc.guc;
186 	CLASS(xe_guc_buf, buf)(&guc->buf, ndwords);
187 	int ret;
188 
189 	xe_gt_assert(gt, size % sizeof(u32) == 0);
190 	xe_gt_assert(gt, size == ndwords * sizeof(u32));
191 
192 	if (!xe_guc_buf_is_valid(buf))
193 		return -ENOBUFS;
194 
195 	/* FW expects this buffer to be zero-initialized */
196 	memset(xe_guc_buf_cpu_ptr(buf), 0, size);
197 
198 	ret = guc_action_vf_save_restore(guc, vfid, GUC_PF_OPCODE_VF_SAVE,
199 					 xe_guc_buf_flush(buf), ndwords);
200 	if (!ret)
201 		ret = -ENODATA;
202 	else if (ret > ndwords)
203 		ret = -EPROTO;
204 	else if (ret > 0)
205 		memcpy(dst, xe_guc_buf_sync_read(buf), ret * sizeof(u32));
206 
207 	return ret;
208 }
209 
210 /* Return: number of state dwords restored or a negative error code on failure */
pf_send_guc_restore_vf_mig_data(struct xe_gt * gt,unsigned int vfid,const void * src,size_t size)211 static int pf_send_guc_restore_vf_mig_data(struct xe_gt *gt, unsigned int vfid,
212 					   const void *src, size_t size)
213 {
214 	const int ndwords = size / sizeof(u32);
215 	struct xe_guc *guc = &gt->uc.guc;
216 	CLASS(xe_guc_buf_from_data, buf)(&guc->buf, src, size);
217 	int ret;
218 
219 	xe_gt_assert(gt, size % sizeof(u32) == 0);
220 	xe_gt_assert(gt, size == ndwords * sizeof(u32));
221 
222 	if (!xe_guc_buf_is_valid(buf))
223 		return -ENOBUFS;
224 
225 	ret = guc_action_vf_save_restore(guc, vfid, GUC_PF_OPCODE_VF_RESTORE,
226 					 xe_guc_buf_flush(buf), ndwords);
227 	if (!ret)
228 		ret = -ENODATA;
229 	else if (ret > ndwords)
230 		ret = -EPROTO;
231 
232 	return ret;
233 }
234 
pf_migration_supported(struct xe_gt * gt)235 static bool pf_migration_supported(struct xe_gt *gt)
236 {
237 	return xe_sriov_pf_migration_supported(gt_to_xe(gt));
238 }
239 
pf_save_vf_guc_mig_data(struct xe_gt * gt,unsigned int vfid)240 static int pf_save_vf_guc_mig_data(struct xe_gt *gt, unsigned int vfid)
241 {
242 	struct xe_sriov_packet *data;
243 	size_t size;
244 	int ret;
245 
246 	ret = pf_send_guc_query_vf_mig_data_size(gt, vfid);
247 	if (ret < 0)
248 		goto fail;
249 
250 	size = ret * sizeof(u32);
251 
252 	data = xe_sriov_packet_alloc(gt_to_xe(gt));
253 	if (!data) {
254 		ret = -ENOMEM;
255 		goto fail;
256 	}
257 
258 	ret = xe_sriov_packet_init(data, gt->tile->id, gt->info.id,
259 				   XE_SRIOV_PACKET_TYPE_GUC, 0, size);
260 	if (ret)
261 		goto fail_free;
262 
263 	ret = pf_send_guc_save_vf_mig_data(gt, vfid, data->vaddr, size);
264 	if (ret < 0)
265 		goto fail_free;
266 	size = ret * sizeof(u32);
267 	xe_gt_assert(gt, size);
268 	xe_gt_assert(gt, size <= data->hdr.size);
269 	data->hdr.size = size;
270 	data->remaining = size;
271 
272 	pf_dump_mig_data(gt, vfid, data, "GuC data save");
273 
274 	ret = xe_gt_sriov_pf_migration_save_produce(gt, vfid, data);
275 	if (ret)
276 		goto fail_free;
277 
278 	return 0;
279 
280 fail_free:
281 	xe_sriov_packet_free(data);
282 fail:
283 	xe_gt_sriov_err(gt, "Failed to save VF%u GuC data (%pe)\n",
284 			vfid, ERR_PTR(ret));
285 	return ret;
286 }
287 
pf_migration_guc_size(struct xe_gt * gt,unsigned int vfid)288 static ssize_t pf_migration_guc_size(struct xe_gt *gt, unsigned int vfid)
289 {
290 	ssize_t size;
291 
292 	if (!pf_migration_supported(gt))
293 		return -ENOPKG;
294 
295 	size = pf_send_guc_query_vf_mig_data_size(gt, vfid);
296 	if (size >= 0)
297 		size *= sizeof(u32);
298 
299 	return size;
300 }
301 
302 /**
303  * xe_gt_sriov_pf_migration_guc_save() - Save VF GuC migration data.
304  * @gt: the &xe_gt
305  * @vfid: the VF identifier
306  *
307  * This function is for PF only.
308  *
309  * Return: 0 on success or a negative error code on failure.
310  */
xe_gt_sriov_pf_migration_guc_save(struct xe_gt * gt,unsigned int vfid)311 int xe_gt_sriov_pf_migration_guc_save(struct xe_gt *gt, unsigned int vfid)
312 {
313 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
314 	xe_gt_assert(gt, vfid != PFID);
315 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
316 
317 	if (!pf_migration_supported(gt))
318 		return -ENOPKG;
319 
320 	return pf_save_vf_guc_mig_data(gt, vfid);
321 }
322 
pf_restore_vf_guc_state(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)323 static int pf_restore_vf_guc_state(struct xe_gt *gt, unsigned int vfid,
324 				   struct xe_sriov_packet *data)
325 {
326 	int ret;
327 
328 	xe_gt_assert(gt, data->hdr.size);
329 
330 	pf_dump_mig_data(gt, vfid, data, "GuC data restore");
331 
332 	ret = pf_send_guc_restore_vf_mig_data(gt, vfid, data->vaddr, data->hdr.size);
333 	if (ret < 0)
334 		goto fail;
335 
336 	return 0;
337 
338 fail:
339 	xe_gt_sriov_err(gt, "Failed to restore VF%u GuC data (%pe)\n",
340 			vfid, ERR_PTR(ret));
341 	return ret;
342 }
343 
344 /**
345  * xe_gt_sriov_pf_migration_guc_restore() - Restore VF GuC migration data.
346  * @gt: the &xe_gt
347  * @vfid: the VF identifier
348  * @data: the &xe_sriov_packet containing migration data
349  *
350  * This function is for PF only.
351  *
352  * Return: 0 on success or a negative error code on failure.
353  */
xe_gt_sriov_pf_migration_guc_restore(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)354 int xe_gt_sriov_pf_migration_guc_restore(struct xe_gt *gt, unsigned int vfid,
355 					 struct xe_sriov_packet *data)
356 {
357 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
358 	xe_gt_assert(gt, vfid != PFID);
359 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
360 
361 	if (!pf_migration_supported(gt))
362 		return -ENOPKG;
363 
364 	return pf_restore_vf_guc_state(gt, vfid, data);
365 }
366 
pf_migration_mmio_size(struct xe_gt * gt,unsigned int vfid)367 static ssize_t pf_migration_mmio_size(struct xe_gt *gt, unsigned int vfid)
368 {
369 	if (xe_gt_is_media_type(gt))
370 		return MED_VF_SW_FLAG_COUNT * sizeof(u32);
371 	else
372 		return VF_SW_FLAG_COUNT * sizeof(u32);
373 }
374 
pf_migration_mmio_save(struct xe_gt * gt,unsigned int vfid,void * buf,size_t size)375 static int pf_migration_mmio_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size)
376 {
377 	struct xe_mmio mmio;
378 	u32 *regs = buf;
379 	int n;
380 
381 	if (size != pf_migration_mmio_size(gt, vfid))
382 		return -EINVAL;
383 
384 	xe_mmio_init_vf_view(&mmio, &gt->mmio, vfid);
385 
386 	if (xe_gt_is_media_type(gt))
387 		for (n = 0; n < MED_VF_SW_FLAG_COUNT; n++)
388 			regs[n] = xe_mmio_read32(&gt->mmio, MED_VF_SW_FLAG(n));
389 	else
390 		for (n = 0; n < VF_SW_FLAG_COUNT; n++)
391 			regs[n] = xe_mmio_read32(&gt->mmio, VF_SW_FLAG(n));
392 
393 	return 0;
394 }
395 
pf_migration_mmio_restore(struct xe_gt * gt,unsigned int vfid,const void * buf,size_t size)396 static int pf_migration_mmio_restore(struct xe_gt *gt, unsigned int vfid,
397 				     const void *buf, size_t size)
398 {
399 	const u32 *regs = buf;
400 	struct xe_mmio mmio;
401 	int n;
402 
403 	if (size != pf_migration_mmio_size(gt, vfid))
404 		return -EINVAL;
405 
406 	xe_mmio_init_vf_view(&mmio, &gt->mmio, vfid);
407 
408 	if (xe_gt_is_media_type(gt))
409 		for (n = 0; n < MED_VF_SW_FLAG_COUNT; n++)
410 			xe_mmio_write32(&gt->mmio, MED_VF_SW_FLAG(n), regs[n]);
411 	else
412 		for (n = 0; n < VF_SW_FLAG_COUNT; n++)
413 			xe_mmio_write32(&gt->mmio, VF_SW_FLAG(n), regs[n]);
414 
415 	return 0;
416 }
417 
pf_save_vf_mmio_mig_data(struct xe_gt * gt,unsigned int vfid)418 static int pf_save_vf_mmio_mig_data(struct xe_gt *gt, unsigned int vfid)
419 {
420 	struct xe_sriov_packet *data;
421 	size_t size;
422 	int ret;
423 
424 	size = pf_migration_mmio_size(gt, vfid);
425 	xe_gt_assert(gt, size);
426 
427 	data = xe_sriov_packet_alloc(gt_to_xe(gt));
428 	if (!data)
429 		return -ENOMEM;
430 
431 	ret = xe_sriov_packet_init(data, gt->tile->id, gt->info.id,
432 				   XE_SRIOV_PACKET_TYPE_MMIO, 0, size);
433 	if (ret)
434 		goto fail;
435 
436 	ret = pf_migration_mmio_save(gt, vfid, data->vaddr, size);
437 	if (ret)
438 		goto fail;
439 
440 	pf_dump_mig_data(gt, vfid, data, "MMIO data save");
441 
442 	ret = xe_gt_sriov_pf_migration_save_produce(gt, vfid, data);
443 	if (ret)
444 		goto fail;
445 
446 	return 0;
447 
448 fail:
449 	xe_sriov_packet_free(data);
450 	xe_gt_sriov_err(gt, "Failed to save VF%u MMIO data (%pe)\n", vfid, ERR_PTR(ret));
451 	return ret;
452 }
453 
pf_restore_vf_mmio_mig_data(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)454 static int pf_restore_vf_mmio_mig_data(struct xe_gt *gt, unsigned int vfid,
455 				       struct xe_sriov_packet *data)
456 {
457 	int ret;
458 
459 	pf_dump_mig_data(gt, vfid, data, "MMIO data restore");
460 
461 	ret = pf_migration_mmio_restore(gt, vfid, data->vaddr, data->hdr.size);
462 	if (ret) {
463 		xe_gt_sriov_err(gt, "Failed to restore VF%u MMIO data (%pe)\n",
464 				vfid, ERR_PTR(ret));
465 
466 		return ret;
467 	}
468 
469 	return 0;
470 }
471 
472 /**
473  * xe_gt_sriov_pf_migration_mmio_save() - Save VF MMIO migration data.
474  * @gt: the &xe_gt
475  * @vfid: the VF identifier (can't be 0)
476  *
477  * This function is for PF only.
478  *
479  * Return: 0 on success or a negative error code on failure.
480  */
xe_gt_sriov_pf_migration_mmio_save(struct xe_gt * gt,unsigned int vfid)481 int xe_gt_sriov_pf_migration_mmio_save(struct xe_gt *gt, unsigned int vfid)
482 {
483 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
484 	xe_gt_assert(gt, vfid != PFID);
485 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
486 
487 	return pf_save_vf_mmio_mig_data(gt, vfid);
488 }
489 
490 /**
491  * xe_gt_sriov_pf_migration_mmio_restore() - Restore VF MMIO migration data.
492  * @gt: the &xe_gt
493  * @vfid: the VF identifier (can't be 0)
494  * @data: the &xe_sriov_packet containing migration data
495  *
496  * This function is for PF only.
497  *
498  * Return: 0 on success or a negative error code on failure.
499  */
xe_gt_sriov_pf_migration_mmio_restore(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)500 int xe_gt_sriov_pf_migration_mmio_restore(struct xe_gt *gt, unsigned int vfid,
501 					  struct xe_sriov_packet *data)
502 {
503 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
504 	xe_gt_assert(gt, vfid != PFID);
505 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
506 
507 	return pf_restore_vf_mmio_mig_data(gt, vfid, data);
508 }
509 
pf_migration_vram_size(struct xe_gt * gt,unsigned int vfid)510 static ssize_t pf_migration_vram_size(struct xe_gt *gt, unsigned int vfid)
511 {
512 	if (!xe_gt_is_main_type(gt))
513 		return 0;
514 
515 	return xe_gt_sriov_pf_config_get_lmem(gt, vfid);
516 }
517 
__pf_save_restore_vram(struct xe_gt * gt,unsigned int vfid,struct xe_bo * vram,u64 vram_offset,struct xe_bo * sysmem,u64 sysmem_offset,size_t size,bool save)518 static struct dma_fence *__pf_save_restore_vram(struct xe_gt *gt, unsigned int vfid,
519 						struct xe_bo *vram, u64 vram_offset,
520 						struct xe_bo *sysmem, u64 sysmem_offset,
521 						size_t size, bool save)
522 {
523 	struct dma_fence *ret = NULL;
524 	struct drm_exec exec;
525 	int err;
526 
527 	drm_exec_init(&exec, 0, 0);
528 	drm_exec_until_all_locked(&exec) {
529 		err = drm_exec_lock_obj(&exec, &vram->ttm.base);
530 		drm_exec_retry_on_contention(&exec);
531 		if (err) {
532 			ret = ERR_PTR(err);
533 			goto err;
534 		}
535 
536 		err = drm_exec_lock_obj(&exec, &sysmem->ttm.base);
537 		drm_exec_retry_on_contention(&exec);
538 		if (err) {
539 			ret = ERR_PTR(err);
540 			goto err;
541 		}
542 	}
543 
544 	ret = xe_migrate_vram_copy_chunk(vram, vram_offset, sysmem, sysmem_offset, size,
545 					 save ? XE_MIGRATE_COPY_TO_SRAM : XE_MIGRATE_COPY_TO_VRAM);
546 
547 err:
548 	drm_exec_fini(&exec);
549 
550 	return ret;
551 }
552 
553 #define PF_VRAM_SAVE_RESTORE_TIMEOUT (5 * HZ)
pf_save_vram_chunk(struct xe_gt * gt,unsigned int vfid,struct xe_bo * src_vram,u64 src_vram_offset,size_t size)554 static int pf_save_vram_chunk(struct xe_gt *gt, unsigned int vfid,
555 			      struct xe_bo *src_vram, u64 src_vram_offset,
556 			      size_t size)
557 {
558 	struct xe_sriov_packet *data;
559 	struct dma_fence *fence;
560 	int ret;
561 
562 	data = xe_sriov_packet_alloc(gt_to_xe(gt));
563 	if (!data)
564 		return -ENOMEM;
565 
566 	ret = xe_sriov_packet_init(data, gt->tile->id, gt->info.id,
567 				   XE_SRIOV_PACKET_TYPE_VRAM, src_vram_offset,
568 				   size);
569 	if (ret)
570 		goto fail;
571 
572 	fence = __pf_save_restore_vram(gt, vfid,
573 				       src_vram, src_vram_offset,
574 				       data->bo, 0, size, true);
575 	if (IS_ERR(fence)) {
576 		ret = PTR_ERR(fence);
577 		goto fail;
578 	}
579 
580 	ret = dma_fence_wait_timeout(fence, false, PF_VRAM_SAVE_RESTORE_TIMEOUT);
581 	dma_fence_put(fence);
582 	if (!ret) {
583 		ret = -ETIME;
584 		goto fail;
585 	}
586 
587 	pf_dump_mig_data(gt, vfid, data, "VRAM data save");
588 
589 	ret = xe_gt_sriov_pf_migration_save_produce(gt, vfid, data);
590 	if (ret)
591 		goto fail;
592 
593 	return 0;
594 
595 fail:
596 	xe_sriov_packet_free(data);
597 	return ret;
598 }
599 
600 #define VF_VRAM_STATE_CHUNK_MAX_SIZE SZ_512M
pf_save_vf_vram_mig_data(struct xe_gt * gt,unsigned int vfid)601 static int pf_save_vf_vram_mig_data(struct xe_gt *gt, unsigned int vfid)
602 {
603 	struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, vfid);
604 	loff_t *offset = &migration->save.vram_offset;
605 	struct xe_bo *vram;
606 	size_t vram_size, chunk_size;
607 	int ret;
608 
609 	vram = xe_gt_sriov_pf_config_get_lmem_obj(gt, vfid);
610 	if (!vram)
611 		return -ENXIO;
612 
613 	vram_size = xe_bo_size(vram);
614 
615 	xe_gt_assert(gt, *offset < vram_size);
616 
617 	chunk_size = min(vram_size - *offset, VF_VRAM_STATE_CHUNK_MAX_SIZE);
618 
619 	ret = pf_save_vram_chunk(gt, vfid, vram, *offset, chunk_size);
620 	if (ret)
621 		goto fail;
622 
623 	*offset += chunk_size;
624 
625 	xe_bo_put(vram);
626 
627 	if (*offset < vram_size)
628 		return -EAGAIN;
629 
630 	return 0;
631 
632 fail:
633 	xe_bo_put(vram);
634 	xe_gt_sriov_err(gt, "Failed to save VF%u VRAM data (%pe)\n", vfid, ERR_PTR(ret));
635 	return ret;
636 }
637 
pf_restore_vf_vram_mig_data(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)638 static int pf_restore_vf_vram_mig_data(struct xe_gt *gt, unsigned int vfid,
639 				       struct xe_sriov_packet *data)
640 {
641 	u64 end = data->hdr.offset + data->hdr.size;
642 	struct dma_fence *fence;
643 	struct xe_bo *vram;
644 	size_t size;
645 	int ret = 0;
646 
647 	vram = xe_gt_sriov_pf_config_get_lmem_obj(gt, vfid);
648 	if (!vram)
649 		return -ENXIO;
650 
651 	size = xe_bo_size(vram);
652 
653 	if (end > size || end < data->hdr.size) {
654 		ret = -EINVAL;
655 		goto err;
656 	}
657 
658 	pf_dump_mig_data(gt, vfid, data, "VRAM data restore");
659 
660 	fence = __pf_save_restore_vram(gt, vfid, vram, data->hdr.offset,
661 				       data->bo, 0, data->hdr.size, false);
662 	if (IS_ERR(fence)) {
663 		ret = PTR_ERR(fence);
664 		goto err;
665 	}
666 
667 	ret = dma_fence_wait_timeout(fence, false, PF_VRAM_SAVE_RESTORE_TIMEOUT);
668 	dma_fence_put(fence);
669 	if (!ret) {
670 		ret = -ETIME;
671 		goto err;
672 	}
673 
674 	xe_bo_put(vram);
675 
676 	return 0;
677 err:
678 	xe_bo_put(vram);
679 	xe_gt_sriov_err(gt, "Failed to restore VF%u VRAM data (%pe)\n", vfid, ERR_PTR(ret));
680 	return ret;
681 }
682 
683 /**
684  * xe_gt_sriov_pf_migration_vram_save() - Save VF VRAM migration data.
685  * @gt: the &xe_gt
686  * @vfid: the VF identifier (can't be 0)
687  *
688  * This function is for PF only.
689  *
690  * Return: 0 on success or a negative error code on failure.
691  */
xe_gt_sriov_pf_migration_vram_save(struct xe_gt * gt,unsigned int vfid)692 int xe_gt_sriov_pf_migration_vram_save(struct xe_gt *gt, unsigned int vfid)
693 {
694 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
695 	xe_gt_assert(gt, vfid != PFID);
696 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
697 
698 	return pf_save_vf_vram_mig_data(gt, vfid);
699 }
700 
701 /**
702  * xe_gt_sriov_pf_migration_vram_restore() - Restore VF VRAM migration data.
703  * @gt: the &xe_gt
704  * @vfid: the VF identifier (can't be 0)
705  * @data: the &xe_sriov_packet containing migration data
706  *
707  * This function is for PF only.
708  *
709  * Return: 0 on success or a negative error code on failure.
710  */
xe_gt_sriov_pf_migration_vram_restore(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)711 int xe_gt_sriov_pf_migration_vram_restore(struct xe_gt *gt, unsigned int vfid,
712 					  struct xe_sriov_packet *data)
713 {
714 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
715 	xe_gt_assert(gt, vfid != PFID);
716 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
717 
718 	return pf_restore_vf_vram_mig_data(gt, vfid, data);
719 }
720 
721 /**
722  * xe_gt_sriov_pf_migration_size() - Total size of migration data from all components within a GT.
723  * @gt: the &xe_gt
724  * @vfid: the VF identifier (can't be 0)
725  *
726  * This function is for PF only.
727  *
728  * Return: total migration data size in bytes or a negative error code on failure.
729  */
xe_gt_sriov_pf_migration_size(struct xe_gt * gt,unsigned int vfid)730 ssize_t xe_gt_sriov_pf_migration_size(struct xe_gt *gt, unsigned int vfid)
731 {
732 	ssize_t total = 0;
733 	ssize_t size;
734 
735 	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
736 	xe_gt_assert(gt, vfid != PFID);
737 	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
738 
739 	size = pf_migration_guc_size(gt, vfid);
740 	if (size < 0)
741 		return size;
742 	if (size > 0)
743 		size += sizeof(struct xe_sriov_packet_hdr);
744 	total += size;
745 
746 	size = pf_migration_ggtt_size(gt, vfid);
747 	if (size < 0)
748 		return size;
749 	if (size > 0)
750 		size += sizeof(struct xe_sriov_packet_hdr);
751 	total += size;
752 
753 	size = pf_migration_mmio_size(gt, vfid);
754 	if (size < 0)
755 		return size;
756 	if (size > 0)
757 		size += sizeof(struct xe_sriov_packet_hdr);
758 	total += size;
759 
760 	size = pf_migration_vram_size(gt, vfid);
761 	if (size < 0)
762 		return size;
763 	if (size > 0)
764 		size += sizeof(struct xe_sriov_packet_hdr);
765 	total += size;
766 
767 	return total;
768 }
769 
770 /**
771  * xe_gt_sriov_pf_migration_ring_empty() - Check if a migration ring is empty.
772  * @gt: the &xe_gt
773  * @vfid: the VF identifier
774  *
775  * Return: true if the ring is empty, otherwise false.
776  */
xe_gt_sriov_pf_migration_ring_empty(struct xe_gt * gt,unsigned int vfid)777 bool xe_gt_sriov_pf_migration_ring_empty(struct xe_gt *gt, unsigned int vfid)
778 {
779 	return ptr_ring_empty(&pf_pick_gt_migration(gt, vfid)->ring);
780 }
781 
782 /**
783  * xe_gt_sriov_pf_migration_ring_full() - Check if a migration ring is full.
784  * @gt: the &xe_gt
785  * @vfid: the VF identifier
786  *
787  * Return: true if the ring is full, otherwise false.
788  */
xe_gt_sriov_pf_migration_ring_full(struct xe_gt * gt,unsigned int vfid)789 bool xe_gt_sriov_pf_migration_ring_full(struct xe_gt *gt, unsigned int vfid)
790 {
791 	return ptr_ring_full(&pf_pick_gt_migration(gt, vfid)->ring);
792 }
793 
794 /**
795  * xe_gt_sriov_pf_migration_ring_free() - Consume and free all data in migration ring
796  * @gt: the &xe_gt
797  * @vfid: the VF identifier
798  */
xe_gt_sriov_pf_migration_ring_free(struct xe_gt * gt,unsigned int vfid)799 void xe_gt_sriov_pf_migration_ring_free(struct xe_gt *gt, unsigned int vfid)
800 {
801 	struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, vfid);
802 	struct xe_sriov_packet *data;
803 
804 	if (ptr_ring_empty(&migration->ring))
805 		return;
806 
807 	xe_gt_sriov_notice(gt, "VF%u unprocessed migration data left in the ring!\n", vfid);
808 
809 	while ((data = ptr_ring_consume(&migration->ring)))
810 		xe_sriov_packet_free(data);
811 }
812 
pf_migration_save_data_todo(struct xe_gt * gt,unsigned int vfid,enum xe_sriov_packet_type type)813 static void pf_migration_save_data_todo(struct xe_gt *gt, unsigned int vfid,
814 					enum xe_sriov_packet_type type)
815 {
816 	set_bit(type, &pf_pick_gt_migration(gt, vfid)->save.data_remaining);
817 }
818 
819 /**
820  * xe_gt_sriov_pf_migration_save_init() - Initialize per-GT migration related data.
821  * @gt: the &xe_gt
822  * @vfid: the VF identifier (can't be 0)
823  */
xe_gt_sriov_pf_migration_save_init(struct xe_gt * gt,unsigned int vfid)824 void xe_gt_sriov_pf_migration_save_init(struct xe_gt *gt, unsigned int vfid)
825 {
826 	struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, vfid);
827 
828 	migration->save.data_remaining = 0;
829 	migration->save.vram_offset = 0;
830 
831 	xe_gt_assert(gt, pf_migration_guc_size(gt, vfid) > 0);
832 	pf_migration_save_data_todo(gt, vfid, XE_SRIOV_PACKET_TYPE_GUC);
833 
834 	if (pf_migration_ggtt_size(gt, vfid) > 0)
835 		pf_migration_save_data_todo(gt, vfid, XE_SRIOV_PACKET_TYPE_GGTT);
836 
837 	xe_gt_assert(gt, pf_migration_mmio_size(gt, vfid) > 0);
838 	pf_migration_save_data_todo(gt, vfid, XE_SRIOV_PACKET_TYPE_MMIO);
839 
840 	if (pf_migration_vram_size(gt, vfid) > 0)
841 		pf_migration_save_data_todo(gt, vfid, XE_SRIOV_PACKET_TYPE_VRAM);
842 }
843 
844 /**
845  * xe_gt_sriov_pf_migration_save_data_pending() - Check if migration data type needs to be saved.
846  * @gt: the &xe_gt
847  * @vfid: the VF identifier (can't be 0)
848  * @type: the &xe_sriov_packet_type of data to be checked
849  *
850  * Return: true if the data needs saving, otherwise false.
851  */
xe_gt_sriov_pf_migration_save_data_pending(struct xe_gt * gt,unsigned int vfid,enum xe_sriov_packet_type type)852 bool xe_gt_sriov_pf_migration_save_data_pending(struct xe_gt *gt, unsigned int vfid,
853 						enum xe_sriov_packet_type type)
854 {
855 	return test_bit(type, &pf_pick_gt_migration(gt, vfid)->save.data_remaining);
856 }
857 
858 /**
859  * xe_gt_sriov_pf_migration_save_data_complete() - Complete migration data type save.
860  * @gt: the &xe_gt
861  * @vfid: the VF identifier (can't be 0)
862  * @type: the &xe_sriov_packet_type to be marked as completed.
863  */
xe_gt_sriov_pf_migration_save_data_complete(struct xe_gt * gt,unsigned int vfid,enum xe_sriov_packet_type type)864 void xe_gt_sriov_pf_migration_save_data_complete(struct xe_gt *gt, unsigned int vfid,
865 						 enum xe_sriov_packet_type type)
866 {
867 	clear_bit(type, &pf_pick_gt_migration(gt, vfid)->save.data_remaining);
868 }
869 
870 /**
871  * xe_gt_sriov_pf_migration_save_produce() - Add VF save data packet to migration ring.
872  * @gt: the &xe_gt
873  * @vfid: the VF identifier
874  * @data: the &xe_sriov_packet
875  *
876  * Called by the save migration data producer (PF SR-IOV Control worker) when
877  * processing migration data.
878  * Wakes up the save migration data consumer (userspace), that is potentially
879  * waiting for data when the ring was empty.
880  *
881  * Return: 0 on success or a negative error code on failure.
882  */
xe_gt_sriov_pf_migration_save_produce(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)883 int xe_gt_sriov_pf_migration_save_produce(struct xe_gt *gt, unsigned int vfid,
884 					  struct xe_sriov_packet *data)
885 {
886 	int ret;
887 
888 	ret = ptr_ring_produce(&pf_pick_gt_migration(gt, vfid)->ring, data);
889 	if (ret)
890 		return ret;
891 
892 	wake_up_all(xe_sriov_pf_migration_waitqueue(gt_to_xe(gt), vfid));
893 
894 	return 0;
895 }
896 
897 /**
898  * xe_gt_sriov_pf_migration_restore_consume() - Get VF restore data packet from migration ring.
899  * @gt: the &xe_gt
900  * @vfid: the VF identifier
901  *
902  * Called by the restore migration data consumer (PF SR-IOV Control worker) when
903  * processing migration data.
904  * Wakes up the restore migration data producer (userspace), that is
905  * potentially waiting to add more data when the ring is full.
906  *
907  * Return: Pointer to &xe_sriov_packet on success,
908  *	   NULL if ring is empty.
909  */
910 struct xe_sriov_packet *
xe_gt_sriov_pf_migration_restore_consume(struct xe_gt * gt,unsigned int vfid)911 xe_gt_sriov_pf_migration_restore_consume(struct xe_gt *gt, unsigned int vfid)
912 {
913 	struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, vfid);
914 	struct wait_queue_head *wq = xe_sriov_pf_migration_waitqueue(gt_to_xe(gt), vfid);
915 	struct xe_sriov_packet *data;
916 
917 	data = ptr_ring_consume(&migration->ring);
918 	if (data)
919 		wake_up_all(wq);
920 
921 	return data;
922 }
923 
pf_restore_data_ready(struct xe_gt * gt,unsigned int vfid)924 static bool pf_restore_data_ready(struct xe_gt *gt, unsigned int vfid)
925 {
926 	if (xe_gt_sriov_pf_control_check_restore_failed(gt, vfid) ||
927 	    !ptr_ring_full(&pf_pick_gt_migration(gt, vfid)->ring))
928 		return true;
929 
930 	return false;
931 }
932 
933 /**
934  * xe_gt_sriov_pf_migration_restore_produce() - Add VF restore data packet to migration ring.
935  * @gt: the &xe_gt
936  * @vfid: the VF identifier
937  * @data: the &xe_sriov_packet
938  *
939  * Called by the restore migration data producer (userspace) when processing
940  * migration data.
941  * If the ring is full, waits until there is space.
942  * Queues the restore migration data consumer (PF SR-IOV Control worker), that
943  * is potentially waiting for data when the ring was empty.
944  *
945  * Return: 0 on success or a negative error code on failure.
946  */
xe_gt_sriov_pf_migration_restore_produce(struct xe_gt * gt,unsigned int vfid,struct xe_sriov_packet * data)947 int xe_gt_sriov_pf_migration_restore_produce(struct xe_gt *gt, unsigned int vfid,
948 					     struct xe_sriov_packet *data)
949 {
950 	int ret;
951 
952 	xe_gt_assert(gt, data->hdr.tile_id == gt->tile->id);
953 	xe_gt_assert(gt, data->hdr.gt_id == gt->info.id);
954 
955 	for (;;) {
956 		if (xe_gt_sriov_pf_control_check_restore_failed(gt, vfid))
957 			return -EIO;
958 
959 		ret = ptr_ring_produce(&pf_pick_gt_migration(gt, vfid)->ring, data);
960 		if (!ret)
961 			break;
962 
963 		ret = wait_event_interruptible(*xe_sriov_pf_migration_waitqueue(gt_to_xe(gt), vfid),
964 					       pf_restore_data_ready(gt, vfid));
965 		if (ret)
966 			return ret;
967 	}
968 
969 	return xe_gt_sriov_pf_control_process_restore_data(gt, vfid);
970 }
971 
972 /**
973  * xe_gt_sriov_pf_migration_save_consume() - Get VF save data packet from migration ring.
974  * @gt: the &xe_gt
975  * @vfid: the VF identifier
976  *
977  * Called by the save migration data consumer (userspace) when
978  * processing migration data.
979  * Queues the save migration data producer (PF SR-IOV Control worker), that is
980  * potentially waiting to add more data when the ring is full.
981  *
982  * Return: Pointer to &xe_sriov_packet on success,
983  *	   NULL if ring is empty and there's no more data available,
984  *	   ERR_PTR(-EAGAIN) if the ring is empty, but data is still produced.
985  */
986 struct xe_sriov_packet *
xe_gt_sriov_pf_migration_save_consume(struct xe_gt * gt,unsigned int vfid)987 xe_gt_sriov_pf_migration_save_consume(struct xe_gt *gt, unsigned int vfid)
988 {
989 	struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, vfid);
990 	struct xe_sriov_packet *data;
991 	int ret;
992 
993 	data = ptr_ring_consume(&migration->ring);
994 	if (data) {
995 		ret = xe_gt_sriov_pf_control_process_save_data(gt, vfid);
996 		if (ret) {
997 			xe_sriov_packet_free(data);
998 			return ERR_PTR(ret);
999 		}
1000 
1001 		return data;
1002 	}
1003 
1004 	if (xe_gt_sriov_pf_control_check_save_data_done(gt, vfid))
1005 		return NULL;
1006 
1007 	if (xe_gt_sriov_pf_control_check_save_failed(gt, vfid))
1008 		return ERR_PTR(-EIO);
1009 
1010 	return ERR_PTR(-EAGAIN);
1011 }
1012 
destroy_pf_packet(void * ptr)1013 static void destroy_pf_packet(void *ptr)
1014 {
1015 	struct xe_sriov_packet *data = ptr;
1016 
1017 	xe_sriov_packet_free(data);
1018 }
1019 
action_ring_cleanup(void * arg)1020 static void action_ring_cleanup(void *arg)
1021 {
1022 	struct ptr_ring *r = arg;
1023 
1024 	ptr_ring_cleanup(r, destroy_pf_packet);
1025 }
1026 
pf_gt_migration_check_support(struct xe_gt * gt)1027 static void pf_gt_migration_check_support(struct xe_gt *gt)
1028 {
1029 	if (GUC_FIRMWARE_VER(&gt->uc.guc) < MAKE_GUC_VER(70, 54, 0))
1030 		xe_sriov_pf_migration_disable(gt_to_xe(gt), "requires GuC version >= 70.54.0");
1031 }
1032 
1033 /**
1034  * xe_gt_sriov_pf_migration_init() - Initialize support for VF migration.
1035  * @gt: the &xe_gt
1036  *
1037  * This function is for PF only.
1038  *
1039  * Return: 0 on success or a negative error code on failure.
1040  */
xe_gt_sriov_pf_migration_init(struct xe_gt * gt)1041 int xe_gt_sriov_pf_migration_init(struct xe_gt *gt)
1042 {
1043 	struct xe_device *xe = gt_to_xe(gt);
1044 	unsigned int n, totalvfs;
1045 	int err;
1046 
1047 	xe_gt_assert(gt, IS_SRIOV_PF(xe));
1048 
1049 	pf_gt_migration_check_support(gt);
1050 
1051 	if (!pf_migration_supported(gt))
1052 		return 0;
1053 
1054 	totalvfs = xe_sriov_pf_get_totalvfs(xe);
1055 	for (n = 1; n <= totalvfs; n++) {
1056 		struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, n);
1057 
1058 		err = ptr_ring_init(&migration->ring,
1059 				    XE_GT_SRIOV_PF_MIGRATION_RING_SIZE, GFP_KERNEL);
1060 		if (err)
1061 			return err;
1062 
1063 		err = devm_add_action_or_reset(xe->drm.dev, action_ring_cleanup, &migration->ring);
1064 		if (err)
1065 			return err;
1066 	}
1067 
1068 	return 0;
1069 }
1070