drm/xe/pf: Add functions to provision scheduling priority

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
This commit is contained in:
Michal Wajdeczko 2025-10-30 23:23:42 +01:00
parent 71f5933c4b
commit 23ceec1e03
2 changed files with 97 additions and 0 deletions

View 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;
}

View 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);