]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe: Add send_tlb_inval_ppgtt helper
authorMatthew Brost <matthew.brost@intel.com>
Fri, 16 Jan 2026 22:17:28 +0000 (14:17 -0800)
committerMatthew Brost <matthew.brost@intel.com>
Sat, 17 Jan 2026 02:24:53 +0000 (18:24 -0800)
Extract the common code that issues a TLB invalidation H2G for PPGTTs
into a helper function. This helper can be reused for both ASID-based
and context-based TLB invalidations.

Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Stuart Summers <stuart.summers@intel.com>
Tested-by: Stuart Summers <stuart.summers@intel.com>
Link: https://patch.msgid.link/20260116221731.868657-9-matthew.brost@intel.com
drivers/gpu/drm/xe/xe_guc_tlb_inval.c

index a6a1c371a28edefbfd5cc05ea8292b4461d98c67..070d2e2cb7c939b20cf5bfc101e89488e5840b2c 100644 (file)
@@ -150,20 +150,16 @@ static u64 normalize_invalidation_range(struct xe_gt *gt, u64 *start, u64 *end)
  */
 #define MAX_RANGE_TLB_INVALIDATION_LENGTH (rounddown_pow_of_two(ULONG_MAX))
 
-static int send_tlb_inval_asid_ppgtt(struct xe_tlb_inval *tlb_inval, u32 seqno,
-                                    u64 start, u64 end, u32 asid,
-                                    struct drm_suballoc *prl_sa)
+static int send_tlb_inval_ppgtt(struct xe_guc *guc, u32 seqno, u64 start,
+                               u64 end, u32 id, u32 type,
+                               struct drm_suballoc *prl_sa)
 {
 #define MAX_TLB_INVALIDATION_LEN       7
-       struct xe_guc *guc = tlb_inval->private;
        struct xe_gt *gt = guc_to_gt(guc);
        u32 action[MAX_TLB_INVALIDATION_LEN];
        u64 length = end - start;
        int len = 0, err;
 
-       if (guc_to_xe(guc)->info.force_execlist)
-               return -ECANCELED;
-
        action[len++] = XE_GUC_ACTION_TLB_INVALIDATION;
        action[len++] = !prl_sa ? seqno : TLB_INVALIDATION_SEQNO_INVALID;
        if (!gt_to_xe(gt)->info.has_range_tlb_inval ||
@@ -174,14 +170,15 @@ static int send_tlb_inval_asid_ppgtt(struct xe_tlb_inval *tlb_inval, u32 seqno,
                                                                 &end);
 
                /* Flush on NULL case, Media is not required to modify flush due to no PPC so NOP */
-               action[len++] = MAKE_INVAL_OP_FLUSH(XE_GUC_TLB_INVAL_PAGE_SELECTIVE, !prl_sa);
-               action[len++] = asid;
+               action[len++] = MAKE_INVAL_OP_FLUSH(type, !prl_sa);
+               action[len++] = id;
                action[len++] = lower_32_bits(start);
                action[len++] = upper_32_bits(start);
                action[len++] = ilog2(normalize_len) - ilog2(SZ_4K);
        }
 
        xe_gt_assert(gt, len <= MAX_TLB_INVALIDATION_LEN);
+#undef MAX_TLB_INVALIDATION_LEN
 
        err = send_tlb_inval(guc, action, len);
        if (!err && prl_sa)
@@ -189,6 +186,21 @@ static int send_tlb_inval_asid_ppgtt(struct xe_tlb_inval *tlb_inval, u32 seqno,
        return err;
 }
 
+static int send_tlb_inval_asid_ppgtt(struct xe_tlb_inval *tlb_inval, u32 seqno,
+                                    u64 start, u64 end, u32 asid,
+                                    struct drm_suballoc *prl_sa)
+{
+       struct xe_guc *guc = tlb_inval->private;
+
+       lockdep_assert_held(&tlb_inval->seqno_lock);
+
+       if (guc_to_xe(guc)->info.force_execlist)
+               return -ECANCELED;
+
+       return send_tlb_inval_ppgtt(guc, seqno, start, end, asid,
+                                   XE_GUC_TLB_INVAL_PAGE_SELECTIVE, prl_sa);
+}
+
 static bool tlb_inval_initialized(struct xe_tlb_inval *tlb_inval)
 {
        struct xe_guc *guc = tlb_inval->private;