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

Signed-off-by: Michał Winiarski <[email protected]>
Reviewed-by: Michal Wajdeczko <[email protected]>
---
 drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c   | 27 ++++++-
 drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c | 71 +++++++++++++++----
 drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h |  8 ++-
 .../drm/xe/xe_gt_sriov_pf_migration_types.h   |  5 ++
 4 files changed, 93 insertions(+), 18 deletions(-)

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 5e8b6929a827d..198bf0c93a4c8 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c
@@ -853,6 +853,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;
 }
 
@@ -891,6 +905,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);
@@ -1078,12 +1093,20 @@ 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->type);
+       switch (data->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->type);
+               break;
+       }
 
        xe_sriov_packet_free(data);
 
-       return 0;
+       return ret;
 }
 
 static bool pf_handle_vf_restore(struct xe_gt *gt, unsigned int vfid)
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 6e2b076065f3b..676205e04487b 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
@@ -176,23 +176,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;
 
@@ -279,12 +266,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_pf_migration_hdr);
+       total += size;
+
        return total;
 }
 
@@ -331,6 +325,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
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 fd81942bfd7a2..1cba651b521fe 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h
@@ -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 *
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration_types.h 
b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration_types.h
index 75d8b94cbbefb..9f24878690d9c 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration_types.h
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration_types.h
@@ -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
-- 
2.51.2

Reply via email to