Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: fei.yang@intel.com
To: intel-xe@lists.freedesktop.org
Cc: Fei Yang <fei.yang@intel.com>,
	Matthew Brost <matthew.brost@intel.com>,
	Stuart Summers <stuart.summers@intel.com>,
	Roper Matthew D <matthew.d.roper@intel.com>
Subject: [PATCH 1/1 v4] drm/xe: Wait for HW clearance before issuing the next TLB inval.
Date: Wed, 24 Jun 2026 15:51:04 -0700	[thread overview]
Message-ID: <20260624225105.2355641-2-fei.yang@intel.com> (raw)
In-Reply-To: <20260624225105.2355641-1-fei.yang@intel.com>

From: Fei Yang <fei.yang@intel.com>

Hardware requires the software to poll the valid bit and make sure
it's cleared before issuing a new TLB invalidation request.
We also need to avoid racing against GuC on TLB invalidations. In
order to achieve that, check for pending TLB invalidation in tlb_inval
list.

Signed-off-by: Fei Yang <fei.yang@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Stuart Summers <stuart.summers@intel.com>
Cc: Roper Matthew D <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/xe/xe_guc_tlb_inval.c | 70 +++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/drivers/gpu/drm/xe/xe_guc_tlb_inval.c b/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
index cf6d106e6036..815fbd059112 100644
--- a/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
+++ b/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
@@ -8,6 +8,7 @@
 #include "xe_device.h"
 #include "xe_exec_queue.h"
 #include "xe_exec_queue_types.h"
+#include "xe_gt_printk.h"
 #include "xe_gt_stats.h"
 #include "xe_gt_types.h"
 #include "xe_guc.h"
@@ -60,6 +61,12 @@ static int send_tlb_inval_all(struct xe_tlb_inval *tlb_inval, u32 seqno)
 
 static int send_tlb_inval_ggtt(struct xe_tlb_inval *tlb_inval, u32 seqno)
 {
+	/*
+	 * Timeout for MMIO-based TLB invalidation polling. Make it 250ms
+	 * based on hw_tlb_timeout = HZ/4 defined in tlb_inval_timeout_delay().
+	 */
+	const long hw_tlb_timeout = HZ / 4;
+
 	struct xe_guc *guc = tlb_inval->private;
 	struct xe_gt *gt = guc_to_gt(guc);
 	struct xe_device *xe = guc_to_xe(guc);
@@ -79,19 +86,82 @@ static int send_tlb_inval_ggtt(struct xe_tlb_inval *tlb_inval, u32 seqno)
 		return send_tlb_inval(guc, action, ARRAY_SIZE(action));
 	} else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) {
 		struct xe_mmio *mmio = &gt->mmio;
+		int err;
 
 		if (IS_SRIOV_VF(xe))
 			return -ECANCELED;
 
+		/*
+		 * seqno_lock serializes MMIO-based TLB invalidations to prevent
+		 * races between concurrent requests issued through GuC CT and
+		 * direct MMIO writes.
+		 */
+		lockdep_assert_held(&tlb_inval->seqno_lock);
+
+		/*
+		 * If there are pending GuC TLB invalidation requests MMIO-based
+		 * requests should be avoided.
+		 */
+		if (!xe_tlb_inval_idle(tlb_inval)) {
+			xe_gt_dbg(gt, "MMIO TLB INV skipped due to pending GuC INv\n");
+			return -ECANCELED;
+		}
+
 		CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FW_GT);
 		if (xe->info.platform == XE_PVC || GRAPHICS_VER(xe) >= 20) {
+			/*
+			 * HW requires the valid bit to be clear before writing a
+			 * new request.
+			 */
+			err = xe_mmio_wait32(mmio, PVC_GUC_TLB_INV_DESC0,
+					     PVC_GUC_TLB_INV_DESC0_VALID, 0,
+					     hw_tlb_timeout, NULL, false);
+			if (err) {
+				xe_gt_err(gt, "MMIO TLB INV pre-write poll timeout\n");
+				return -ECANCELED;
+			}
+
 			xe_mmio_write32(mmio, PVC_GUC_TLB_INV_DESC1,
 					PVC_GUC_TLB_INV_DESC1_INVALIDATE);
 			xe_mmio_write32(mmio, PVC_GUC_TLB_INV_DESC0,
 					PVC_GUC_TLB_INV_DESC0_VALID);
+
+			/*
+			 * Poll for clearance of the valid bit after writing to
+			 * ensure the request has been consumed and to avoid races
+			 * between TLB invalidation through GuC and MMIO.
+			 */
+			err = xe_mmio_wait32(mmio, PVC_GUC_TLB_INV_DESC0,
+					     PVC_GUC_TLB_INV_DESC0_VALID, 0,
+					     hw_tlb_timeout, NULL, false);
+			if (err)
+				xe_gt_err(gt, "MMIO TLB INV post-write poll timeout\n");
 		} else {
+			/*
+			 * HW requires the valid bit to be clear before writing a
+			 * new request.
+			 */
+			err = xe_mmio_wait32(mmio, GUC_TLB_INV_CR,
+					     GUC_TLB_INV_CR_INVALIDATE, 0,
+					     hw_tlb_timeout, NULL, false);
+			if (err) {
+				xe_gt_err(gt, "MMIO TLB INV pre-write poll timeout\n");
+				return -ECANCELED;
+			}
+
 			xe_mmio_write32(mmio, GUC_TLB_INV_CR,
 					GUC_TLB_INV_CR_INVALIDATE);
+
+			/*
+			 * Poll for clearance of the valid bit after writing to
+			 * ensure the request has been consumed and to avoid races
+			 * between TLB invalidation through GuC and MMIO.
+			 */
+			err = xe_mmio_wait32(mmio, GUC_TLB_INV_CR,
+					     GUC_TLB_INV_CR_INVALIDATE, 0,
+					     hw_tlb_timeout, NULL, false);
+			if (err)
+				xe_gt_err(gt, "MMIO TLB INV post-write poll timeout\n");
 		}
 	}
 
-- 
2.43.0


  reply	other threads:[~2026-06-24 22:47 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-24 22:51 [PATCH 0/1 v4] drm/xe: Wait for HW clearance before issuing the next TLB inval fei.yang
2026-06-24 22:51 ` fei.yang [this message]
2026-06-24 23:00 ` ✓ CI.KUnit: success for " Patchwork
2026-06-25  0:37 ` ✗ Xe.CI.BAT: failure " Patchwork

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=20260624225105.2355641-2-fei.yang@intel.com \
    --to=fei.yang@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=matthew.brost@intel.com \
    --cc=matthew.d.roper@intel.com \
    --cc=stuart.summers@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