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 = >->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
next prev parent 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.