pf_version->major, pf_version->minor);
}
-static void vf_post_migration_shutdown(struct xe_gt *gt)
+static bool vf_post_migration_shutdown(struct xe_gt *gt)
{
+ struct xe_device *xe = gt_to_xe(gt);
+
+ /*
+ * On platforms where CCS must be restored by the primary GT, the media
+ * GT's VF post-migration recovery must run afterward. Detect this case
+ * and re-queue the media GT's restore work item if necessary.
+ */
+ if (xe->info.needs_shared_vf_gt_wq && xe_gt_is_media_type(gt)) {
+ struct xe_gt *primary_gt = gt_to_tile(gt)->primary_gt;
+
+ if (xe_gt_sriov_vf_recovery_pending(primary_gt))
+ return true;
+ }
+
spin_lock_irq(>->sriov.vf.migration.lock);
gt->sriov.vf.migration.recovery_queued = false;
spin_unlock_irq(>->sriov.vf.migration.lock);
xe_guc_ct_flush_and_stop(>->uc.guc.ct);
xe_guc_submit_pause(>->uc.guc);
xe_tlb_inval_reset(>->tlb_inval);
+
+ return false;
}
static size_t post_migration_scratch_size(struct xe_device *xe)
{
struct xe_device *xe = gt_to_xe(gt);
int err;
+ bool retry;
xe_gt_sriov_dbg(gt, "migration recovery in progress\n");
xe_pm_runtime_get(xe);
- vf_post_migration_shutdown(gt);
+ retry = vf_post_migration_shutdown(gt);
+ if (retry)
+ goto queue;
if (!xe_sriov_vf_migration_supported(xe)) {
xe_gt_sriov_err(gt, "migration is not supported\n");
xe_pm_runtime_put(xe);
xe_gt_sriov_err(gt, "migration recovery failed (%pe)\n", ERR_PTR(err));
xe_device_declare_wedged(xe);
+ return;
+
+queue:
+ xe_gt_sriov_info(gt, "Re-queuing migration recovery\n");
+ queue_work(gt->ordered_wq, >->sriov.vf.migration.worker);
+ xe_pm_runtime_put(xe);
}
static void migration_worker_func(struct work_struct *w)