drm/xe/vf: Check if scheduler groups are enabled
authorDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Thu, 18 Dec 2025 22:38:52 +0000 (14:38 -0800)
committerDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Mon, 22 Dec 2025 18:22:07 +0000 (10:22 -0800)
VF can check if PF has enabled scheduler groups with a dedicated KLV
query. If scheduler groups are enabled, MLRC queue registrations are
forbidden.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Link: https://patch.msgid.link/20251218223846.1146344-20-daniele.ceraolospurio@intel.com
drivers/gpu/drm/xe/abi/guc_klvs_abi.h
drivers/gpu/drm/xe/xe_exec_queue.c
drivers/gpu/drm/xe/xe_gt_sriov_vf.c
drivers/gpu/drm/xe/xe_gt_sriov_vf.h
drivers/gpu/drm/xe/xe_gt_sriov_vf_types.h
drivers/gpu/drm/xe/xe_guc_klv_helpers.c

index ac10cf3..39dee68 100644 (file)
  *      Refers to 32 bit architecture version as reported by the HW IP.
  *      This key is supported on MTL+ platforms only.
  *      Requires GuC ABI 1.2+.
+ *
+ * _`GUC_KLV_GLOBAL_CFG_GROUP_SCHEDULING_AVAILABLE` : 0x3001
+ *      Tells the driver whether scheduler groups are enabled or not.
+ *      Requires GuC ABI 1.26+
  */
 
 #define GUC_KLV_GLOBAL_CFG_GMD_ID_KEY                  0x3000u
 #define GUC_KLV_GLOBAL_CFG_GMD_ID_LEN                  1u
 
+#define GUC_KLV_GLOBAL_CFG_GROUP_SCHEDULING_AVAILABLE_KEY      0x3001u
+#define GUC_KLV_GLOBAL_CFG_GROUP_SCHEDULING_AVAILABLE_LEN      1u
+
 /**
  * DOC: GuC Self Config KLVs
  *
index c336dcd..0b9e074 100644 (file)
@@ -1114,6 +1114,9 @@ static bool has_sched_groups(struct xe_gt *gt)
        if (IS_SRIOV_PF(gt_to_xe(gt)) && xe_gt_sriov_pf_sched_groups_enabled(gt))
                return true;
 
+       if (IS_SRIOV_VF(gt_to_xe(gt)) && xe_gt_sriov_vf_sched_groups_enabled(gt))
+               return true;
+
        return false;
 }
 
index b8b391c..d91c65d 100644 (file)
@@ -612,6 +612,52 @@ static void vf_cache_gmdid(struct xe_gt *gt)
        gt->sriov.vf.runtime.gmdid = xe_gt_sriov_vf_gmdid(gt);
 }
 
+static int vf_query_sched_groups(struct xe_gt *gt)
+{
+       struct xe_guc *guc = &gt->uc.guc;
+       struct xe_uc_fw_version guc_version;
+       u32 value = 0;
+       int err;
+
+       xe_gt_sriov_vf_guc_versions(gt, NULL, &guc_version);
+
+       if (MAKE_GUC_VER_STRUCT(guc_version) < MAKE_GUC_VER(1, 26, 0))
+               return 0;
+
+       err = guc_action_query_single_klv32(guc,
+                                           GUC_KLV_GLOBAL_CFG_GROUP_SCHEDULING_AVAILABLE_KEY,
+                                           &value);
+       if (unlikely(err)) {
+               xe_gt_sriov_err(gt, "Failed to obtain sched groups status (%pe)\n",
+                               ERR_PTR(err));
+               return err;
+       }
+
+       /* valid values are 0 (disabled) and 1 (enabled) */
+       if (value > 1) {
+               xe_gt_sriov_err(gt, "Invalid sched groups status %u\n", value);
+               return -EPROTO;
+       }
+
+       xe_gt_sriov_dbg(gt, "sched groups %s\n", str_enabled_disabled(value));
+       return value;
+}
+
+static int vf_cache_sched_groups_status(struct xe_gt *gt)
+{
+       int ret;
+
+       xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
+
+       ret = vf_query_sched_groups(gt);
+       if (ret < 0)
+               return ret;
+
+       gt->sriov.vf.runtime.uses_sched_groups = ret;
+
+       return 0;
+}
+
 /**
  * xe_gt_sriov_vf_query_config - Query SR-IOV config data over MMIO.
  * @gt: the &xe_gt
@@ -641,12 +687,33 @@ int xe_gt_sriov_vf_query_config(struct xe_gt *gt)
        if (unlikely(err))
                return err;
 
+       err = vf_cache_sched_groups_status(gt);
+       if (unlikely(err))
+               return err;
+
        if (has_gmdid(xe))
                vf_cache_gmdid(gt);
 
        return 0;
 }
 
+/**
+ * xe_gt_sriov_vf_sched_groups_enabled() - Check if PF has enabled multiple
+ * scheduler groups
+ * @gt: the &xe_gt
+ *
+ * This function is for VF use only.
+ *
+ * Return: true if shed groups were enabled, false otherwise.
+ */
+bool xe_gt_sriov_vf_sched_groups_enabled(struct xe_gt *gt)
+{
+       xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
+       xe_gt_assert(gt, gt->sriov.vf.guc_version.major);
+
+       return gt->sriov.vf.runtime.uses_sched_groups;
+}
+
 /**
  * xe_gt_sriov_vf_guc_ids - VF GuC context IDs configuration.
  * @gt: the &xe_gt
index af40276..7d97189 100644 (file)
@@ -30,6 +30,7 @@ bool xe_gt_sriov_vf_recovery_pending(struct xe_gt *gt);
 u32 xe_gt_sriov_vf_gmdid(struct xe_gt *gt);
 u16 xe_gt_sriov_vf_guc_ids(struct xe_gt *gt);
 u64 xe_gt_sriov_vf_lmem(struct xe_gt *gt);
+bool xe_gt_sriov_vf_sched_groups_enabled(struct xe_gt *gt);
 
 u32 xe_gt_sriov_vf_read32(struct xe_gt *gt, struct xe_reg reg);
 void xe_gt_sriov_vf_write32(struct xe_gt *gt, struct xe_reg reg, u32 val);
index 510c331..9a6b567 100644 (file)
@@ -27,6 +27,8 @@ struct xe_gt_sriov_vf_selfconfig {
 struct xe_gt_sriov_vf_runtime {
        /** @gmdid: cached value of the GDMID register. */
        u32 gmdid;
+       /** @uses_sched_groups: whether PF enabled sched groups or not. */
+       bool uses_sched_groups;
        /** @regs_size: size of runtime register array. */
        u32 regs_size;
        /** @num_regs: number of runtime registers in the array. */
index 1b08b44..dd504b7 100644 (file)
@@ -21,6 +21,9 @@
 const char *xe_guc_klv_key_to_string(u16 key)
 {
        switch (key) {
+       /* GuC Global Config KLVs */
+       case GUC_KLV_GLOBAL_CFG_GROUP_SCHEDULING_AVAILABLE_KEY:
+               return "group_scheduling_available";
        /* VGT POLICY keys */
        case GUC_KLV_VGT_POLICY_SCHED_IF_IDLE_KEY:
                return "sched_if_idle";