From: Michal Wajdeczko <michal.wajdeczko@intel.com>
To: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>,
<intel-xe@lists.freedesktop.org>
Subject: Re: [PATCH 09/10] drm/xe/sriov: Add functions to set preempt timeouts for each group
Date: Tue, 2 Dec 2025 21:01:07 +0100 [thread overview]
Message-ID: <cc4c6142-17ef-428d-bc4b-59cdac7f446b@intel.com> (raw)
In-Reply-To: <20251127014507.2323746-21-daniele.ceraolospurio@intel.com>
On 11/27/2025 2:45 AM, Daniele Ceraolo Spurio wrote:
> The KLV to set the preemption timeout for each groups works the exact
> same way as the one for the exec quantums, so we add similar functions.
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
> ---
> drivers/gpu/drm/xe/abi/guc_klvs_abi.h | 12 ++
> drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 157 ++++++++++++++++++++-
> drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h | 8 ++
> 3 files changed, 173 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/abi/guc_klvs_abi.h b/drivers/gpu/drm/xe/abi/guc_klvs_abi.h
> index a0763cc15518..02547043a9e0 100644
> --- a/drivers/gpu/drm/xe/abi/guc_klvs_abi.h
> +++ b/drivers/gpu/drm/xe/abi/guc_klvs_abi.h
> @@ -393,6 +393,16 @@ enum {
> * the GuC always sets the EQ for all groups (even the non-enabled ones),
> * so if we provide fewer values than the max the GuC will use 0 for the
> * remaining groups.
> + *
> + * _`GUC_KLV_VF_CFG_ENGINE_GROUP_PREEMPT_TIMEOUT' : 0x8A0F
> + * This config sets the VFs-preemption-timeout for each scheduling group in
> + * microseconds. The driver must provide an array of values, with each of
> + * them matching the respective group index (first value goes to group 0,
> + * second to group 1, etc). The setting of group values follows the same
> + * behavior and rules as setting via GUC_KLV_VF_CFG_PREEMPT_TIMEOUT. Note
> + * that the GuC always sets the EQ for all groups (even the non-enabled
> + * ones), so if we provide fewer values than the max the GuC will use 0 for
> + * the remaining groups.
update xe_guc_klv_key_to_string()
> */
>
> #define GUC_KLV_VF_CFG_GGTT_START_KEY 0x0001
> @@ -456,6 +466,8 @@ enum {
>
> #define GUC_KLV_VF_CFG_ENGINE_GROUP_EXEC_QUANTUM_KEY 0x8a0e
>
> +#define GUC_KLV_VF_CFG_ENGINE_GROUP_PREEMPT_TIMEOUT_KEY 0x8a0f
add MIN_LEN and MAX_LEN
> +
> /*
> * Workaround keys:
> */
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> index 1bfb25bda432..deb79b2a7527 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> @@ -325,8 +325,15 @@ static u32 encode_config(struct xe_gt *gt, u32 *cfg,
> cfg[n++] = config->exec_quantum[0];
> }
>
> - cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_PREEMPT_TIMEOUT);
> - cfg[n++] = config->preempt_timeout[0];
> + if (xe_sriov_gt_pf_policy_has_valid_sched_group_modes(gt)) {
> + cfg[n++] = PREP_GUC_KLV_CONST(GUC_KLV_VF_CFG_ENGINE_GROUP_PREEMPT_TIMEOUT_KEY,
> + GUC_KLV_VGT_POLICY_ENGINE_GROUP_MAX_COUNT);
> + for (i = 0; i < GUC_KLV_VGT_POLICY_ENGINE_GROUP_MAX_COUNT; i++)
> + cfg[n++] = config->exec_quantum[i];
> + } else {
> + cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_PREEMPT_TIMEOUT);
> + cfg[n++] = config->preempt_timeout[0];
> + }
move to new encode_sched()
>
> #define encode_threshold_config(TAG, ...) ({ \
> cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_THRESHOLD_##TAG); \
> @@ -2207,11 +2214,16 @@ static int pf_provision_preempt_timeout(struct xe_gt *gt, unsigned int vfid,
> return 0;
> }
>
> -static u32 pf_get_preempt_timeout(struct xe_gt *gt, unsigned int vfid)
> +static u32 pf_get_group_preempt_timeout(struct xe_gt *gt, unsigned int vfid, u8 group)
> {
> struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid);
>
> - return config->preempt_timeout[0];
> + return config->preempt_timeout[group];
> +}
> +
> +static u32 pf_get_preempt_timeout(struct xe_gt *gt, unsigned int vfid)
> +{
> + return pf_get_group_preempt_timeout(gt, vfid, 0);
> }
>
> /**
> @@ -2317,6 +2329,138 @@ int xe_gt_sriov_pf_config_bulk_set_preempt_timeout_locked(struct xe_gt *gt, u32
> preempt_timeout_unit, n, err);
> }
>
> +static int pf_provision_groups_preempt_timeouts(struct xe_gt *gt, unsigned int vfid,
> + const u32 *preempt_timeouts, u32 count)
> +{
> + struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid);
> + int err;
> + int i;
> +
> + err = pf_push_vf_grp_cfg_u32(gt, vfid, GUC_KLV_VF_CFG_ENGINE_GROUP_PREEMPT_TIMEOUT_KEY,
> + preempt_timeouts, count);
> + if (unlikely(err))
> + return err;
> +
> + /*
> + * GuC silently clamps values exceeding the max and zeroes out the
> + * quantum for groups not in the array
" .. not in the KLV payload" ?
> + */
> + for (i = 0; i < GUC_KLV_VGT_POLICY_ENGINE_GROUP_MAX_COUNT; i++) {
> + if (i < count)
> + config->preempt_timeout[i] =
> + min_t(u32, preempt_timeouts[i],
> + GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_MAX_VALUE);
> + else
> + config->preempt_timeout[i] = 0;
> + }
> +
> + return 0;
> +}
> +
> +static void pf_get_groups_preempt_timeouts(struct xe_gt *gt, unsigned int vfid,
> + u32 *preempt_timeouts, u32 max_count)
> +{
> + struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid);
> + u32 count = min_t(u32, max_count, GUC_KLV_VGT_POLICY_ENGINE_GROUP_MAX_COUNT);
> +
> + memcpy(preempt_timeouts, config->preempt_timeout, sizeof(u32) * count);
> +}
> +
> +/**
> + * xe_gt_sriov_pf_config_set_groups_preempt_timeouts() - Configure PF/VF PTs for sched groups.
> + * @gt: the &xe_gt
> + * @vfid: the PF or VF identifier
> + * @preempt_timeouts: array of requested PTs in microseconds (0 is infinity)
> + * @count: number of entries in the array
> + *
> + * This function can only be called on PF.
> + * It will log the provisioned value or an error in case of the failure.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_config_set_groups_preempt_timeouts(struct xe_gt *gt, unsigned int vfid,
> + u32 *preempt_timeouts, u32 count)
> +{
> + int err;
> +
> + guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
> +
> + err = pf_provision_groups_preempt_timeouts(gt, vfid, preempt_timeouts, count);
> +
> + return pf_groups_cfg_set_u32_array_done(gt, vfid, preempt_timeouts, count,
> + pf_get_groups_preempt_timeouts,
> + "preempt_timeout",
> + preempt_timeout_unit, err);
> +}
> +
> +/**
> + * xe_gt_sriov_pf_config_get_groups_preempt_timeouts - Get PF/VF sched groups PTs
> + * @gt: the &xe_gt
> + * @vfid: the PF or VF identifier
> + * @preempt_timeouts: array in which to store the preemption timeouts values
> + * @max_count: maximum number of entries to store
> + *
> + * This function can only be called on PF.
> + */
> +void xe_gt_sriov_pf_config_get_groups_preempt_timeouts(struct xe_gt *gt, unsigned int vfid,
> + u32 *preempt_timeouts, u32 max_count)
> +{
> + guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
> +
> + return pf_get_groups_preempt_timeouts(gt, vfid, preempt_timeouts, max_count);
> +}
> +
> +/**
> + * xe_gt_sriov_pf_config_set_group_preempt_timeout - Configure PF/VF PT for a sched group.
> + * @gt: the &xe_gt
> + * @vfid: the PF or VF identifier
> + * @group: index of the group to configure
I don't think we need to expose per-group function to change PT as
GuC ABI does not allow to do that directly
for debugfs purposes it should be sufficient to read/configure all at once
> + * @preempt_timeout: requested PT in microseconds (0 is infinity)
> + *
> + * This function can only be called on PF.
> + * It will log the provisioned value or an error in case of the failure.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_config_set_group_preempt_timeout(struct xe_gt *gt, unsigned int vfid,
> + u8 group, u32 preempt_timeout)
> +{
> + u32 values[GUC_KLV_VGT_POLICY_ENGINE_GROUP_MAX_COUNT];
> + int err;
> +
> + xe_gt_assert(gt, group < GUC_KLV_VGT_POLICY_ENGINE_GROUP_MAX_COUNT);
> +
> + guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
> +
> + pf_get_groups_preempt_timeouts(gt, vfid, values, ARRAY_SIZE(values));
> + values[group] = preempt_timeout;
> +
> + err = pf_provision_groups_preempt_timeouts(gt, vfid, values, ARRAY_SIZE(values));
> +
> + return pf_group_config_set_u32_done(gt, vfid, group, preempt_timeout,
> + pf_get_group_preempt_timeout(gt, vfid, group),
> + "preempt_timeout", preempt_timeout_unit, err);
> +}
> +
> +/**
> + * xe_gt_sriov_pf_config_get_group_preempt_timeout - Get PF/VF PT for a sched groups
> + * @gt: the &xe_gt
> + * @vfid: the PF or VF identifier
> + * @group: index of the group for which to get the PT
> + *
> + * This function can only be called on PF.
> + *
> + * Return: preemption timeout in microseconds (or 0 if infinity).
> + */
> +u32 xe_gt_sriov_pf_config_get_group_preempt_timeout(struct xe_gt *gt, unsigned int vfid, u8 group)
> +{
> + xe_gt_assert(gt, group < GUC_KLV_VGT_POLICY_ENGINE_GROUP_MAX_COUNT);
> +
> + guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
> +
> + return pf_get_group_preempt_timeout(gt, vfid, group);
> +}
> +
> static const char *sched_priority_unit(u32 priority)
> {
> return priority == GUC_SCHED_PRIORITY_LOW ? "(low)" :
> @@ -2764,6 +2908,11 @@ static int pf_restore_vf_config_klv(struct xe_gt *gt, unsigned int vfid,
> return -EBADMSG;
> return pf_provision_groups_exec_quantums(gt, vfid, value, len);
>
> + case GUC_KLV_VF_CFG_ENGINE_GROUP_PREEMPT_TIMEOUT_KEY:
> + if (len > GUC_KLV_VGT_POLICY_ENGINE_GROUP_MAX_COUNT)
> + return -EBADMSG;
> + return pf_provision_groups_preempt_timeouts(gt, vfid, value, len);
> +
> case GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_KEY:
> if (len != GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_LEN)
> return -EBADMSG;
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h
> index aaf6bb824bc9..f4bfb26b2407 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h
> @@ -63,6 +63,14 @@ int xe_gt_sriov_pf_config_set_preempt_timeout_locked(struct xe_gt *gt, unsigned
> u32 preempt_timeout);
> int xe_gt_sriov_pf_config_bulk_set_preempt_timeout_locked(struct xe_gt *gt, u32 preempt_timeout);
>
> +void xe_gt_sriov_pf_config_get_groups_preempt_timeouts(struct xe_gt *gt, unsigned int vfid,
> + u32 *preempt_timeout, u32 max_count);
> +int xe_gt_sriov_pf_config_set_groups_preempt_timeouts(struct xe_gt *gt, unsigned int vfid,
> + u32 *preempt_timeout, u32 count);
> +u32 xe_gt_sriov_pf_config_get_group_preempt_timeout(struct xe_gt *gt, unsigned int vfid, u8 group);
> +int xe_gt_sriov_pf_config_set_group_preempt_timeout(struct xe_gt *gt, unsigned int vfid,
> + u8 group, u32 preempt_timeout);
> +
> u32 xe_gt_sriov_pf_config_get_sched_priority(struct xe_gt *gt, unsigned int vfid);
> int xe_gt_sriov_pf_config_set_sched_priority(struct xe_gt *gt, unsigned int vfid, u32 priority);
>
next prev parent reply other threads:[~2025-12-02 20:02 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-27 1:45 [PATCH 00/10] Introduce SRIOV scheduler groups Daniele Ceraolo Spurio
2025-11-27 1:45 ` [PATCH 01/10] drm/xe/gt: Add engine masks for each class Daniele Ceraolo Spurio
2025-12-01 16:52 ` Michal Wajdeczko
2025-11-27 1:45 ` [PATCH 02/10] drm/xe/sriov: Initialize scheduler groups Daniele Ceraolo Spurio
2025-12-01 22:37 ` Michal Wajdeczko
2025-12-01 23:33 ` Daniele Ceraolo Spurio
2025-12-02 21:08 ` Michal Wajdeczko
2025-12-02 23:02 ` Daniele Ceraolo Spurio
2025-12-03 1:15 ` Daniele Ceraolo Spurio
2025-11-27 1:45 ` [PATCH 03/10] drm/xe/sriov: Add support for enabling " Daniele Ceraolo Spurio
2025-12-02 11:49 ` Michal Wajdeczko
2025-12-02 17:39 ` Daniele Ceraolo Spurio
2025-12-04 22:06 ` Daniele Ceraolo Spurio
2025-11-27 1:45 ` [PATCH 04/10] drm/xe/sriov: Scheduler groups are incompatible with multi-lrc Daniele Ceraolo Spurio
2025-12-02 13:32 ` Michal Wajdeczko
2025-12-02 17:57 ` Daniele Ceraolo Spurio
2025-12-02 21:17 ` Michal Wajdeczko
2025-12-02 21:25 ` Daniele Ceraolo Spurio
2025-12-02 21:37 ` Michal Wajdeczko
2025-12-02 21:42 ` Daniele Ceraolo Spurio
2025-11-27 1:45 ` [PATCH 05/10] drm/xe/sriov: Add debugfs to enable scheduler groups Daniele Ceraolo Spurio
2025-12-02 15:52 ` Michal Wajdeczko
2025-12-02 18:03 ` Daniele Ceraolo Spurio
2025-12-02 21:24 ` Michal Wajdeczko
2025-11-27 1:45 ` [PATCH 06/10] drm/xe/sriov: Add debugfs with scheduler groups information Daniele Ceraolo Spurio
2025-12-02 16:24 ` Michal Wajdeczko
2025-12-02 18:20 ` Daniele Ceraolo Spurio
2025-12-02 21:31 ` Michal Wajdeczko
2025-11-27 1:45 ` [PATCH 07/10] drm/xe/sriov: Prep for multiple exec quantums and preemption timeouts Daniele Ceraolo Spurio
2025-12-02 16:42 ` Michal Wajdeczko
2025-12-06 1:55 ` Daniele Ceraolo Spurio
2025-11-27 1:45 ` [PATCH 08/10] drm/xe/sriov: Add functions to set exec quantums for each group Daniele Ceraolo Spurio
2025-12-02 19:54 ` Michal Wajdeczko
2025-12-06 1:58 ` Daniele Ceraolo Spurio
2025-11-27 1:45 ` [PATCH 09/10] drm/xe/sriov: Add functions to set preempt timeouts " Daniele Ceraolo Spurio
2025-12-02 20:01 ` Michal Wajdeczko [this message]
2025-11-27 1:45 ` [PATCH 10/10] drm/xe/sriov: Add debugfs to set EQ and PT for scheduler groups Daniele Ceraolo Spurio
2025-12-02 20:17 ` Michal Wajdeczko
2025-12-06 1:53 ` Daniele Ceraolo Spurio
2025-11-27 1:51 ` ✗ CI.checkpatch: warning for Introduce SRIOV " Patchwork
2025-11-27 1:52 ` ✓ CI.KUnit: success " Patchwork
2025-11-27 2:36 ` ✗ Xe.CI.BAT: failure " Patchwork
2025-11-27 3:18 ` ✗ Xe.CI.Full: " Patchwork
2025-12-01 17:46 ` Daniele Ceraolo Spurio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cc4c6142-17ef-428d-bc4b-59cdac7f446b@intel.com \
--to=michal.wajdeczko@intel.com \
--cc=daniele.ceraolospurio@intel.com \
--cc=intel-xe@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox