drm/xe/reg_sr: Don't process gt/hwe lists in VF

There are a few different reg_sr lists managed by the driver for
workarounds/tuning:

 - gt->reg_sr
 - hwe->reg_sr
 - hwe->reg_lrc

The first two are not relevant to SRIOV VFs; a VF KMD does not have
access to the registers that appear on this list and it is the PF KMD's
responsibility to apply such programming on behalf of the entire system.
However the third list contains per-client values that the VF KMD needs
to ensure are incorporated whenever a new LRC is created.

Handling of reg_sr lists comes in two steps: processing an RTP table to
build a reg_sr from the relevant entries, and then applying the contents
of the reg_sr.  Skipping the RTP processing (resulting in an empty
reg_sr) or skipping the application of a reg_sr are both valid ways to
avoid having a VF accidentally try to write registers it doesn't have
access to.  In commit c19e705ec9 ("drm/xe/vf: Stop applying
save-restore MMIOs if VF") and commit 92a5bd3024 ("drm/xe/vf: Unblock
xe_rtp_process_to_sr for VFs") we adjusted the drivers behavior to
always process the RTP table into a reg_sr and just skipped the
application step.  This works fine functionally, but can lead to
confusion during debugging since facilities like the debugfs
'register-save-restore' will still report a bunch of registers that the
VF KMD isn't actually trying to handle.  It will also mislead other
upcoming debug changes.

Let's go back to skipping the RTP => reg_sr processing step, but only
for GT / hwe tables this time.  This will allow LRC reg_sr handling to
continue to work, but will ensure that gt->reg_sr and hwe->reg_sr remain
empty and that debugfs reporting more accurately reflects the KMD's
behavior.

v2:
 - Also skip the hwe processing in hw_engine_setup_default_state() and
   xe_reg_whitelist_process_engine().

v3:
 - Handle skipping via an additional parameter passed to
   xe_rtp_process_to_sr() rather than adding conditions at each
   callsite.  (Ashutosh)

Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Ashutosh Dixit <ashutosh.dixit@intel.com>
Cc: Harish Chegondi <harish.chegondi@intel.com>
Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Link: https://patch.msgid.link/20260218-sr_verify-v4-1-35d6deeb3421@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
This commit is contained in:
Matt Roper
2026-02-18 14:09:12 -08:00
parent 6c2e331c91
commit a41ee215b5
8 changed files with 34 additions and 14 deletions

View File

@@ -322,7 +322,8 @@ static void xe_rtp_process_to_sr_tests(struct kunit *test)
count_rtp_entries++;
xe_rtp_process_ctx_enable_active_tracking(&ctx, &active, count_rtp_entries);
xe_rtp_process_to_sr(&ctx, param->entries, count_rtp_entries, reg_sr);
xe_rtp_process_to_sr(&ctx, param->entries, count_rtp_entries,
reg_sr, false);
xa_for_each(&reg_sr->xa, idx, sre) {
if (idx == param->expected_reg.addr)

View File

@@ -408,7 +408,8 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe)
},
};
xe_rtp_process_to_sr(&ctx, lrc_setup, ARRAY_SIZE(lrc_setup), &hwe->reg_lrc);
xe_rtp_process_to_sr(&ctx, lrc_setup, ARRAY_SIZE(lrc_setup),
&hwe->reg_lrc, true);
}
static void
@@ -472,7 +473,8 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
},
};
xe_rtp_process_to_sr(&ctx, engine_entries, ARRAY_SIZE(engine_entries), &hwe->reg_sr);
xe_rtp_process_to_sr(&ctx, engine_entries, ARRAY_SIZE(engine_entries),
&hwe->reg_sr, false);
}
static const struct engine_info *find_engine_info(enum xe_engine_class class, int instance)

View File

@@ -13,6 +13,7 @@
#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include "xe_assert.h"
#include "xe_device.h"
#include "xe_device_types.h"
#include "xe_force_wake.h"
@@ -169,8 +170,11 @@ void xe_reg_sr_apply_mmio(struct xe_reg_sr *sr, struct xe_gt *gt)
if (xa_empty(&sr->xa))
return;
if (IS_SRIOV_VF(gt_to_xe(gt)))
return;
/*
* We don't process non-LRC reg_sr lists in VF, so they should have
* been empty in the check above.
*/
xe_gt_assert(gt, !IS_SRIOV_VF(gt_to_xe(gt)));
xe_gt_dbg(gt, "Applying %s save-restore MMIOs\n", sr->name);

View File

@@ -189,7 +189,7 @@ void xe_reg_whitelist_process_engine(struct xe_hw_engine *hwe)
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
xe_rtp_process_to_sr(&ctx, register_whitelist, ARRAY_SIZE(register_whitelist),
&hwe->reg_whitelist);
&hwe->reg_whitelist, false);
whitelist_apply_to_hwe(hwe);
}

View File

