From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 47741E9A02C for ; Thu, 19 Feb 2026 02:23:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 049BF10E243; Thu, 19 Feb 2026 02:23:09 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="RvDm16aK"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.10]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9F13310E243 for ; Thu, 19 Feb 2026 02:23:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1771467788; x=1803003788; h=date:message-id:from:to:cc:subject:in-reply-to: references:mime-version; bh=jMU5vmvOHe4yIOmtkGXDuQ2+8BDQsWf14qiDRLoJ1tg=; b=RvDm16aK+SVcuu14ZclN2uJ+nO8HX9hULiIbOVMAiz91ZyqVkDqCYTtV +JAxRyXf4YO1hGdJkVnADsehPj3WsBxBFLyn7+BYqXfxUhLtIH5+UIuDt X/zK4AjHx0ay/RxRRUaKqJPj/BYynDCcjwoJYYtwsIxqDY36bNi3g5+vf 3Fkg0mGdYqPvwZiHLaXt6FIvVbibniA8m+F4b5DokachmyUPXcCzyHlW3 sJGUrn03i9pmnA/nwPEFadqhTogYP2BxPQi1LYuqUkMVQmKDqk1ZJT2fn Rg+t0L6b9dWQ4E675pjVVn9tulLM8fslcDNO2Kf6oM2h887x0MWstSbeu Q==; X-CSE-ConnectionGUID: uWbGp5bMQsKsV20t+pB37w== X-CSE-MsgGUID: N5pjht0zQ9Oal9lmwiJ/uw== X-IronPort-AV: E=McAfee;i="6800,10657,11705"; a="83915429" X-IronPort-AV: E=Sophos;i="6.21,299,1763452800"; d="scan'208";a="83915429" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 18:23:07 -0800 X-CSE-ConnectionGUID: 3JOZa+QZRnGij97FozRyYQ== X-CSE-MsgGUID: Te6JzuqhS1WUoztSuM2yTA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,299,1763452800"; d="scan'208";a="214390351" Received: from unknown (HELO adixit-MOBL3.intel.com) ([10.125.136.209]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 18:23:08 -0800 Date: Wed, 18 Feb 2026 18:23:06 -0800 Message-ID: <87jyw9wjxx.wl-ashutosh.dixit@intel.com> From: "Dixit, Ashutosh" To: Matt Roper Cc: , Michal Wajdeczko Subject: Re: [PATCH v4 3/4] drm/xe: Add facility to lookup the value of a register in a default LRC In-Reply-To: <20260218-sr_verify-v4-3-35d6deeb3421@intel.com> References: <20260218-sr_verify-v4-0-35d6deeb3421@intel.com> <20260218-sr_verify-v4-3-35d6deeb3421@intel.com> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (=?ISO-8859-4?Q?Goj=F2?=) APEL-LB/10.8 EasyPG/1.0.0 Emacs/30.2 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: text/plain; charset=US-ASCII X-BeenThere: intel-xe@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel Xe graphics driver List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-xe-bounces@lists.freedesktop.org Sender: "Intel-xe" 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 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 > --- > 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 >