]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/pf: Add functions to provision scheduling priority
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Thu, 30 Oct 2025 22:23:42 +0000 (23:23 +0100)
committerMichal Wajdeczko <michal.wajdeczko@intel.com>
Fri, 31 Oct 2025 19:01:44 +0000 (20:01 +0100)
We already have function to configure PF (or VF) scheduling priority
on a single GT, but we also need function that will cover all tiles
and GTs.

However, due to the current GuC FW limitation, we can't always rely
on per-GT function as it actually only works for the PF case. The
only way to change VFs scheduling priority is to use 'sched_if_idle'
policy KLV that will change priorities for all VFs (and the PF).

We will use these new functions in the upcoming patches.

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
Link: https://patch.msgid.link/20251030222348.186658-12-michal.wajdeczko@intel.com
drivers/gpu/drm/xe/xe_sriov_pf_provision.c
drivers/gpu/drm/xe/xe_sriov_pf_provision.h

index 0f5bcc076b783ec0c9a506fc35d3334f8496c3f9..01470c42e8a72f51843a6313423c63e8c4ba4fee 100644 (file)
@@ -6,6 +6,7 @@
 #include "xe_assert.h"
 #include "xe_device.h"
 #include "xe_gt_sriov_pf_config.h"
+#include "xe_gt_sriov_pf_policy.h"
 #include "xe_sriov.h"
 #include "xe_sriov_pf_helpers.h"
 #include "xe_sriov_pf_provision.h"
@@ -343,3 +344,95 @@ int xe_sriov_pf_provision_query_vf_pt(struct xe_device *xe, unsigned int vfid, u
 
        return !count ? -ENODATA : 0;
 }
+
+/**
+ * xe_sriov_pf_provision_bulk_apply_priority() - Change scheduling priority of all VFs and PF.
+ * @xe: the PF &xe_device
+ * @prio: scheduling priority to set
+ *
+ * Change the scheduling priority provisioning on all tiles/GTs.
+ *
+ * This function can only be called on PF.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int xe_sriov_pf_provision_bulk_apply_priority(struct xe_device *xe, u32 prio)
+{
+       bool sched_if_idle;
+       struct xe_gt *gt;
+       unsigned int id;
+       int result = 0;
+       int err;
+
+       /*
+        * Currently, priority changes that involves VFs are only allowed using
+        * the 'sched_if_idle' policy KLV, so only LOW and NORMAL are supported.
+        */
+       xe_assert(xe, prio < GUC_SCHED_PRIORITY_HIGH);
+       sched_if_idle = prio == GUC_SCHED_PRIORITY_NORMAL;
+
+       for_each_gt(gt, xe, id) {
+               err = xe_gt_sriov_pf_policy_set_sched_if_idle(gt, sched_if_idle);
+               result = result ?: err;
+       }
+
+       return result;
+}
+
+/**
+ * xe_sriov_pf_provision_apply_vf_priority() - Change VF's scheduling priority.
+ * @xe: the PF &xe_device
+ * @vfid: the VF identifier
+ * @prio: scheduling priority to set
+ *
+ * Change VF's scheduling priority provisioning on all tiles/GTs.
+ *
+ * This function can only be called on PF.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int xe_sriov_pf_provision_apply_vf_priority(struct xe_device *xe, unsigned int vfid, u32 prio)
+{
+       struct xe_gt *gt;
+       unsigned int id;
+       int result = 0;
+       int err;
+
+       for_each_gt(gt, xe, id) {
+               err = xe_gt_sriov_pf_config_set_sched_priority(gt, vfid, prio);
+               result = result ?: err;
+       }
+
+       return result;
+}
+
+/**
+ * xe_sriov_pf_provision_query_vf_priority() - Query VF's scheduling priority.
+ * @xe: the PF &xe_device
+ * @vfid: the VF identifier
+ * @prio: placeholder for the returned scheduling priority
+ *
+ * Query VF's scheduling priority provisioning from all tiles/GTs.
+ * If values across tiles/GTs are inconsistent then -EUCLEAN error will be returned.
+ *
+ * This function can only be called on PF.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int xe_sriov_pf_provision_query_vf_priority(struct xe_device *xe, unsigned int vfid, u32 *prio)
+{
+       struct xe_gt *gt;
+       unsigned int id;
+       int count = 0;
+       u32 value;
+
+       for_each_gt(gt, xe, id) {
+               value = xe_gt_sriov_pf_config_get_sched_priority(gt, vfid);
+               if (!count++)
+                       *prio = value;
+               else if (value != *prio)
+                       return pf_report_unclean(gt, vfid, "priority", value, *prio);
+       }
+
+       return !count ? -ENODATA : 0;
+}
index aa8a95b1c0becb22665bf1a973860a36d514cd8d..bccf23d51396ba3734ac54c667350c20e544d91d 100644 (file)
@@ -20,6 +20,10 @@ int xe_sriov_pf_provision_bulk_apply_pt(struct xe_device *xe, u32 pt);
 int xe_sriov_pf_provision_apply_vf_pt(struct xe_device *xe, unsigned int vfid, u32 pt);
 int xe_sriov_pf_provision_query_vf_pt(struct xe_device *xe, unsigned int vfid, u32 *pt);
 
+int xe_sriov_pf_provision_bulk_apply_priority(struct xe_device *xe, u32 prio);
+int xe_sriov_pf_provision_apply_vf_priority(struct xe_device *xe, unsigned int vfid, u32 prio);
+int xe_sriov_pf_provision_query_vf_priority(struct xe_device *xe, unsigned int vfid, u32 *prio);
+
 int xe_sriov_pf_provision_vfs(struct xe_device *xe, unsigned int num_vfs);
 int xe_sriov_pf_unprovision_vfs(struct xe_device *xe, unsigned int num_vfs);