]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
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 ac10cf3adbc150c9712939385212f3f633fd7c69..39dee685a92c714a460258b1ee5973664b59fd7c 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 c336dcd19020b8f50ebae7f905e18746766b78bf..0b9e074b022fffa64b6d133af390b4cb2571be47 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 b8b391cfc8eb81b54d5a73d0bb88e4274a4c23bf..d91c65dc349603afe25cbee0ce70dea80238e8fc 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 af40276790fadb21a28c22afe0f83053e5dcd8ef..7d97189c2d3d9da81d1b9a2e73f3ea6308c8ea68 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 510c33116fbdb3820066531c25b2d0cbbaeda2bb..9a6b5672d569b6a8112de33b12bb210fa5702292 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 1b08b443606e0a658f1323bd3bb985d8afc46a6c..dd504b77cb17684a64fdf8dc6f2f7f389c71a973 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";