From: "Dixit, Ashutosh" <ashutosh.dixit@intel.com>
To: Matt Roper <matthew.d.roper@intel.com>
Cc: <intel-xe@lists.freedesktop.org>,
Michal Wajdeczko <michal.wajdeczko@intel.com>
Subject: Re: [PATCH v4 3/4] drm/xe: Add facility to lookup the value of a register in a default LRC
Date: Wed, 18 Feb 2026 18:23:06 -0800 [thread overview]
Message-ID: <87jyw9wjxx.wl-ashutosh.dixit@intel.com> (raw)
In-Reply-To: <20260218-sr_verify-v4-3-35d6deeb3421@intel.com>
On Wed, 18 Feb 2026 14:09:14 -0800, Matt Roper wrote:
>
> An LRC is stored in memory as a special batchbuffer that hardware will
> execute to re-load state when switching to the context; it's a
> collection of register values (encoded as MI_LOAD_REGISTER_IMM commands)
> and other state instructions (e.g., 3DSTATE_*). The value that will be
> loaded for a given register can be determined by parsing the batchbuffer
> to find MI_LRI commands and extracting the value from the offset/value
> pairs it contains. Add functions to do this, which will be used in a
> future patch to help verify that our expected reg_sr programming is in
> place.
>
> The implementation here returns the value as soon as it finds a match in
> the LRC. Technically a register could appear multiple times (either due
> to memory corruption or a hardware defect) and the last value
> encountered would be the one in effect when the context resumes
> execution. We can adjust the logic to keep looking and return the last
> match instead of first in the future if we encounter real-world cases
> where this would assist with debugging.
>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
OK, in xe_gt_record_default_lrcs, the default lrc is first constructed,
applied and then saved after a contex switch. So it will capture register
values which might be different from those in our rtp/sr lists. So
everything here looks good:
Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
> ---
> drivers/gpu/drm/xe/xe_lrc.c | 96 +++++++++++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_lrc.h | 4 ++
> 2 files changed, 100 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
> index 38f648b98868d8a6caa038e2d940f72783f2074b..57ef4f527ed0d142ad382ba17c020d8f8c241bfd 100644
> --- a/drivers/gpu/drm/xe/xe_lrc.c
> +++ b/drivers/gpu/drm/xe/xe_lrc.c
> @@ -2155,6 +2155,102 @@ void xe_lrc_dump_default(struct drm_printer *p,
> }
> }
>
> +/*
> + * Lookup the value of a register within the offset/value pairs of an
> + * MI_LOAD_REGISTER_IMM instruction.
> + *
> + * Return -ENOENT if the register is not present in the MI_LRI instruction.
> + */
> +static int lookup_reg_in_mi_lri(u32 offset, u32 *value,
> + const u32 *dword_pair, int num_regs)
> +{
> + for (int i = 0; i < num_regs; i++) {
> + if (dword_pair[2 * i] == offset) {
> + *value = dword_pair[2 * i + 1];
> + return 0;
> + }
> + }
> +
> + return -ENOENT;
> +}
> +
> +/*
> + * Lookup the value of a register in a specific engine type's default LRC.
> + *
> + * Return -EINVAL if the default LRC doesn't exist, or ENOENT if the register
> + * cannot be found in the default LRC.
> + */
> +int xe_lrc_lookup_default_reg_value(struct xe_gt *gt,
> + enum xe_engine_class hwe_class,
> + u32 offset,
> + u32 *value)
> +{
> + u32 *dw;
> + int remaining_dw, ret;
> +
> + if (!gt->default_lrc[hwe_class])
> + return -EINVAL;
> +
> + /*
> + * Skip the beginning of the LRC since it contains the per-process
> + * hardware status page.
> + */
> + dw = gt->default_lrc[hwe_class] + LRC_PPHWSP_SIZE;
> + remaining_dw = (xe_gt_lrc_size(gt, hwe_class) - LRC_PPHWSP_SIZE) / 4;
> +
> + while (remaining_dw > 0) {
> + u32 num_dw = instr_dw(*dw);
> +
> + if (num_dw > remaining_dw)
> + num_dw = remaining_dw;
> +
> + switch (*dw & XE_INSTR_CMD_TYPE) {
> + case XE_INSTR_MI:
> + switch (*dw & MI_OPCODE) {
> + case MI_BATCH_BUFFER_END:
> + /* End of LRC; register not found */
> + return -ENOENT;
> +
> + case MI_NOOP:
> + case MI_TOPOLOGY_FILTER:
> + /*
> + * MI_NOOP and MI_TOPOLOGY_FILTER don't have
> + * a length field and are always 1-dword
> + * instructions.
> + */
> + remaining_dw--;
> + dw++;
> + break;
> +
> + case MI_LOAD_REGISTER_IMM:
> + ret = lookup_reg_in_mi_lri(offset, value,
> + dw + 1, (num_dw - 1) / 2);
> + if (ret == 0)
> + return 0;
> +
> + fallthrough;
> +
> + default:
> + /*
> + * Jump to next instruction based on length
> + * field.
> + */
> + remaining_dw -= num_dw;
> + dw += num_dw;
> + break;
> + }
> + break;
> +
> + default:
> + /* Jump to next instruction based on length field. */
> + remaining_dw -= num_dw;
> + dw += num_dw;
> + }
> + }
> +
> + return -ENOENT;
> +}
> +
> struct instr_state {
> u32 instr;
> u16 num_dw;
> diff --git a/drivers/gpu/drm/xe/xe_lrc.h b/drivers/gpu/drm/xe/xe_lrc.h
> index c307a3fd9ea287d54f2d211cdb688e1143a43d03..3e500004f1ae449befaf4cbcefef36dc4c92bdec 100644
> --- a/drivers/gpu/drm/xe/xe_lrc.h
> +++ b/drivers/gpu/drm/xe/xe_lrc.h
> @@ -133,6 +133,10 @@ size_t xe_lrc_skip_size(struct xe_device *xe);
> void xe_lrc_dump_default(struct drm_printer *p,
> struct xe_gt *gt,
> enum xe_engine_class);
> +int xe_lrc_lookup_default_reg_value(struct xe_gt *gt,
> + enum xe_engine_class hwe_class,
> + u32 offset,
> + u32 *value);
>
> u32 *xe_lrc_emit_hwe_state_instructions(struct xe_exec_queue *q, u32 *cs);
>
>
> --
> 2.53.0
>
next prev parent reply other threads:[~2026-02-19 2:23 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-18 22:09 [PATCH v4 0/4] Add debugfs facility to catch RTP mistakes Matt Roper
2026-02-18 22:09 ` [PATCH v4 1/4] drm/xe/reg_sr: Don't process gt/hwe lists in VF Matt Roper
2026-02-18 22:55 ` Dixit, Ashutosh
2026-02-18 22:09 ` [PATCH v4 2/4] drm/xe/reg_sr: Add debugfs to verify status of reg_sr programming Matt Roper
2026-02-18 22:09 ` [PATCH v4 3/4] drm/xe: Add facility to lookup the value of a register in a default LRC Matt Roper
2026-02-19 2:23 ` Dixit, Ashutosh [this message]
2026-02-18 22:09 ` [PATCH v4 4/4] drm/xe/reg_sr: Allow register_save_restore_check debugfs to verify LRC values Matt Roper
2026-02-19 2:23 ` Dixit, Ashutosh
2026-02-18 22:52 ` ✓ CI.KUnit: success for Add debugfs facility to catch RTP mistakes (rev3) Patchwork
2026-02-18 23:28 ` ✓ Xe.CI.BAT: " Patchwork
2026-02-19 0:30 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-02-19 15:36 ` Matt Roper
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=87jyw9wjxx.wl-ashutosh.dixit@intel.com \
--to=ashutosh.dixit@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=matthew.d.roper@intel.com \
--cc=michal.wajdeczko@intel.com \
/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