Skip to content

Commit ed46ff0

Browse files
committed
drm/xe/pf: Add save/restore control state stubs and connect to debugfs
The states will be used by upcoming changes to produce (in case of save) or consume (in case of resume) the VF migration data. Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patch.msgid.link/20251112132220.516975-5-michal.winiarski@intel.com Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
1 parent cd0ffc8 commit ed46ff0

6 files changed

Lines changed: 404 additions & 0 deletions

File tree

drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ static const char *control_bit_to_string(enum xe_gt_sriov_control_bits bit)
184184
CASE2STR(PAUSE_SAVE_GUC);
185185
CASE2STR(PAUSE_FAILED);
186186
CASE2STR(PAUSED);
187+
CASE2STR(SAVE_WIP);
188+
CASE2STR(SAVE_FAILED);
189+
CASE2STR(SAVED);
190+
CASE2STR(RESTORE_WIP);
191+
CASE2STR(RESTORE_FAILED);
192+
CASE2STR(RESTORED);
187193
CASE2STR(RESUME_WIP);
188194
CASE2STR(RESUME_SEND_RESUME);
189195
CASE2STR(RESUME_FAILED);
@@ -208,6 +214,8 @@ static unsigned long pf_get_default_timeout(enum xe_gt_sriov_control_bits bit)
208214
case XE_GT_SRIOV_STATE_FLR_WIP:
209215
case XE_GT_SRIOV_STATE_FLR_RESET_CONFIG:
210216
return 5 * HZ;
217+
case XE_GT_SRIOV_STATE_RESTORE_WIP:
218+
return 20 * HZ;
211219
default:
212220
return HZ;
213221
}
@@ -329,6 +337,8 @@ static void pf_exit_vf_mismatch(struct xe_gt *gt, unsigned int vfid)
329337
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_FAILED);
330338
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESUME_FAILED);
331339
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_FAILED);
340+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_FAILED);
341+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_FAILED);
332342
}
333343

334344
#define pf_enter_vf_state_machine_bug(gt, vfid) ({ \
@@ -359,6 +369,8 @@ static void pf_queue_vf(struct xe_gt *gt, unsigned int vfid)
359369

360370
static void pf_exit_vf_flr_wip(struct xe_gt *gt, unsigned int vfid);
361371
static void pf_exit_vf_stop_wip(struct xe_gt *gt, unsigned int vfid);
372+
static void pf_exit_vf_save_wip(struct xe_gt *gt, unsigned int vfid);
373+
static void pf_exit_vf_restore_wip(struct xe_gt *gt, unsigned int vfid);
362374
static void pf_exit_vf_pause_wip(struct xe_gt *gt, unsigned int vfid);
363375
static void pf_exit_vf_resume_wip(struct xe_gt *gt, unsigned int vfid);
364376

@@ -380,6 +392,8 @@ static void pf_exit_vf_wip(struct xe_gt *gt, unsigned int vfid)
380392

381393
pf_exit_vf_flr_wip(gt, vfid);
382394
pf_exit_vf_stop_wip(gt, vfid);
395+
pf_exit_vf_save_wip(gt, vfid);
396+
pf_exit_vf_restore_wip(gt, vfid);
383397
pf_exit_vf_pause_wip(gt, vfid);
384398
pf_exit_vf_resume_wip(gt, vfid);
385399

@@ -399,6 +413,8 @@ static void pf_enter_vf_ready(struct xe_gt *gt, unsigned int vfid)
399413
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
400414
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_STOPPED);
401415
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESUMED);
416+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED);
417+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED);
402418
pf_exit_vf_mismatch(gt, vfid);
403419
pf_exit_vf_wip(gt, vfid);
404420
}
@@ -675,6 +691,8 @@ static void pf_enter_vf_resumed(struct xe_gt *gt, unsigned int vfid)
675691
{
676692
pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESUMED);
677693
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
694+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED);
695+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED);
678696
pf_exit_vf_mismatch(gt, vfid);
679697
pf_exit_vf_wip(gt, vfid);
680698
}
@@ -753,6 +771,16 @@ int xe_gt_sriov_pf_control_resume_vf(struct xe_gt *gt, unsigned int vfid)
753771
return -EPERM;
754772
}
755773

