drm/xe/pf: Handle GuC migration data as part of PF control

Connect the helpers to allow save and restore of GuC migration data in
stop_copy / resume device state.

Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Link: https://patch.msgid.link/20251112132220.516975-17-michal.winiarski@intel.com
Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
This commit is contained in:
Michał Winiarski 2025-11-12 14:22:12 +01:00
parent 642a30a946
commit 762a9f2998
4 changed files with 94 additions and 18 deletions

View File

@ -854,6 +854,20 @@ static void pf_enter_vf_save_failed(struct xe_gt *gt, unsigned int vfid)
static int pf_handle_vf_save_data(struct xe_gt *gt, unsigned int vfid)
{
int ret;
if (xe_gt_sriov_pf_migration_save_data_pending(gt, vfid,
XE_SRIOV_PACKET_TYPE_GUC)) {
ret = xe_gt_sriov_pf_migration_guc_save(gt, vfid);
if (ret)
return ret;
xe_gt_sriov_pf_migration_save_data_complete(gt, vfid,
XE_SRIOV_PACKET_TYPE_GUC);
return -EAGAIN;
}
return 0;
}
@ -892,6 +906,7 @@ static void pf_exit_vf_save_wait_data(struct xe_gt *gt, unsigned int vfid)
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)) {
xe_gt_sriov_pf_migration_save_init(gt, vfid);
pf_enter_vf_wip(gt, vfid);
pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_PROCESS_DATA);
pf_queue_vf(gt, vfid);
@ -1079,12 +1094,21 @@ static void pf_enter_vf_restore_failed(struct xe_gt *gt, unsigned int vfid)
static int pf_handle_vf_restore_data(struct xe_gt *gt, unsigned int vfid)
{
struct xe_sriov_packet *data = xe_gt_sriov_pf_migration_restore_consume(gt, vfid);
int ret = 0;
xe_gt_sriov_notice(gt, "Skipping VF%u unknown data type: %d\n", vfid, data->hdr.type);
switch (data->hdr.type) {
case XE_SRIOV_PACKET_TYPE_GUC:
ret = xe_gt_sriov_pf_migration_guc_restore(gt, vfid, data);
break;
default:
xe_gt_sriov_notice(gt, "Skipping VF%u unknown data type: %d\n",
vfid, data->hdr.type);
break;
}
xe_sriov_packet_free(data);
return 0;
return ret;
}
static bool pf_handle_vf_restore(struct xe_gt *gt, unsigned int vfid)

View File

