xref: /linux/drivers/gpu/drm/xe/xe_sriov_vf.c (revision 6e6d7b41f9870cd464bed7632228b5f977e2c0b1)
1*6e6d7b41STomasz Lis // SPDX-License-Identifier: MIT
2*6e6d7b41STomasz Lis /*
3*6e6d7b41STomasz Lis  * Copyright © 2023-2024 Intel Corporation
4*6e6d7b41STomasz Lis  */
5*6e6d7b41STomasz Lis 
6*6e6d7b41STomasz Lis #include <drm/drm_managed.h>
7*6e6d7b41STomasz Lis 
8*6e6d7b41STomasz Lis #include "xe_assert.h"
9*6e6d7b41STomasz Lis #include "xe_device.h"
10*6e6d7b41STomasz Lis #include "xe_gt_sriov_printk.h"
11*6e6d7b41STomasz Lis #include "xe_sriov.h"
12*6e6d7b41STomasz Lis #include "xe_sriov_printk.h"
13*6e6d7b41STomasz Lis #include "xe_sriov_vf.h"
14*6e6d7b41STomasz Lis 
15*6e6d7b41STomasz Lis static void migration_worker_func(struct work_struct *w);
16*6e6d7b41STomasz Lis 
17*6e6d7b41STomasz Lis /**
18*6e6d7b41STomasz Lis  * xe_sriov_vf_init_early - Initialize SR-IOV VF specific data.
19*6e6d7b41STomasz Lis  * @xe: the &xe_device to initialize
20*6e6d7b41STomasz Lis  */
21*6e6d7b41STomasz Lis void xe_sriov_vf_init_early(struct xe_device *xe)
22*6e6d7b41STomasz Lis {
23*6e6d7b41STomasz Lis 	INIT_WORK(&xe->sriov.vf.migration.worker, migration_worker_func);
24*6e6d7b41STomasz Lis }
25*6e6d7b41STomasz Lis 
26*6e6d7b41STomasz Lis static void vf_post_migration_recovery(struct xe_device *xe)
27*6e6d7b41STomasz Lis {
28*6e6d7b41STomasz Lis 	drm_dbg(&xe->drm, "migration recovery in progress\n");
29*6e6d7b41STomasz Lis 	/* FIXME: add the recovery steps */
30*6e6d7b41STomasz Lis 	drm_notice(&xe->drm, "migration recovery ended\n");
31*6e6d7b41STomasz Lis }
32*6e6d7b41STomasz Lis 
33*6e6d7b41STomasz Lis static void migration_worker_func(struct work_struct *w)
34*6e6d7b41STomasz Lis {
35*6e6d7b41STomasz Lis 	struct xe_device *xe = container_of(w, struct xe_device,
36*6e6d7b41STomasz Lis 					    sriov.vf.migration.worker);
37*6e6d7b41STomasz Lis 
38*6e6d7b41STomasz Lis 	vf_post_migration_recovery(xe);
39*6e6d7b41STomasz Lis }
40*6e6d7b41STomasz Lis 
41*6e6d7b41STomasz Lis static bool vf_ready_to_recovery_on_all_gts(struct xe_device *xe)
42*6e6d7b41STomasz Lis {
43*6e6d7b41STomasz Lis 	struct xe_gt *gt;
44*6e6d7b41STomasz Lis 	unsigned int id;
45*6e6d7b41STomasz Lis 
46*6e6d7b41STomasz Lis 	for_each_gt(gt, xe, id) {
47*6e6d7b41STomasz Lis 		if (!test_bit(id, &xe->sriov.vf.migration.gt_flags)) {
48*6e6d7b41STomasz Lis 			xe_gt_sriov_dbg_verbose(gt, "still not ready to recover\n");
49*6e6d7b41STomasz Lis 			return false;
50*6e6d7b41STomasz Lis 		}
51*6e6d7b41STomasz Lis 	}
52*6e6d7b41STomasz Lis 	return true;
53*6e6d7b41STomasz Lis }
54*6e6d7b41STomasz Lis 
55*6e6d7b41STomasz Lis /**
56*6e6d7b41STomasz Lis  * xe_sriov_vf_start_migration_recovery - Start VF migration recovery.
57*6e6d7b41STomasz Lis  * @xe: the &xe_device to start recovery on
58*6e6d7b41STomasz Lis  *
59*6e6d7b41STomasz Lis  * This function shall be called only by VF.
60*6e6d7b41STomasz Lis  */
61*6e6d7b41STomasz Lis void xe_sriov_vf_start_migration_recovery(struct xe_device *xe)
62*6e6d7b41STomasz Lis {
63*6e6d7b41STomasz Lis 	bool started;
64*6e6d7b41STomasz Lis 
65*6e6d7b41STomasz Lis 	xe_assert(xe, IS_SRIOV_VF(xe));
66*6e6d7b41STomasz Lis 
67*6e6d7b41STomasz Lis 	if (!vf_ready_to_recovery_on_all_gts(xe))
68*6e6d7b41STomasz Lis 		return;
69*6e6d7b41STomasz Lis 
70*6e6d7b41STomasz Lis 	WRITE_ONCE(xe->sriov.vf.migration.gt_flags, 0);
71*6e6d7b41STomasz Lis 	/* Ensure other threads see that no flags are set now. */
72*6e6d7b41STomasz Lis 	smp_mb();
73*6e6d7b41STomasz Lis 
74*6e6d7b41STomasz Lis 	started = queue_work(xe->sriov.wq, &xe->sriov.vf.migration.worker);
75*6e6d7b41STomasz Lis 	drm_info(&xe->drm, "VF migration recovery %s\n", started ?
76*6e6d7b41STomasz Lis 		 "scheduled" : "already in progress");
77*6e6d7b41STomasz Lis }
78