From: Michal Wajdeczko <michal.wajdeczko@intel.com>
To: "Michał Winiarski" <michal.winiarski@intel.com>,
"Alex Williamson" <alex.williamson@redhat.com>,
"Lucas De Marchi" <lucas.demarchi@intel.com>,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
"Jason Gunthorpe" <jgg@ziepe.ca>,
"Yishai Hadas" <yishaih@nvidia.com>,
"Kevin Tian" <kevin.tian@intel.com>,
intel-xe@lists.freedesktop.org, linux-kernel@vger.kernel.org,
kvm@vger.kernel.org, "Matthew Brost" <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>,
Jani Nikula <jani.nikula@linux.intel.com>,
Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
Tvrtko Ursulin <tursulin@ursulin.net>,
David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
"Lukasz Laguna" <lukasz.laguna@intel.com>
Subject: Re: [PATCH v2 03/26] drm/xe/pf: Add save/restore control state stubs and connect to debugfs
Date: Thu, 23 Oct 2025 00:31:47 +0200 [thread overview]
Message-ID: <fdf1ebb7-e8dd-4228-9b13-588e2e617b15@intel.com> (raw)
In-Reply-To: <20251021224133.577765-4-michal.winiarski@intel.com>
On 10/22/2025 12:41 AM, Michał Winiarski wrote:
> The states will be used by upcoming changes to produce (in case of save)
> or consume (in case of resume) the VF migration data.
>
> Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
> ---
> drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c | 248 ++++++++++++++++++
> drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h | 6 +
> .../gpu/drm/xe/xe_gt_sriov_pf_control_types.h | 14 +
> drivers/gpu/drm/xe/xe_sriov_pf_control.c | 96 +++++++
> drivers/gpu/drm/xe/xe_sriov_pf_control.h | 4 +
> drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c | 38 +++
> 6 files changed, 406 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c
> index 2e6bd3d1fe1da..b770916e88e53 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c
> @@ -184,6 +184,12 @@ static const char *control_bit_to_string(enum xe_gt_sriov_control_bits bit)
> CASE2STR(PAUSE_SAVE_GUC);
> CASE2STR(PAUSE_FAILED);
> CASE2STR(PAUSED);
> + CASE2STR(SAVE_WIP);
> + CASE2STR(SAVE_FAILED);
> + CASE2STR(SAVED);
> + CASE2STR(RESTORE_WIP);
> + CASE2STR(RESTORE_FAILED);
> + CASE2STR(RESTORED);
> CASE2STR(RESUME_WIP);
> CASE2STR(RESUME_SEND_RESUME);
> CASE2STR(RESUME_FAILED);
> @@ -208,6 +214,8 @@ static unsigned long pf_get_default_timeout(enum xe_gt_sriov_control_bits bit)
> case XE_GT_SRIOV_STATE_FLR_WIP:
> case XE_GT_SRIOV_STATE_FLR_RESET_CONFIG:
> return 5 * HZ;
> + case XE_GT_SRIOV_STATE_RESTORE_WIP:
> + return 20 * HZ;
> default:
> return HZ;
> }
> @@ -329,6 +337,8 @@ static void pf_exit_vf_mismatch(struct xe_gt *gt, unsigned int vfid)
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_FAILED);
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESUME_FAILED);
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_FAILED);
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_FAILED);
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_FAILED);
> }
>
> #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)
>
> static void pf_exit_vf_flr_wip(struct xe_gt *gt, unsigned int vfid);
> static void pf_exit_vf_stop_wip(struct xe_gt *gt, unsigned int vfid);
> +static void pf_exit_vf_save_wip(struct xe_gt *gt, unsigned int vfid);
> +static void pf_exit_vf_restore_wip(struct xe_gt *gt, unsigned int vfid);
> static void pf_exit_vf_pause_wip(struct xe_gt *gt, unsigned int vfid);
> static void pf_exit_vf_resume_wip(struct xe_gt *gt, unsigned int vfid);
>
> @@ -380,6 +392,8 @@ static void pf_exit_vf_wip(struct xe_gt *gt, unsigned int vfid)
>
> pf_exit_vf_flr_wip(gt, vfid);
> pf_exit_vf_stop_wip(gt, vfid);
> + pf_exit_vf_save_wip(gt, vfid);
> + pf_exit_vf_restore_wip(gt, vfid);
> pf_exit_vf_pause_wip(gt, vfid);
> pf_exit_vf_resume_wip(gt, vfid);
>
> @@ -399,6 +413,8 @@ static void pf_enter_vf_ready(struct xe_gt *gt, unsigned int vfid)
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_STOPPED);
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESUMED);
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED);
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED);
> pf_exit_vf_mismatch(gt, vfid);
> pf_exit_vf_wip(gt, vfid);
> }
> @@ -675,6 +691,8 @@ static void pf_enter_vf_resumed(struct xe_gt *gt, unsigned int vfid)
> {
> pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESUMED);
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED);
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED);
> pf_exit_vf_mismatch(gt, vfid);
> pf_exit_vf_wip(gt, vfid);
> }
> @@ -753,6 +771,16 @@ int xe_gt_sriov_pf_control_resume_vf(struct xe_gt *gt, unsigned int vfid)
> return -EPERM;
> }
>
> + if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP)) {
> + xe_gt_sriov_dbg(gt, "VF%u save is in progress!\n", vfid);
> + return -EBUSY;
> + }
> +
> + if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
> + xe_gt_sriov_dbg(gt, "VF%u restore is in progress!\n", vfid);
> + return -EBUSY;
> + }
> +
> if (!pf_enter_vf_resume_wip(gt, vfid)) {
> xe_gt_sriov_dbg(gt, "VF%u resume already in progress!\n", vfid);
> return -EALREADY;
> @@ -776,6 +804,218 @@ int xe_gt_sriov_pf_control_resume_vf(struct xe_gt *gt, unsigned int vfid)
> return -ECANCELED;
> }
>
> +static void pf_exit_vf_save_wip(struct xe_gt *gt, unsigned int vfid)
> +{
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP);
> +}
> +
> +static void pf_enter_vf_saved(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED))
> + pf_enter_vf_state_machine_bug(gt, vfid);
> +
> + xe_gt_sriov_dbg(gt, "VF%u saved!\n", vfid);
nit: you can move expect(PAUSED) here
> +
> + pf_exit_vf_mismatch(gt, vfid);
> + pf_exit_vf_wip(gt, vfid);
> + pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
> +}
> +
> +static bool pf_handle_vf_save(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP))
> + return false;
> +
> + pf_enter_vf_saved(gt, vfid);
> +
> + return true;
> +}
> +
> +static bool pf_enter_vf_save_wip(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP)) {
> + pf_enter_vf_wip(gt, vfid);
> + pf_queue_vf(gt, vfid);
> + return true;
> + }
> +
> + return false;
> +}
> +
> +/**
> + * xe_gt_sriov_pf_control_trigger_save_vf() - Start an SR-IOV VF migration data save sequence.
> + * @gt: the &xe_gt
> + * @vfid: the VF identifier
> + *
> + * This function is for PF only.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_control_trigger_save_vf(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_STOPPED)) {
> + xe_gt_sriov_dbg(gt, "VF%u is stopped!\n", vfid);
> + return -EPERM;
> + }
> +
> + if (!pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED)) {
> + xe_gt_sriov_dbg(gt, "VF%u is not paused!\n", vfid);
> + return -EPERM;
> + }
> +
> + if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
> + xe_gt_sriov_dbg(gt, "VF%u restore is in progress!\n", vfid);
> + return -EBUSY;
> + }
> +
> + if (!pf_enter_vf_save_wip(gt, vfid)) {
> + xe_gt_sriov_dbg(gt, "VF%u save already in progress!\n", vfid);
> + return -EALREADY;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * xe_gt_sriov_pf_control_finish_save_vf() - Complete a VF migration data save sequence.
> + * @gt: the &xe_gt
> + * @vfid: the VF identifier
> + *
> + * This function is for PF only.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_control_finish_save_vf(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (!pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED)) {
> + pf_enter_vf_mismatch(gt, vfid);
> + return -EIO;
> + }
> +
> + pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
> +
> + return 0;
> +}
> +
> +static void pf_exit_vf_restore_wip(struct xe_gt *gt, unsigned int vfid)
> +{
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP);
> +}
> +
> +static void pf_enter_vf_restored(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED))
> + pf_enter_vf_state_machine_bug(gt, vfid);
> +
> + xe_gt_sriov_dbg(gt, "VF%u restored!\n", vfid);
> +
> + pf_exit_vf_mismatch(gt, vfid);
> + pf_exit_vf_wip(gt, vfid);
> + pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
> +}
> +
> +static bool pf_handle_vf_restore(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP))
> + return false;
> +
> + pf_enter_vf_restored(gt, vfid);
> +
> + return true;
> +}
> +
> +static bool pf_enter_vf_restore_wip(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
> + pf_enter_vf_wip(gt, vfid);
> + pf_queue_vf(gt, vfid);
> + return true;
> + }
> +
> + return false;
> +}
> +
> +/**
> + * xe_gt_sriov_pf_control_trigger restore_vf() - Start an SR-IOV VF migration data restore sequence.
> + * @gt: the &xe_gt
> + * @vfid: the VF identifier
> + *
> + * This function is for PF only.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_control_trigger_restore_vf(struct xe_gt *gt, unsigned int vfid)
> +{
> + if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_STOPPED)) {
> + xe_gt_sriov_dbg(gt, "VF%u is stopped!\n", vfid);
> + return -EPERM;
> + }
> +
> + if (!pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED)) {
> + xe_gt_sriov_dbg(gt, "VF%u is not paused!\n", vfid);
> + return -EPERM;
> + }
> +
> + if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP)) {
> + xe_gt_sriov_dbg(gt, "VF%u save is in progress!\n", vfid);
> + return -EBUSY;
> + }
> +
> + if (!pf_enter_vf_restore_wip(gt, vfid)) {
> + xe_gt_sriov_dbg(gt, "VF%u restore already in progress!\n", vfid);
> + return -EALREADY;
> + }
> +
> + return 0;
> +}
> +
> +static int pf_wait_vf_restore_done(struct xe_gt *gt, unsigned int vfid)
> +{
> + unsigned long timeout = pf_get_default_timeout(XE_GT_SRIOV_STATE_RESTORE_WIP);
> + int err;
> +
> + err = pf_wait_vf_wip_done(gt, vfid, timeout);
> + if (err) {
> + xe_gt_sriov_notice(gt, "VF%u RESTORE didn't finish in %u ms (%pe)\n",
> + vfid, jiffies_to_msecs(timeout), ERR_PTR(err));
> + return err;
> + }
> +
> + if (!pf_expect_vf_not_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_FAILED))
> + return -EIO;
> +
> + return 0;
> +}
> +
> +/**
> + * xe_gt_sriov_pf_control_finish_restore_vf() - Complete a VF migration data restore sequence.
> + * @gt: the &xe_gt
> + * @vfid: the VF identifier
> + *
> + * This function is for PF only.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_control_finish_restore_vf(struct xe_gt *gt, unsigned int vfid)
> +{
> + int ret;
> +
> + if (pf_check_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
> + ret = pf_wait_vf_restore_done(gt, vfid);
> + if (ret)
> + return ret;
> + }
> +
> + if (!pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED)) {
> + pf_enter_vf_mismatch(gt, vfid);
> + return -EIO;
> + }
> +
> + pf_expect_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
> +
> + return 0;
> +}
> +
> /**
> * DOC: The VF STOP state machine
> *
> @@ -817,6 +1057,8 @@ static void pf_enter_vf_stopped(struct xe_gt *gt, unsigned int vfid)
>
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESUMED);
> pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSED);
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVED);
> + pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORED);
> pf_exit_vf_mismatch(gt, vfid);
> pf_exit_vf_wip(gt, vfid);
> }
> @@ -1461,6 +1703,12 @@ static bool pf_process_vf_state_machine(struct xe_gt *gt, unsigned int vfid)
> if (pf_exit_vf_pause_save_guc(gt, vfid))
> return true;
>
> + if (pf_handle_vf_save(gt, vfid))
> + return true;
> +
> + if (pf_handle_vf_restore(gt, vfid))
> + return true;
> +
> if (pf_exit_vf_resume_send_resume(gt, vfid))
> return true;
>
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h
> index 8a72ef3778d47..abc233f6302ed 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.h
> @@ -14,8 +14,14 @@ struct xe_gt;
> int xe_gt_sriov_pf_control_init(struct xe_gt *gt);
> void xe_gt_sriov_pf_control_restart(struct xe_gt *gt);
>
> +bool xe_gt_sriov_pf_control_check_vf_data_wip(struct xe_gt *gt, unsigned int vfid);
> +
> int xe_gt_sriov_pf_control_pause_vf(struct xe_gt *gt, unsigned int vfid);
> int xe_gt_sriov_pf_control_resume_vf(struct xe_gt *gt, unsigned int vfid);
> +int xe_gt_sriov_pf_control_trigger_save_vf(struct xe_gt *gt, unsigned int vfid);
> +int xe_gt_sriov_pf_control_finish_save_vf(struct xe_gt *gt, unsigned int vfid);
> +int xe_gt_sriov_pf_control_trigger_restore_vf(struct xe_gt *gt, unsigned int vfid);
> +int xe_gt_sriov_pf_control_finish_restore_vf(struct xe_gt *gt, unsigned int vfid);
> int xe_gt_sriov_pf_control_stop_vf(struct xe_gt *gt, unsigned int vfid);
> int xe_gt_sriov_pf_control_trigger_flr(struct xe_gt *gt, unsigned int vfid);
> int xe_gt_sriov_pf_control_sync_flr(struct xe_gt *gt, unsigned int vfid, bool sync);
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h
> index c80b7e77f1ad2..e113dc98b33ce 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h
> @@ -31,6 +31,12 @@
> * @XE_GT_SRIOV_STATE_PAUSE_SAVE_GUC: indicates that the PF needs to save the VF GuC state.
> * @XE_GT_SRIOV_STATE_PAUSE_FAILED: indicates that a VF pause operation has failed.
> * @XE_GT_SRIOV_STATE_PAUSED: indicates that the VF is paused.
> + * @XE_GT_SRIOV_STATE_SAVE_WIP: indicates that VF save operation is in progress.
> + * @XE_GT_SRIOV_STATE_SAVE_FAILED: indicates that VF save operation has failed.
> + * @XE_GT_SRIOV_STATE_SAVED: indicates that VF data is saved.
> + * @XE_GT_SRIOV_STATE_RESTORE_WIP: indicates that VF restore operation is in progress.
> + * @XE_GT_SRIOV_STATE_RESTORE_FAILED: indicates that VF restore operation has failed.
> + * @XE_GT_SRIOV_STATE_RESTORED: indicates that VF data is restored.
> * @XE_GT_SRIOV_STATE_RESUME_WIP: indicates the a VF resume operation is in progress.
> * @XE_GT_SRIOV_STATE_RESUME_SEND_RESUME: indicates that the PF is about to send RESUME command.
> * @XE_GT_SRIOV_STATE_RESUME_FAILED: indicates that a VF resume operation has failed.
> @@ -63,6 +69,14 @@ enum xe_gt_sriov_control_bits {
> XE_GT_SRIOV_STATE_PAUSE_FAILED,
> XE_GT_SRIOV_STATE_PAUSED,
>
> + XE_GT_SRIOV_STATE_SAVE_WIP,
> + XE_GT_SRIOV_STATE_SAVE_FAILED,
> + XE_GT_SRIOV_STATE_SAVED,
> +
> + XE_GT_SRIOV_STATE_RESTORE_WIP,
> + XE_GT_SRIOV_STATE_RESTORE_FAILED,
> + XE_GT_SRIOV_STATE_RESTORED,
> +
> XE_GT_SRIOV_STATE_RESUME_WIP,
> XE_GT_SRIOV_STATE_RESUME_SEND_RESUME,
> XE_GT_SRIOV_STATE_RESUME_FAILED,
it is easier to understand those states after patch 04/26 with diagrams,
and while there are small and hard to avoid overlaps between 03/26 and 04/26
the patch itself LGTM, so
Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
> diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_control.c b/drivers/gpu/drm/xe/xe_sriov_pf_control.c
> index 416d00a03fbb7..8d8a01faf5291 100644
> --- a/drivers/gpu/drm/xe/xe_sriov_pf_control.c
> +++ b/drivers/gpu/drm/xe/xe_sriov_pf_control.c
> @@ -149,3 +149,99 @@ int xe_sriov_pf_control_sync_flr(struct xe_device *xe, unsigned int vfid)
>
> return 0;
> }
> +
> +/**
> + * xe_sriov_pf_control_trigger_save_vf - Start a VF migration data SAVE sequence on all GTs.
> + * @xe: the &xe_device
> + * @vfid: the VF identifier
> + *
> + * This function is for PF only.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_pf_control_trigger_save_vf(struct xe_device *xe, unsigned int vfid)
> +{
> + struct xe_gt *gt;
> + unsigned int id;
> + int ret;
> +
> + for_each_gt(gt, xe, id) {
> + ret = xe_gt_sriov_pf_control_trigger_save_vf(gt, vfid);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * xe_sriov_pf_control_finish_save_vf - Complete a VF migration data SAVE sequence on all GTs.
> + * @xe: the &xe_device
> + * @vfid: the VF identifier
> + *
> + * This function is for PF only.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_pf_control_finish_save_vf(struct xe_device *xe, unsigned int vfid)
> +{
> + struct xe_gt *gt;
> + unsigned int id;
> + int ret;
> +
> + for_each_gt(gt, xe, id) {
> + ret = xe_gt_sriov_pf_control_finish_save_vf(gt, vfid);
> + if (ret)
> + break;
> + }
> +
> + return ret;
> +}
> +
> +/**
> + * xe_sriov_pf_control_trigger_restore_vf - Start a VF migration data RESTORE sequence on all GTs.
> + * @xe: the &xe_device
> + * @vfid: the VF identifier
> + *
> + * This function is for PF only.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_pf_control_trigger_restore_vf(struct xe_device *xe, unsigned int vfid)
> +{
> + struct xe_gt *gt;
> + unsigned int id;
> + int ret;
> +
> + for_each_gt(gt, xe, id) {
> + ret = xe_gt_sriov_pf_control_trigger_restore_vf(gt, vfid);
> + if (ret)
> + return ret;
> + }
> +
> + return ret;
> +}
> +
> +/**
> + * xe_sriov_pf_control_wait_restore_vf - Complete a VF migration data RESTORE sequence in all GTs.
> + * @xe: the &xe_device
> + * @vfid: the VF identifier
> + *
> + * This function is for PF only.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_pf_control_finish_restore_vf(struct xe_device *xe, unsigned int vfid)
> +{
> + struct xe_gt *gt;
> + unsigned int id;
> + int ret;
> +
> + for_each_gt(gt, xe, id) {
> + ret = xe_gt_sriov_pf_control_finish_restore_vf(gt, vfid);
> + if (ret)
> + break;
> + }
> +
> + return ret;
> +}
> diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_control.h b/drivers/gpu/drm/xe/xe_sriov_pf_control.h
> index 2d52d0ac1b28f..30318c1fba34e 100644
> --- a/drivers/gpu/drm/xe/xe_sriov_pf_control.h
> +++ b/drivers/gpu/drm/xe/xe_sriov_pf_control.h
> @@ -13,5 +13,9 @@ int xe_sriov_pf_control_resume_vf(struct xe_device *xe, unsigned int vfid);
> int xe_sriov_pf_control_stop_vf(struct xe_device *xe, unsigned int vfid);
> int xe_sriov_pf_control_reset_vf(struct xe_device *xe, unsigned int vfid);
> int xe_sriov_pf_control_sync_flr(struct xe_device *xe, unsigned int vfid);
> +int xe_sriov_pf_control_trigger_save_vf(struct xe_device *xe, unsigned int vfid);
> +int xe_sriov_pf_control_finish_save_vf(struct xe_device *xe, unsigned int vfid);
> +int xe_sriov_pf_control_trigger_restore_vf(struct xe_device *xe, unsigned int vfid);
> +int xe_sriov_pf_control_finish_restore_vf(struct xe_device *xe, unsigned int vfid);
>
> #endif
> diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
> index a81aa05c55326..e0e6340c49106 100644
> --- a/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
> +++ b/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
> @@ -136,11 +136,31 @@ static void pf_populate_pf(struct xe_device *xe, struct dentry *pfdent)
> * │ │ ├── reset
> * │ │ ├── resume
> * │ │ ├── stop
> + * │ │ ├── save
> + * │ │ ├── restore
> * │ │ :
> * │ ├── vf2
> * │ │ ├── ...
> */
>
> +static int from_file_read_to_vf_call(struct seq_file *s,
> + int (*call)(struct xe_device *, unsigned int))
> +{
> + struct dentry *dent = file_dentry(s->file)->d_parent;
> + struct xe_device *xe = extract_xe(dent);
> + unsigned int vfid = extract_vfid(dent);
> + int ret;
> +
> + xe_pm_runtime_get(xe);
> + ret = call(xe, vfid);
> + xe_pm_runtime_put(xe);
> +
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> static ssize_t from_file_write_to_vf_call(struct file *file, const char __user *userbuf,
> size_t count, loff_t *ppos,
> int (*call)(struct xe_device *, unsigned int))
> @@ -179,10 +199,26 @@ static ssize_t OP##_write(struct file *file, const char __user *userbuf, \
> } \
> DEFINE_SHOW_STORE_ATTRIBUTE(OP)
>
> +#define DEFINE_VF_CONTROL_ATTRIBUTE_RW(OP) \
> +static int OP##_show(struct seq_file *s, void *unused) \
> +{ \
> + return from_file_read_to_vf_call(s, \
> + xe_sriov_pf_control_finish_##OP); \
> +} \
> +static ssize_t OP##_write(struct file *file, const char __user *userbuf, \
> + size_t count, loff_t *ppos) \
> +{ \
> + return from_file_write_to_vf_call(file, userbuf, count, ppos, \
> + xe_sriov_pf_control_trigger_##OP); \
> +} \
> +DEFINE_SHOW_STORE_ATTRIBUTE(OP)
> +
> DEFINE_VF_CONTROL_ATTRIBUTE(pause_vf);
> DEFINE_VF_CONTROL_ATTRIBUTE(resume_vf);
> DEFINE_VF_CONTROL_ATTRIBUTE(stop_vf);
> DEFINE_VF_CONTROL_ATTRIBUTE(reset_vf);
> +DEFINE_VF_CONTROL_ATTRIBUTE_RW(save_vf);
> +DEFINE_VF_CONTROL_ATTRIBUTE_RW(restore_vf);
>
> static void pf_populate_vf(struct xe_device *xe, struct dentry *vfdent)
> {
> @@ -190,6 +226,8 @@ static void pf_populate_vf(struct xe_device *xe, struct dentry *vfdent)
> debugfs_create_file("resume", 0200, vfdent, xe, &resume_vf_fops);
> debugfs_create_file("stop", 0200, vfdent, xe, &stop_vf_fops);
> debugfs_create_file("reset", 0200, vfdent, xe, &reset_vf_fops);
> + debugfs_create_file("save", 0600, vfdent, xe, &save_vf_fops);
> + debugfs_create_file("restore", 0600, vfdent, xe, &restore_vf_fops);
> }
>
> static void pf_populate_with_tiles(struct xe_device *xe, struct dentry *dent, unsigned int vfid)
next prev parent reply other threads:[~2025-10-22 22:31 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-21 22:41 [PATCH v2 00/26] vfio/xe: Add driver variant for Xe VF migration Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 01/26] drm/xe/pf: Remove GuC version check for migration support Michał Winiarski
2025-10-28 2:33 ` Tian, Kevin
2025-10-28 8:06 ` Winiarski, Michal
2025-10-21 22:41 ` [PATCH v2 02/26] drm/xe: Move migration support to device-level struct Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 03/26] drm/xe/pf: Add save/restore control state stubs and connect to debugfs Michał Winiarski
2025-10-22 22:31 ` Michal Wajdeczko [this message]
2025-10-27 12:02 ` Michał Winiarski
2025-10-28 3:06 ` Tian, Kevin
2025-10-28 8:02 ` Michal Wajdeczko
2025-10-21 22:41 ` [PATCH v2 04/26] drm/xe/pf: Add data structures and handlers for migration rings Michał Winiarski
2025-10-22 22:06 ` Michal Wajdeczko
2025-10-27 12:33 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 05/26] drm/xe/pf: Add helpers for migration data allocation / free Michał Winiarski
2025-10-22 22:18 ` Michal Wajdeczko
2025-10-27 12:47 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 06/26] drm/xe/pf: Add support for encap/decap of bitstream to/from packet Michał Winiarski
2025-10-22 22:34 ` Michal Wajdeczko
2025-10-27 13:27 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 07/26] drm/xe/pf: Add minimalistic migration descriptor Michał Winiarski
2025-10-22 22:49 ` Michal Wajdeczko
2025-10-27 14:52 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 08/26] drm/xe/pf: Expose VF migration data size over debugfs Michał Winiarski
2025-10-22 23:02 ` Michal Wajdeczko
2025-10-21 22:41 ` [PATCH v2 09/26] drm/xe: Add sa/guc_buf_cache sync interface Michał Winiarski
2025-10-22 23:05 ` Michal Wajdeczko
2025-10-21 22:41 ` [PATCH v2 10/26] drm/xe: Allow the caller to pass guc_buf_cache size Michał Winiarski
2025-10-22 23:13 ` Michal Wajdeczko
2025-10-21 22:41 ` [PATCH v2 11/26] drm/xe/pf: Increase PF GuC Buffer Cache size and use it for VF migration Michał Winiarski
2025-10-23 17:37 ` Michal Wajdeczko
2025-10-28 10:46 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 12/26] drm/xe/pf: Remove GuC migration data save/restore from GT debugfs Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 13/26] drm/xe/pf: Don't save GuC VF migration data on pause Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 14/26] drm/xe/pf: Switch VF migration GuC save/restore to struct migration data Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 15/26] drm/xe/pf: Handle GuC migration data as part of PF control Michał Winiarski
2025-10-23 20:39 ` Michal Wajdeczko
2025-10-28 13:04 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 16/26] drm/xe/pf: Add helpers for VF GGTT migration data handling Michał Winiarski
2025-10-23 21:50 ` Michal Wajdeczko
2025-10-28 17:03 ` Michał Winiarski
2025-10-28 3:22 ` Tian, Kevin
2025-10-28 7:38 ` Michal Wajdeczko
2025-10-21 22:41 ` [PATCH v2 17/26] drm/xe/pf: Handle GGTT migration data as part of PF control Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 18/26] drm/xe/pf: Add helpers for VF MMIO migration data handling Michał Winiarski
2025-10-23 22:10 ` Michal Wajdeczko
2025-10-28 23:37 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 19/26] drm/xe/pf: Handle MMIO migration data as part of PF control Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 20/26] drm/xe/pf: Add helper to retrieve VF's LMEM object Michał Winiarski
2025-10-23 20:25 ` Michal Wajdeczko
2025-10-28 23:40 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 21/26] drm/xe/migrate: Add function to copy of VRAM data in chunks Michał Winiarski
2025-10-23 19:29 ` Michal Wajdeczko
2025-10-30 6:07 ` Laguna, Lukasz
2025-10-21 22:41 ` [PATCH v2 22/26] drm/xe/pf: Handle VRAM migration data as part of PF control Michał Winiarski
2025-10-23 11:44 ` kernel test robot
2025-10-23 19:54 ` Michal Wajdeczko
2025-10-29 8:54 ` Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 23/26] drm/xe/pf: Add wait helper for VF FLR Michał Winiarski
2025-10-21 22:41 ` [PATCH v2 24/26] drm/xe/pf: Enable SR-IOV VF migration for PTL and BMG Michał Winiarski
2025-10-23 20:15 ` Michal Wajdeczko
2025-10-21 22:41 ` [PATCH v2 25/26] drm/xe/pf: Export helpers for VFIO Michał Winiarski
2025-10-28 3:28 ` Tian, Kevin
2025-10-21 22:41 ` [PATCH v2 26/26] vfio/xe: Add vendor-specific vfio_pci driver for Intel graphics Michał Winiarski
2025-10-22 7:12 ` Christoph Hellwig
2025-10-22 8:52 ` Michał Winiarski
2025-10-22 8:54 ` Christoph Hellwig
2025-10-22 9:12 ` Michał Winiarski
2025-10-22 11:33 ` Jason Gunthorpe
2025-10-22 13:27 ` Michał Winiarski
2025-10-27 7:24 ` Tian, Kevin
2025-10-29 20:46 ` Winiarski, Michal
2025-10-27 7:26 ` Tian, Kevin
2025-10-21 22:50 ` ✗ CI.checkpatch: warning for vfio/xe: Add driver variant for Xe VF migration (rev2) Patchwork
2025-10-21 22:52 ` ✓ CI.KUnit: success " Patchwork
2025-10-21 23:31 ` ✓ Xe.CI.BAT: " Patchwork
2025-10-22 2:54 ` ✗ Xe.CI.Full: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fdf1ebb7-e8dd-4228-9b13-588e2e617b15@intel.com \
--to=michal.wajdeczko@intel.com \
--cc=airlied@gmail.com \
--cc=alex.williamson@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=jgg@ziepe.ca \
--cc=joonas.lahtinen@linux.intel.com \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lucas.demarchi@intel.com \
--cc=lukasz.laguna@intel.com \
--cc=matthew.brost@intel.com \
--cc=michal.winiarski@intel.com \
--cc=rodrigo.vivi@intel.com \
--cc=simona@ffwll.ch \
--cc=thomas.hellstrom@linux.intel.com \
--cc=tursulin@ursulin.net \
--cc=yishaih@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.