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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.