774+
if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP)) {
775+
xe_gt_sriov_dbg(gt, "VF%u save is in progress!\n", vfid);
776+
return -EBUSY;
777+
}
778+
779+
if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
780+
xe_gt_sriov_dbg(gt, "VF%u restore is in progress!\n", vfid);
781+
return -EBUSY;
782+
}
783+
756784
if (!pf_enter_vf_resume_wip(gt, vfid)) {
757785
xe_gt_sriov_dbg(gt, "VF%u resume already in progress!\n", vfid);
758786
return -EALREADY;
@@ -776,6 +804,218 @@ int xe_gt_sriov_pf_control_resume_vf(struct xe_gt *gt, unsigned int vfid)
776804
return -ECANCELED;
777805
}
778806

807+
static void pf_exit_vf_save_wip(struct xe_gt *gt, unsigned int vfid)
808+
{
809+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP);
810+
}
811+
812+
static void pf_enter_vf_saved(struct xe_gt *gt, unsigned int vfid)
813+
{
814+
if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED))
815+
pf_enter_vf_state_machine_bug(gt, vfid);
816+
817+
xe_gt_sriov_dbg(gt, "VF%u saved!\n", vfid);
818+
819+
pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
820+
pf_exit_vf_mismatch(gt, vfid);
821+
pf_exit_vf_wip(gt, vfid);
822+
}
823+
824+
static bool pf_handle_vf_save(struct xe_gt *gt, unsigned int vfid)
825+
{
826+
if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP))
827+
return false;
828+
829+
pf_enter_vf_saved(gt, vfid);
830+
831+
return true;
832+
}
833+
834+
static bool pf_enter_vf_save_wip(struct xe_gt *gt, unsigned int vfid)
835+
{
836+
if (pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP)) {
837+
pf_enter_vf_wip(gt, vfid);
838+
pf_queue_vf(gt, vfid);
839+
return true;
840+
}
841+
842+
return false;
843+
}
844+
845+
/**
846+
* xe_gt_sriov_pf_control_trigger_save_vf() - Start an SR-IOV VF migration data save sequence.
847+
* @gt: the &xe_gt
848+
* @vfid: the VF identifier
849+
*
850+
* This function is for PF only.
851+
*
852+
* Return: 0 on success or a negative error code on failure.
853+
*/
854+
int xe_gt_sriov_pf_control_trigger_save_vf(struct xe_gt *gt, unsigned int vfid)
855+
{
856+
if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_STOPPED)) {
857+
xe_gt_sriov_dbg(gt, "VF%u is stopped!\n", vfid);
858+
return -EPERM;
859+
}
860+
861+
if (!pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED)) {
862+
xe_gt_sriov_dbg(gt, "VF%u is not paused!\n", vfid);
863+
return -EPERM;
864+
}
865+
866+
if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
867+
xe_gt_sriov_dbg(gt, "VF%u restore is in progress!\n", vfid);
868+
return -EBUSY;
869+
}
870+
871+
if (!pf_enter_vf_save_wip(gt, vfid)) {
872+
xe_gt_sriov_dbg(gt, "VF%u save already in progress!\n", vfid);
873+
return -EALREADY;
874+
}
875+
876+
return 0;
877+
}
878+
879+
/**
880+
* xe_gt_sriov_pf_control_finish_save_vf() - Complete a VF migration data save sequence.
881+
* @gt: the &xe_gt
882+
* @vfid: the VF identifier
883+
*
884+
* This function is for PF only.
885+
*
886+
* Return: 0 on success or a negative error code on failure.
887+
*/
888+
int xe_gt_sriov_pf_control_finish_save_vf(struct xe_gt *gt, unsigned int vfid)
889+
{
890+
if (!pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED)) {
891+
pf_enter_vf_mismatch(gt, vfid);
892+
return -EIO;
893+
}
894+
895+
pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
896+
897+
return 0;
898+
}
899+
900+
static void pf_exit_vf_restore_wip(struct xe_gt *gt, unsigned int vfid)
901+
{
902+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP);
903+
}
904+
905+
static void pf_enter_vf_restored(struct xe_gt *gt, unsigned int vfid)
906+
{
907+
if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED))
908+
pf_enter_vf_state_machine_bug(gt, vfid);
909+
910+
xe_gt_sriov_dbg(gt, "VF%u restored!\n", vfid);
911+
912+
pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
913+
pf_exit_vf_mismatch(gt, vfid);
914+
pf_exit_vf_wip(gt, vfid);
915+
}
916+
917+
static bool pf_handle_vf_restore(struct xe_gt *gt, unsigned int vfid)
918+
{
919+
if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP))
920+
return false;
921+
922+
pf_enter_vf_restored(gt, vfid);
923+
924+
return true;
925+
}
926+
927+
static bool pf_enter_vf_restore_wip(struct xe_gt *gt, unsigned int vfid)
928+
{
929+
if (pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
930+
pf_enter_vf_wip(gt, vfid);
931+
pf_queue_vf(gt, vfid);
932+
return true;
933+
}
934+
935+
return false;
936+
}
937+
938+
/**
939+
* xe_gt_sriov_pf_control_trigger restore_vf() - Start an SR-IOV VF migration data restore sequence.
940+
* @gt: the &xe_gt
941+
* @vfid: the VF identifier
942+
*
943+
* This function is for PF only.
944+
*
945+
* Return: 0 on success or a negative error code on failure.
946+
*/
947+
int xe_gt_sriov_pf_control_trigger_restore_vf(struct xe_gt *gt, unsigned int vfid)
948+
{
949+
if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_STOPPED)) {
950+
xe_gt_sriov_dbg(gt, "VF%u is stopped!\n", vfid);
951+
return -EPERM;
952+
}
953+
954+
if (!pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED)) {
955+
xe_gt_sriov_dbg(gt, "VF%u is not paused!\n", vfid);
956+
return -EPERM;
957+
}
958+
959+
if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP)) {
960+
xe_gt_sriov_dbg(gt, "VF%u save is in progress!\n", vfid);
961+
return -EBUSY;
962+
}
963+
964+
if (!pf_enter_vf_restore_wip(gt, vfid)) {
965+
xe_gt_sriov_dbg(gt, "VF%u restore already in progress!\n", vfid);
966+
return -EALREADY;
967+
}
968+
969+
return 0;
970+
}
971+
972+
static int pf_wait_vf_restore_done(struct xe_gt *gt, unsigned int vfid)
973+
{
974+
unsigned long timeout = pf_get_default_timeout(XE_GT_SRIOV_STATE_RESTORE_WIP);
975+
int err;
976+
977+
err = pf_wait_vf_wip_done(gt, vfid, timeout);
978+
if (err) {
979+
xe_gt_sriov_notice(gt, "VF%u RESTORE didn't finish in %u ms (%pe)\n",
980+
vfid, jiffies_to_msecs(timeout), ERR_PTR(err));
981+
return err;
982+
}
983+
984+
if (!pf_expect_vf_not_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_FAILED))
985+
return -EIO;
986+
987+
return 0;
988+
}
989+
990+
/**
991+
* xe_gt_sriov_pf_control_finish_restore_vf() - Complete a VF migration data restore sequence.
992+
* @gt: the &xe_gt
993+
* @vfid: the VF identifier
994+
*
995+
* This function is for PF only.
996+
*
997+
* Return: 0 on success or a negative error code on failure.
998+
*/
999+
int xe_gt_sriov_pf_control_finish_restore_vf(struct xe_gt *gt, unsigned int vfid)
1000+
{
1001+
int ret;
1002+
1003+
if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
1004+
ret = pf_wait_vf_restore_done(gt, vfid);
1005+
if (ret)
1006+
return ret;
1007+
}
1008+
1009+
if (!pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED)) {
1010+
pf_enter_vf_mismatch(gt, vfid);
1011+
return -EIO;
1012+
}
1013+
1014+
pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
1015+
1016+
return 0;
1017+
}
1018+
7791019
/**
7801020
* DOC: The VF STOP state machine
7811021
*
@@ -817,6 +1057,8 @@ static void pf_enter_vf_stopped(struct xe_gt *gt, unsigned int vfid)
8171057

8181058
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESUMED);
8191059
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
1060+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED);
1061+
pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED);
8201062
pf_exit_vf_mismatch(gt, vfid);
8211063
pf_exit_vf_wip(gt, vfid);
8221064
}
@@ -1463,6 +1705,12 @@ static bool pf_process_vf_state_machine(struct xe_gt *gt, unsigned int vfid)
14631705
if (pf_exit_vf_pause_save_guc(gt, vfid))
14641706
return true;
14651707

1708+
if (pf_handle_vf_save(gt, vfid))
1709+
return true;
1710+
1711+
if (pf_handle_vf_restore(gt, vfid))
1712+
return true;
1713+
14661714
if (pf_exit_vf_resume_send_resume(gt, vfid))
14671715
return true;
14681716

drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ void xe_gt_sriov_pf_control_restart(struct xe_gt *gt);
1616

1717
int xe_gt_sriov_pf_control_pause_vf(struct xe_gt *gt, unsigned int vfid);
1818
int xe_gt_sriov_pf_control_resume_vf(struct xe_gt *gt, unsigned int vfid);
19+
int xe_gt_sriov_pf_control_trigger_save_vf(struct xe_gt *gt, unsigned int vfid);
20+
int xe_gt_sriov_pf_control_finish_save_vf(struct xe_gt *gt, unsigned int vfid);
21+
int xe_gt_sriov_pf_control_trigger_restore_vf(struct xe_gt *gt, unsigned int vfid);
22+
int xe_gt_sriov_pf_control_finish_restore_vf(struct xe_gt *gt, unsigned int vfid);
1923
int xe_gt_sriov_pf_control_stop_vf(struct xe_gt *gt, unsigned int vfid);
2024
int xe_gt_sriov_pf_control_trigger_flr(struct xe_gt *gt, unsigned int vfid);
2125
int xe_gt_sriov_pf_control_sync_flr(struct xe_gt *gt, unsigned int vfid, bool sync);

drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
* @XE_GT_SRIOV_STATE_PAUSE_SAVE_GUC: indicates that the PF needs to save the VF GuC state.
3232
* @XE_GT_SRIOV_STATE_PAUSE_FAILED: indicates that a VF pause operation has failed.
3333
* @XE_GT_SRIOV_STATE_PAUSED: indicates that the VF is paused.
34+
* @XE_GT_SRIOV_STATE_SAVE_WIP: indicates that VF save operation is in progress.
35+
* @XE_GT_SRIOV_STATE_SAVE_FAILED: indicates that VF save operation has failed.
36+
* @XE_GT_SRIOV_STATE_SAVED: indicates that VF data is saved.
37+
* @XE_GT_SRIOV_STATE_RESTORE_WIP: indicates that VF restore operation is in progress.
38+
* @XE_GT_SRIOV_STATE_RESTORE_FAILED: indicates that VF restore operation has failed.
39+
* @XE_GT_SRIOV_STATE_RESTORED: indicates that VF data is restored.
3440
* @XE_GT_SRIOV_STATE_RESUME_WIP: indicates the a VF resume operation is in progress.
3541
* @XE_GT_SRIOV_STATE_RESUME_SEND_RESUME: indicates that the PF is about to send RESUME command.
3642
* @XE_GT_SRIOV_STATE_RESUME_FAILED: indicates that a VF resume operation has failed.
@@ -63,6 +69,14 @@ enum xe_gt_sriov_control_bits {
6369
XE_GT_SRIOV_STATE_PAUSE_FAILED,
6470
XE_GT_SRIOV_STATE_PAUSED,
6571

72+
XE_GT_SRIOV_STATE_SAVE_WIP,
73+
XE_GT_SRIOV_STATE_SAVE_FAILED,
74+
XE_GT_SRIOV_STATE_SAVED,
75+
76+
XE_GT_SRIOV_STATE_RESTORE_WIP,
77+
XE_GT_SRIOV_STATE_RESTORE_FAILED,
78+
XE_GT_SRIOV_STATE_RESTORED,
79+
6680
XE_GT_SRIOV_STATE_RESUME_WIP,
6781
XE_GT_SRIOV_STATE_RESUME_SEND_RESUME,
6882
XE_GT_SRIOV_STATE_RESUME_FAILED,

0 commit comments

Comments
 (0)