@ -177,23 +177,10 @@ static int pf_save_vf_guc_mig_data(struct xe_gt *gt, unsigned int vfid)
return ret;
}
/**
* xe_gt_sriov_pf_migration_guc_size() - Get the size of VF GuC migration data.
* @gt: the &xe_gt
* @vfid: the VF identifier
*
* This function is for PF only.
*
* Return: size in bytes or a negative error code on failure.
*/
ssize_t xe_gt_sriov_pf_migration_guc_size(struct xe_gt *gt, unsigned int vfid)
static ssize_t pf_migration_guc_size(struct xe_gt *gt, unsigned int vfid)
{
ssize_t size;
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)));
if (!pf_migration_supported(gt))
return -ENOPKG;
@ -281,12 +268,19 @@ int xe_gt_sriov_pf_migration_guc_restore(struct xe_gt *gt, unsigned int vfid,
ssize_t xe_gt_sriov_pf_migration_size(struct xe_gt *gt, unsigned int vfid)
{
ssize_t total = 0;
ssize_t size;
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)));
/* Nothing to query yet - will be updated once per-GT migration data types are added */
size = pf_migration_guc_size(gt, vfid);
if (size < 0)
return size;
if (size > 0)
size += sizeof(struct xe_sriov_packet_hdr);
total += size;
return total;
}
@ -333,6 +327,53 @@ void xe_gt_sriov_pf_migration_ring_free(struct xe_gt *gt, unsigned int vfid)
xe_sriov_packet_free(data);
}
static void pf_migration_save_data_todo(struct xe_gt *gt, unsigned int vfid,
enum xe_sriov_packet_type type)
{
set_bit(type, &pf_pick_gt_migration(gt, vfid)->save.data_remaining);
}
/**
* xe_gt_sriov_pf_migration_save_init() - Initialize per-GT migration related data.
* @gt: the &xe_gt
* @vfid: the VF identifier (can't be 0)
*/
void xe_gt_sriov_pf_migration_save_init(struct xe_gt *gt, unsigned int vfid)
{
struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, vfid);
migration->save.data_remaining = 0;
xe_gt_assert(gt, pf_migration_guc_size(gt, vfid) > 0);
pf_migration_save_data_todo(gt, vfid, XE_SRIOV_PACKET_TYPE_GUC);
}
/**
* xe_gt_sriov_pf_migration_save_data_pending() - Check if migration data type needs to be saved.
* @gt: the &xe_gt
* @vfid: the VF identifier (can't be 0)
* @type: the &xe_sriov_packet_type of data to be checked
*
* Return: true if the data needs saving, otherwise false.
*/
bool xe_gt_sriov_pf_migration_save_data_pending(struct xe_gt *gt, unsigned int vfid,
enum xe_sriov_packet_type type)
{
return test_bit(type, &pf_pick_gt_migration(gt, vfid)->save.data_remaining);
}
/**
* xe_gt_sriov_pf_migration_save_data_complete() - Complete migration data type save.
* @gt: the &xe_gt
* @vfid: the VF identifier (can't be 0)
* @type: the &xe_sriov_packet_type to be marked as completed.
*/
void xe_gt_sriov_pf_migration_save_data_complete(struct xe_gt *gt, unsigned int vfid,
enum xe_sriov_packet_type type)
{
clear_bit(type, &pf_pick_gt_migration(gt, vfid)->save.data_remaining);
}
/**
* xe_gt_sriov_pf_migration_save_produce() - Add VF save data packet to migration ring.
* @gt: the &xe_gt

View File

@ -10,12 +10,12 @@
struct xe_gt;
struct xe_sriov_packet;
enum xe_sriov_packet_type;
/* TODO: get this information by querying GuC in the future */
#define XE_GT_SRIOV_PF_MIGRATION_GUC_DATA_MAX_SIZE SZ_8M
int xe_gt_sriov_pf_migration_init(struct xe_gt *gt);
ssize_t xe_gt_sriov_pf_migration_guc_size(struct xe_gt *gt, unsigned int vfid);
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_packet *data);
@ -26,6 +26,12 @@ bool xe_gt_sriov_pf_migration_ring_empty(struct xe_gt *gt, unsigned int vfid);
bool xe_gt_sriov_pf_migration_ring_full(struct xe_gt *gt, unsigned int vfid);
void xe_gt_sriov_pf_migration_ring_free(struct xe_gt *gt, unsigned int vfid);
void xe_gt_sriov_pf_migration_save_init(struct xe_gt *gt, unsigned int vfid);
bool xe_gt_sriov_pf_migration_save_data_pending(struct xe_gt *gt, unsigned int vfid,
enum xe_sriov_packet_type type);
void xe_gt_sriov_pf_migration_save_data_complete(struct xe_gt *gt, unsigned int vfid,
enum xe_sriov_packet_type type);
int xe_gt_sriov_pf_migration_save_produce(struct xe_gt *gt, unsigned int vfid,
struct xe_sriov_packet *data);
struct xe_sriov_packet *

View File

@ -16,6 +16,11 @@
struct xe_gt_sriov_migration_data {
/** @ring: queue containing VF save / restore migration data */
struct ptr_ring ring;
/** @save: structure for currently processed save migration data */
struct {
/** @save.data_remaining: bitmap of migration types that need to be saved */
unsigned long data_remaining;
} save;
};
#endif