On Fri, Oct 31, 2025 at 07:26:29PM +0100, Michal Wajdeczko wrote: > > > On 10/30/2025 9:31 PM, Michał Winiarski wrote: > > Connect the helpers to allow save and restore of GGTT migration data in > > stop_copy / resume device state. > > > > Signed-off-by: Michał Winiarski <[email protected]> > > --- > > drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c | 13 ++ > > drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c | 113 ++++++++++++++++++ > > drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h | 3 + > > 3 files changed, 129 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 cb45e97f4c4d9..e7ea9b88fd246 100644 > > --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c > > +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c > > @@ -860,6 +860,16 @@ static int pf_handle_vf_save_data(struct xe_gt *gt, > > unsigned int vfid) > > return -EAGAIN; > > } > > > > + if (xe_gt_sriov_pf_migration_save_test(gt, vfid, > > XE_SRIOV_MIGRATION_DATA_TYPE_GGTT)) { > > + ret = xe_gt_sriov_pf_migration_ggtt_save(gt, vfid); > > + if (ret) > > + return ret; > > + > > + xe_gt_sriov_pf_migration_save_clear(gt, vfid, > > XE_SRIOV_MIGRATION_DATA_TYPE_GGTT); > > + > > + return -EAGAIN; > > + } > > + > > return 0; > > } > > > > @@ -1066,6 +1076,9 @@ static int pf_handle_vf_restore_data(struct xe_gt > > *gt, unsigned int vfid) > > xe_gt_assert(gt, data); > > > > switch (data->type) { > > + case XE_SRIOV_MIGRATION_DATA_TYPE_GGTT: > > + ret = xe_gt_sriov_pf_migration_ggtt_restore(gt, vfid, data); > > + break; > > case XE_SRIOV_MIGRATION_DATA_TYPE_GUC: > > ret = xe_gt_sriov_pf_migration_guc_restore(gt, vfid, data); > > break; > > diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c > > b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c > > index fbb451767712a..6f2ee5820bdd4 100644 > > --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c > > +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c > > @@ -7,6 +7,9 @@ > > > > #include "abi/guc_actions_sriov_abi.h" > > #include "xe_bo.h" > > +#include "xe_ggtt.h" > > +#include "xe_gt.h" > > +#include "xe_gt_sriov_pf_config.h" > > #include "xe_gt_sriov_pf_control.h" > > #include "xe_gt_sriov_pf_helpers.h" > > #include "xe_gt_sriov_pf_migration.h" > > @@ -39,6 +42,106 @@ static void pf_dump_mig_data(struct xe_gt *gt, unsigned > > int vfid, > > } > > } > > > > +static ssize_t pf_migration_ggtt_size(struct xe_gt *gt, unsigned int vfid) > > +{ > > + if (!xe_gt_is_main_type(gt)) > > + return 0; > > + > > + return xe_gt_sriov_pf_config_ggtt_save(gt, vfid, NULL, 0); > > +} > > + > > +static int pf_save_vf_ggtt_mig_data(struct xe_gt *gt, unsigned int vfid) > > +{ > > + struct xe_sriov_migration_data *data; > > + size_t size; > > + int ret; > > + > > + size = pf_migration_ggtt_size(gt, vfid); > > + xe_gt_assert(gt, size); > > + > > + data = xe_sriov_migration_data_alloc(gt_to_xe(gt)); > > + if (!data) > > + return -ENOMEM; > > + > > + ret = xe_sriov_migration_data_init(data, gt->tile->id, gt->info.id, > > + XE_SRIOV_MIGRATION_DATA_TYPE_GGTT, > > 0, size); > > + if (ret) > > + goto fail; > > + > > + ret = xe_gt_sriov_pf_config_ggtt_save(gt, vfid, data->vaddr, size); > > + if (ret) > > + goto fail; > > + > > + xe_gt_sriov_dbg_verbose(gt, "VF%u GGTT data save (%zu bytes)\n", vfid, > > size); > > + pf_dump_mig_data(gt, vfid, data); > > + > > + ret = xe_gt_sriov_pf_migration_save_produce(gt, vfid, data); > > + if (ret) > > + goto fail; > > + > > + return 0; > > + > > +fail: > > + xe_sriov_migration_data_free(data); > > + xe_gt_sriov_err(gt, "Failed to save VF%u GGTT data (%pe)\n", vfid, > > ERR_PTR(ret)); > > + return ret; > > +} > > + > > +static int pf_restore_vf_ggtt_mig_data(struct xe_gt *gt, unsigned int vfid, > > + struct xe_sriov_migration_data *data) > > +{ > > + int ret; > > + > > + xe_gt_sriov_dbg_verbose(gt, "VF%u GGTT data restore (%llu bytes)\n", > > vfid, data->size); > > + pf_dump_mig_data(gt, vfid, data); > > + > > + ret = xe_gt_sriov_pf_config_ggtt_restore(gt, vfid, data->vaddr, > > data->size); > > + if (ret) { > > + xe_gt_sriov_err(gt, "Failed to restore VF%u GGTT data (%pe)\n", > > + vfid, ERR_PTR(ret)); > > + return ret; > > + } > > + > > + return 0; > > +} > > + > > +/** > > + * xe_gt_sriov_pf_migration_ggtt_save() - Save VF GGTT migration data. > > + * @gt: the &xe_gt > > + * @vfid: the VF identifier (can't be 0) > > + * > > + * This function is for PF only. > > + * > > + * Return: 0 on success or a negative error code on failure. > > + */ > > +int xe_gt_sriov_pf_migration_ggtt_save(struct xe_gt *gt, unsigned int vfid) > > +{ > > + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); > > + xe_gt_assert(gt, vfid != PFID); > > + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); > > + > > + return pf_save_vf_ggtt_mig_data(gt, vfid); > > +} > > + > > +/** > > + * xe_gt_sriov_pf_migration_ggtt_restore() - Restore VF GGTT migration > > data. > > + * @gt: the &xe_gt > > + * @vfid: the VF identifier (can't be 0) > > + * > > + * This function is for PF only. > > + * > > + * Return: 0 on success or a negative error code on failure. > > + */ > > +int xe_gt_sriov_pf_migration_ggtt_restore(struct xe_gt *gt, unsigned int > > vfid, > > + struct xe_sriov_migration_data *data) > > +{ > > + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); > > + xe_gt_assert(gt, vfid != PFID); > > + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); > > + > > + return pf_restore_vf_ggtt_mig_data(gt, vfid, data); > > +} > > + > > /* Return: number of dwords saved/restored/required or a negative error > > code on failure */ > > static int guc_action_vf_save_restore(struct xe_guc *guc, u32 vfid, u32 > > opcode, > > u64 addr, u32 ndwords) > > @@ -279,6 +382,13 @@ ssize_t xe_gt_sriov_pf_migration_size(struct xe_gt > > *gt, unsigned int vfid) > > size += sizeof(struct xe_sriov_pf_migration_hdr); > > total += size; > > > > + size = pf_migration_ggtt_size(gt, vfid); > > + if (size < 0) > > + return size; > > + if (size > 0) > > + size += sizeof(struct xe_sriov_pf_migration_hdr); > > + total += size; > > + > > return total; > > } > > > > @@ -340,6 +450,9 @@ void xe_gt_sriov_pf_migration_save_init(struct xe_gt > > *gt, unsigned int vfid) > > > > xe_gt_assert(gt, pf_migration_guc_size(gt, vfid) > 0); > > set_bit(XE_SRIOV_MIGRATION_DATA_TYPE_GUC, > > &migration->save.data_remaining); > > + > > + if (pf_migration_ggtt_size(gt, vfid) > 0) > > + set_bit(XE_SRIOV_MIGRATION_DATA_TYPE_GGTT, > > &migration->save.data_remaining); > > btw, does it make sense to save GuC data if there is no GGTT data on the main > GT?
Not in a sense that such provisioning is usable, but we do not want to have any dependencies between data types, and we do need to handle this corner case (not fail the migration if GGTT size is set to 0). > > > } > > > > /** > > diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h > > b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h > > index 66a45d6234245..bc201d8f3147a 100644 > > --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h > > +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h > > @@ -19,6 +19,9 @@ int xe_gt_sriov_pf_migration_init(struct xe_gt *gt); > > int xe_gt_sriov_pf_migration_guc_save(struct xe_gt *gt, unsigned int vfid); > > int xe_gt_sriov_pf_migration_guc_restore(struct xe_gt *gt, unsigned int > > vfid, > > struct xe_sriov_migration_data *data); > > +int xe_gt_sriov_pf_migration_ggtt_save(struct xe_gt *gt, unsigned int > > vfid); > > +int xe_gt_sriov_pf_migration_ggtt_restore(struct xe_gt *gt, unsigned int > > vfid, > > + struct xe_sriov_migration_data *data); > > > > ssize_t xe_gt_sriov_pf_migration_size(struct xe_gt *gt, unsigned int vfid); > > > > only one nit question about corner case, so > > Reviewed-by: Michal Wajdeczko <[email protected]> > Thanks, -Michał
