From: stuartsummers <stuart.summers@intel.com>
Cc: matthew.brost@intel.com, farah.kassabri@intel.com,
intel-xe@lists.freedesktop.org,
Stuart Summers <stuart.summers@intel.com>
Subject: [PATCH 7/8] drm/xe: Add helpers to send TLB invalidations
Date: Wed, 6 Aug 2025 22:24:03 +0000 [thread overview]
Message-ID: <20250806222404.30333-8-stuart.summers@intel.com> (raw)
In-Reply-To: <20250806222404.30333-1-stuart.summers@intel.com>
From: Matthew Brost <matthew.brost@intel.com>
Break out the GuC specific code into helpers as part of the process to
decouple frontback TLB invalidation code from the backend.
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Stuart Summers <stuart.summers@intel.com>
Reviewed-by: Stuart Summers <stuart.summers@intel.com>
---
drivers/gpu/drm/xe/xe_tlb_inval.c | 230 +++++++++++++++---------------
1 file changed, 115 insertions(+), 115 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_tlb_inval.c b/drivers/gpu/drm/xe/xe_tlb_inval.c
index 2ffd677ee180..5db7f26bce2e 100644
--- a/drivers/gpu/drm/xe/xe_tlb_inval.c
+++ b/drivers/gpu/drm/xe/xe_tlb_inval.c
@@ -199,12 +199,11 @@ static bool tlb_inval_seqno_past(struct xe_gt *gt, int seqno)
return seqno_recv >= seqno;
}
-static int send_tlb_inval(struct xe_guc *guc, struct xe_tlb_inval_fence *fence,
- u32 *action, int len)
+static int send_tlb_inval(struct xe_guc *guc, const u32 *action, int len)
{
struct xe_gt *gt = guc_to_gt(guc);
- xe_gt_assert(gt, fence);
+ xe_gt_assert(gt, action[1]); /* Seqno */
/*
* XXX: The seqno algorithm relies on TLB invalidation being processed
@@ -213,7 +212,6 @@ static int send_tlb_inval(struct xe_guc *guc, struct xe_tlb_inval_fence *fence,
*/
xe_gt_stats_incr(gt, XE_GT_STATS_ID_TLB_INVAL, 1);
- action[1] = fence->seqno;
return xe_guc_ct_send(&guc->ct, action, len,
G2H_LEN_DW_TLB_INVALIDATE, 1);
@@ -248,89 +246,15 @@ static void xe_tlb_inval_fence_prep(struct xe_tlb_inval_fence *fence)
XE_GUC_TLB_INVAL_MODE_HEAVY << XE_GUC_TLB_INVAL_MODE_SHIFT | \
XE_GUC_TLB_INVAL_FLUSH_CACHE)
-/**
- * xe_tlb_inval_guc - Issue a TLB invalidation on this GT for the GuC
- * @gt: GT structure
- * @fence: invalidation fence which will be signal on TLB invalidation
- * completion
- *
- * Issue a TLB invalidation for the GuC. Completion of TLB is asynchronous and
- * caller can use the invalidation fence to wait for completion.
- *
- * Return: 0 on success, negative error code on error
- */
-static int xe_tlb_inval_guc(struct xe_gt *gt,
- struct xe_tlb_inval_fence *fence)
+static int send_tlb_inval_ggtt(struct xe_gt *gt, int seqno)
{
u32 action[] = {
XE_GUC_ACTION_TLB_INVALIDATION,
- 0, /* seqno, replaced in send_tlb_inval */
+ seqno,
MAKE_INVAL_OP(XE_GUC_TLB_INVAL_GUC),
};
- int ret;
-
- xe_tlb_inval_fence_prep(fence);
-
- ret = send_tlb_inval(>->uc.guc, fence, action, ARRAY_SIZE(action));
- if (ret < 0)
- inval_fence_signal_unlocked(gt_to_xe(gt), fence);
-
- /*
- * -ECANCELED indicates the CT is stopped for a GT reset. TLB caches
- * should be nuked on a GT reset so this error can be ignored.
- */
- if (ret == -ECANCELED)
- return 0;
-
- return ret;
-}
-
-/**
- * xe_tlb_inval_ggtt - Issue a TLB invalidation on this GT for the GGTT
- * @tlb_inval: TLB invalidation client
- *
- * Issue a TLB invalidation for the GGTT. Completion of TLB invalidation is
- * synchronous.
- *
- * Return: 0 on success, negative error code on error
- */
-int xe_tlb_inval_ggtt(struct xe_tlb_inval *tlb_inval)
-{
- struct xe_gt *gt = tlb_inval->private;
- struct xe_device *xe = gt_to_xe(gt);
- unsigned int fw_ref;
-
- if (xe_guc_ct_enabled(>->uc.guc.ct) &&
- gt->uc.guc.submission_state.enabled) {
- struct xe_tlb_inval_fence fence;
- int ret;
-
- xe_tlb_inval_fence_init(tlb_inval, &fence, true);
- ret = xe_tlb_inval_guc(gt, &fence);
- if (ret)
- return ret;
- xe_tlb_inval_fence_wait(&fence);
- } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) {
- struct xe_mmio *mmio = >->mmio;
-
- if (IS_SRIOV_VF(xe))
- return 0;
-
- fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
- if (xe->info.platform == XE_PVC || GRAPHICS_VER(xe) >= 20) {
- 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);
- } else {
- xe_mmio_write32(mmio, GUC_TLB_INV_CR,
- GUC_TLB_INV_CR_INVALIDATE);
- }
- xe_force_wake_put(gt_to_fw(gt), fw_ref);
- }
-
- return 0;
+ return send_tlb_inval(>->uc.guc, action, ARRAY_SIZE(action));
}
static int send_tlb_inval_all(struct xe_tlb_inval *tlb_inval,
@@ -345,7 +269,7 @@ static int send_tlb_inval_all(struct xe_tlb_inval *tlb_inval,
xe_gt_assert(gt, fence);
- return send_tlb_inval(>->uc.guc, fence, action, ARRAY_SIZE(action));
+ return send_tlb_inval(>->uc.guc, action, ARRAY_SIZE(action));
}
/**
@@ -377,43 +301,17 @@ int xe_tlb_inval_all(struct xe_tlb_inval *tlb_inval,
*/
#define MAX_RANGE_TLB_INVALIDATION_LENGTH (rounddown_pow_of_two(ULONG_MAX))
-/**
- * xe_tlb_inval_range - Issue a TLB invalidation on this GT for an address range
- * @tlb_inval: TLB invalidation client
- * @fence: invalidation fence which will be signal on TLB invalidation
- * completion
- * @start: start address
- * @end: end address
- * @asid: address space id
- *
- * Issue a range based TLB invalidation if supported, if not fallback to a full
- * TLB invalidation. Completion of TLB is asynchronous and caller can use
- * the invalidation fence to wait for completion.
- *
- * Return: Negative error code on error, 0 on success
- */
-int xe_tlb_inval_range(struct xe_tlb_inval *tlb_inval,
- struct xe_tlb_inval_fence *fence, u64 start, u64 end,
- u32 asid)
+static int send_tlb_inval_ppgtt(struct xe_gt *gt, u64 start, u64 end,
+ u32 asid, int seqno)
{
- struct xe_gt *gt = tlb_inval->private;
- struct xe_device *xe = gt_to_xe(gt);
#define MAX_TLB_INVALIDATION_LEN 7
u32 action[MAX_TLB_INVALIDATION_LEN];
u64 length = end - start;
- int len = 0, ret;
-
- xe_gt_assert(gt, fence);
-
- /* Execlists not supported */
- if (gt_to_xe(gt)->info.force_execlist) {
- __inval_fence_signal(xe, fence);
- return 0;
- }
+ int len = 0;
action[len++] = XE_GUC_ACTION_TLB_INVALIDATION;
- action[len++] = 0; /* seqno, replaced in send_tlb_inval */
- if (!xe->info.has_range_tlb_inval ||
+ action[len++] = seqno;
+ if (!gt_to_xe(gt)->info.has_range_tlb_inval ||
length > MAX_RANGE_TLB_INVALIDATION_LENGTH) {
action[len++] = MAKE_INVAL_OP(XE_GUC_TLB_INVAL_FULL);
} else {
@@ -462,10 +360,112 @@ int xe_tlb_inval_range(struct xe_tlb_inval *tlb_inval,
xe_gt_assert(gt, len <= MAX_TLB_INVALIDATION_LEN);
+ return send_tlb_inval(>->uc.guc, action, len);
+}
+
+static int __xe_tlb_inval_ggtt(struct xe_gt *gt,
+ struct xe_tlb_inval_fence *fence)
+{
+ int ret;
+
+ xe_tlb_inval_fence_prep(fence);
+
+ ret = send_tlb_inval_ggtt(gt, fence->seqno);
+ if (ret < 0)
+ inval_fence_signal_unlocked(gt_to_xe(gt), fence);
+
+ /*
+ * -ECANCELED indicates the CT is stopped for a GT reset. TLB caches
+ * should be nuked on a GT reset so this error can be ignored.
+ */
+ if (ret == -ECANCELED)
+ return 0;
+
+ return ret;
+}
+
+/**
+ * xe_tlb_inval_ggtt - Issue a TLB invalidation on this GT for the GGTT
+ * @tlb_inval: TLB invalidation client
+ *
+ * Issue a TLB invalidation for the GGTT. Completion of TLB invalidation is
+ * synchronous.
+ *
+ * Return: 0 on success, negative error code on error
+ */
+int xe_tlb_inval_ggtt(struct xe_tlb_inval *tlb_inval)
+{
+ struct xe_gt *gt = tlb_inval->private;
+ struct xe_device *xe = gt_to_xe(gt);
+ unsigned int fw_ref;
+
+ if (xe_guc_ct_enabled(>->uc.guc.ct) &&
+ gt->uc.guc.submission_state.enabled) {
+ struct xe_tlb_inval_fence fence;
+ int ret;
+
+ xe_tlb_inval_fence_init(tlb_inval, &fence, true);
+ ret = __xe_tlb_inval_ggtt(gt, &fence);
+ if (ret)
+ return ret;
+
+ xe_tlb_inval_fence_wait(&fence);
+ } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) {
+ struct xe_mmio *mmio = >->mmio;
+
+ if (IS_SRIOV_VF(xe))
+ return 0;
+
+ fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
+ if (xe->info.platform == XE_PVC || GRAPHICS_VER(xe) >= 20) {
+ 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);
+ } else {
+ xe_mmio_write32(mmio, GUC_TLB_INV_CR,
+ GUC_TLB_INV_CR_INVALIDATE);
+ }
+ xe_force_wake_put(gt_to_fw(gt), fw_ref);
+ }
+
+ return 0;
+}
+
+/**
+ * xe_tlb_inval_range - Issue a TLB invalidation on this GT for an address range
+ * @tlb_inval: TLB invalidation client
+ * @fence: invalidation fence which will be signal on TLB invalidation
+ * completion
+ * @start: start address
+ * @end: end address
+ * @asid: address space id
+ *
+ * Issue a range based TLB invalidation if supported, if not fallback to a full
+ * TLB invalidation. Completion of TLB is asynchronous and caller can use
+ * the invalidation fence to wait for completion.
+ *
+ * Return: Negative error code on error, 0 on success
+ */
+int xe_tlb_inval_range(struct xe_tlb_inval *tlb_inval,
+ struct xe_tlb_inval_fence *fence, u64 start, u64 end,
+ u32 asid)
+{
+ struct xe_gt *gt = tlb_inval->private;
+ struct xe_device *xe = gt_to_xe(gt);
+ int ret;
+
+ xe_gt_assert(gt, fence);
+
+ /* Execlists not supported */
+ if (xe->info.force_execlist) {
+ __inval_fence_signal(xe, fence);
+ return 0;
+ }
+
xe_tlb_inval_fence_prep(fence);
- ret = send_tlb_inval(>->uc.guc, fence, action,
- ARRAY_SIZE(action));
+ ret = send_tlb_inval_ppgtt(gt, start, end, asid, fence->seqno);
if (ret < 0)
inval_fence_signal_unlocked(xe, fence);
--
2.34.1
next prev parent reply other threads:[~2025-08-06 22:24 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-06 22:23 [PATCH 0/8] Add TLB invalidation abstraction stuartsummers
2025-08-06 22:23 ` [PATCH 1/8] drm/xe: Move explicit CT lock in TLB invalidation sequence stuartsummers
2025-08-07 17:10 ` Summers, Stuart
2025-08-07 17:40 ` Matthew Brost
2025-08-07 18:53 ` Summers, Stuart
2025-08-06 22:23 ` [PATCH 2/8] drm/xe: s/tlb_invalidation/tlb_inval stuartsummers
2025-08-06 22:23 ` [PATCH 3/8] drm/xe: Add xe_tlb_inval structure stuartsummers
2025-08-06 22:24 ` [PATCH 4/8] drm/xe: Add xe_gt_tlb_invalidation_done_handler stuartsummers
2025-08-06 22:24 ` [PATCH 5/8] drm/xe: Decouple TLB invalidations from GT stuartsummers
2025-08-06 22:24 ` [PATCH 6/8] drm/xe: Prep TLB invalidation fence before sending stuartsummers
2025-08-06 22:24 ` stuartsummers [this message]
2025-08-06 22:24 ` [PATCH 8/8] drm/xe: Split TLB invalidation code in frontend and backend stuartsummers
2025-08-06 22:32 ` ✗ CI.checkpatch: warning for Add TLB invalidation abstraction (rev3) Patchwork
2025-08-06 22:33 ` ✓ CI.KUnit: success " Patchwork
2025-08-06 23:35 ` ✓ Xe.CI.BAT: " Patchwork
2025-08-07 0:57 ` ✗ Xe.CI.Full: failure " Patchwork
2025-08-07 14:58 ` Summers, Stuart
-- strict thread matches above, loose matches on Subject: below --
2025-08-07 20:39 [PATCH 0/8] Add TLB invalidation abstraction stuartsummers
2025-08-07 20:39 ` [PATCH 7/8] drm/xe: Add helpers to send TLB invalidations stuartsummers
2025-08-07 19:36 [PATCH 0/8] Add TLB invalidation abstraction stuartsummers
2025-08-07 19:36 ` [PATCH 7/8] drm/xe: Add helpers to send TLB invalidations stuartsummers
2025-07-30 20:45 [PATCH 0/8] Add TLB invalidation abstraction stuartsummers
2025-07-30 20:45 ` [PATCH 7/8] drm/xe: Add helpers to send TLB invalidations stuartsummers
2025-08-06 21:41 ` Summers, Stuart
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=20250806222404.30333-8-stuart.summers@intel.com \
--to=stuart.summers@intel.com \
--cc=farah.kassabri@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=matthew.brost@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.