@@ -270,6 +270,8 @@ static void rtp_mark_active(struct xe_device *xe,
* @sr: Save-restore struct where matching rules execute the action. This can be
* viewed as the "coalesced view" of multiple the tables. The bits for each
* register set are expected not to collide with previously added entries
* @process_in_vf: Whether this RTP table should get processed for SR-IOV VF
* devices. Should generally only be 'true' for LRC tables.
*
* Walk the table pointed by @entries (with an empty sentinel) and add all
* entries with matching rules to @sr. If @hwe is not NULL, its mmio_base is
@@ -278,7 +280,8 @@ static void rtp_mark_active(struct xe_device *xe,
void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
const struct xe_rtp_entry_sr *entries,
size_t n_entries,
struct xe_reg_sr *sr)
struct xe_reg_sr *sr,
bool process_in_vf)
{
const struct xe_rtp_entry_sr *entry;
struct xe_hw_engine *hwe = NULL;
@@ -287,6 +290,9 @@ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
rtp_get_context(ctx, &hwe, &gt, &xe);
if (!process_in_vf && IS_SRIOV_VF(xe))
return;
xe_assert(xe, entries);
for (entry = entries; entry - entries < n_entries; entry++) {

View File

@@ -431,7 +431,8 @@ void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx,
void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
const struct xe_rtp_entry_sr *entries,
size_t n_entries, struct xe_reg_sr *sr);
size_t n_entries, struct xe_reg_sr *sr,
bool process_in_vf);
void xe_rtp_process(struct xe_rtp_process_ctx *ctx,
const struct xe_rtp_entry *entries);

View File

@@ -15,6 +15,7 @@
#include "xe_gt_types.h"
#include "xe_platform_types.h"
#include "xe_rtp.h"
#include "xe_sriov.h"
#undef XE_REG_MCR
#define XE_REG_MCR(...) XE_REG(__VA_ARGS__, .mcr = 1)
@@ -200,7 +201,8 @@ void xe_tuning_process_gt(struct xe_gt *gt)
xe_rtp_process_ctx_enable_active_tracking(&ctx,
gt->tuning_active.gt,
ARRAY_SIZE(gt_tunings));
xe_rtp_process_to_sr(&ctx, gt_tunings, ARRAY_SIZE(gt_tunings), &gt->reg_sr);
xe_rtp_process_to_sr(&ctx, gt_tunings, ARRAY_SIZE(gt_tunings),
&gt->reg_sr, false);
}
EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt);
@@ -212,7 +214,7 @@ void xe_tuning_process_engine(struct xe_hw_engine *hwe)
hwe->gt->tuning_active.engine,
ARRAY_SIZE(engine_tunings));
xe_rtp_process_to_sr(&ctx, engine_tunings, ARRAY_SIZE(engine_tunings),
&hwe->reg_sr);
&hwe->reg_sr, false);
}
EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_engine);
@@ -231,7 +233,8 @@ void xe_tuning_process_lrc(struct xe_hw_engine *hwe)
xe_rtp_process_ctx_enable_active_tracking(&ctx,
hwe->gt->tuning_active.lrc,
ARRAY_SIZE(lrc_tunings));
xe_rtp_process_to_sr(&ctx, lrc_tunings, ARRAY_SIZE(lrc_tunings), &hwe->reg_lrc);
xe_rtp_process_to_sr(&ctx, lrc_tunings, ARRAY_SIZE(lrc_tunings),
&hwe->reg_lrc, true);
}
/**

View File

@@ -1005,7 +1005,8 @@ void xe_wa_process_gt(struct xe_gt *gt)
xe_rtp_process_ctx_enable_active_tracking(&ctx, gt->wa_active.gt,
ARRAY_SIZE(gt_was));
xe_rtp_process_to_sr(&ctx, gt_was, ARRAY_SIZE(gt_was), &gt->reg_sr);
xe_rtp_process_to_sr(&ctx, gt_was, ARRAY_SIZE(gt_was),
&gt->reg_sr, false);
}
EXPORT_SYMBOL_IF_KUNIT(xe_wa_process_gt);
@@ -1023,7 +1024,8 @@ void xe_wa_process_engine(struct xe_hw_engine *hwe)
xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->wa_active.engine,
ARRAY_SIZE(engine_was));
xe_rtp_process_to_sr(&ctx, engine_was, ARRAY_SIZE(engine_was), &hwe->reg_sr);
xe_rtp_process_to_sr(&ctx, engine_was, ARRAY_SIZE(engine_was),
&hwe->reg_sr, false);
}
/**
@@ -1040,7 +1042,8 @@ void xe_wa_process_lrc(struct xe_hw_engine *hwe)
xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->wa_active.lrc,
ARRAY_SIZE(lrc_was));
xe_rtp_process_to_sr(&ctx, lrc_was, ARRAY_SIZE(lrc_was), &hwe->reg_lrc);
xe_rtp_process_to_sr(&ctx, lrc_was, ARRAY_SIZE(lrc_was),
&hwe->reg_lrc, true);
}
/**