Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
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
>

  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