From: Jonathan Cavitt <jonathan.cavitt@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: andi.shyti@intel.com, jonathan.cavitt@intel.com,
saurabhg.gupta@intel.com, nirmoy.das@intel.com
Subject: [Intel-gfx] [RFC PATCH 09/10] drm/i915: Add generic interface for tlb invalidation
Date: Tue, 10 Oct 2023 11:44:22 -0700 [thread overview]
Message-ID: <20231010184423.2118908-12-jonathan.cavitt@intel.com> (raw)
In-Reply-To: <20231010184423.2118908-1-jonathan.cavitt@intel.com>
From: Prathap Kumar Valsan <prathap.kumar.valsan@intel.com>
This supports selective and full tlb invalidations. When GuC is enabled
the tlb invalidations use guc ct otherwise use mmio interface.
Signed-off-by: Prathap Kumar Valsan <prathap.kumar.valsan@intel.com>
CC: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
CC: Fei Yang <fei.yang@intel.com>
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
---
drivers/gpu/drm/i915/gt/intel_gt_regs.h | 8 ++
drivers/gpu/drm/i915/gt/intel_tlb.c | 52 +++++++++++
drivers/gpu/drm/i915/gt/intel_tlb.h | 1 +
drivers/gpu/drm/i915/gt/selftest_tlb.c | 88 +++++++++++++++++++
.../drm/i915/selftests/i915_mock_selftests.h | 1 +
5 files changed, 150 insertions(+)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index eecd0a87a6478..f2ca1c26ecde5 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1124,6 +1124,14 @@
#define GEN12_GAM_DONE _MMIO(0xcf68)
+#define XEHPSDV_TLB_INV_DESC0 _MMIO(0xcf7c)
+#define XEHPSDV_TLB_INV_DESC0_ADDR_LO REG_GENMASK(31, 12)
+#define XEHPSDV_TLB_INV_DESC0_ADDR_MASK REG_GENMASK(8, 3)
+#define XEHPSDV_TLB_INV_DESC0_G REG_GENMASK(2, 1)
+#define XEHPSDV_TLB_INV_DESC0_VALID REG_BIT(0)
+#define XEHPSDV_TLB_INV_DESC1 _MMIO(0xcf80)
+#define XEHPSDV_TLB_INV_DESC0_ADDR_HI REG_GENMASK(31, 0)
+
#define GEN7_HALF_SLICE_CHICKEN1 _MMIO(0xe100) /* IVB GT1 + VLV */
#define GEN8_HALF_SLICE_CHICKEN1 MCR_REG(0xe100)
#define GEN7_MAX_PS_THREAD_DEP (8 << 12)
diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c b/drivers/gpu/drm/i915/gt/intel_tlb.c
index 4bb13d1890e37..c31fd0875ac4f 100644
--- a/drivers/gpu/drm/i915/gt/intel_tlb.c
+++ b/drivers/gpu/drm/i915/gt/intel_tlb.c
@@ -157,6 +157,58 @@ void intel_gt_invalidate_tlb_full(struct intel_gt *gt, u32 seqno)
}
}
+static u64 tlb_page_selective_size(u64 *addr, u64 length)
+{
+ const u64 end = *addr + length;
+ u64 start;
+
+ /*
+ * Minimum invalidation size for a 2MB page that the hardware expects is
+ * 16MB
+ */
+ length = max_t(u64, roundup_pow_of_two(length), SZ_4K);
+ if (length >= SZ_2M)
+ length = max_t(u64, SZ_16M, length);
+
+ /*
+ * We need to invalidate a higher granularity if start address is not
+ * aligned to length. When start is not aligned with length we need to
+ * find the length large enough to create an address mask covering the
+ * required range.
+ */
+ start = round_down(*addr, length);
+ while (start + length < end) {
+ length <<= 1;
+ start = round_down(*addr, length);
+ }
+
+ *addr = start;
+ return length;
+}
+
+bool intel_gt_invalidate_tlb_range(struct intel_gt *gt,
+ u64 start, u64 length)
+{
+ struct intel_guc *guc = >->uc.guc;
+ intel_wakeref_t wakeref;
+ u64 size, vm_total;
+ bool ret = true;
+
+ if (intel_gt_is_wedged(gt))
+ return true;
+
+ vm_total = BIT_ULL(RUNTIME_INFO(gt->i915)->ppgtt_size);
+ /* Align start and length */
+ size = min_t(u64, vm_total, tlb_page_selective_size(&start, length));
+
+ with_intel_gt_pm_if_awake(gt, wakeref)
+ ret = intel_guc_invalidate_tlb_page_selective(guc,
+ INTEL_GUC_TLB_INVAL_MODE_HEAVY,
+ start, size) == 0;
+
+ return ret;
+}
+
void intel_gt_init_tlb(struct intel_gt *gt)
{
mutex_init(>->tlb.invalidate_lock);
diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.h b/drivers/gpu/drm/i915/gt/intel_tlb.h
index 337327af92ac4..9e5fc40c2b08e 100644
--- a/drivers/gpu/drm/i915/gt/intel_tlb.h
+++ b/drivers/gpu/drm/i915/gt/intel_tlb.h
@@ -12,6 +12,7 @@
#include "intel_gt_types.h"
void intel_gt_invalidate_tlb_full(struct intel_gt *gt, u32 seqno);
+bool intel_gt_invalidate_tlb_range(struct intel_gt *gt, u64 start, u64 length);
void intel_gt_init_tlb(struct intel_gt *gt);
void intel_gt_fini_tlb(struct intel_gt *gt);
diff --git a/drivers/gpu/drm/i915/gt/selftest_tlb.c b/drivers/gpu/drm/i915/gt/selftest_tlb.c
index 24beb94aa7a37..29f137a6e0362 100644
--- a/drivers/gpu/drm/i915/gt/selftest_tlb.c
+++ b/drivers/gpu/drm/i915/gt/selftest_tlb.c
@@ -382,10 +382,45 @@ static int invalidate_full(void *arg)
return err;
}
+static void tlbinv_range(struct i915_address_space *vm, u64 addr, u64 length)
+{
+ if (!intel_gt_invalidate_tlb_range(vm->gt, addr, length))
+ pr_err("range invalidate failed\n");
+}
+
+static bool has_invalidate_range(struct intel_gt *gt)
+{
+ intel_wakeref_t wf;
+ bool result = false;
+
+ with_intel_gt_pm(gt, wf)
+ result = intel_gt_invalidate_tlb_range(gt, 0, gt->vm->total);
+
+ return result;
+}
+
+static int invalidate_range(void *arg)
+{
+ struct intel_gt *gt = arg;
+ int err;
+
+ if (!has_invalidate_range(gt))
+ return 0;
+
+ err = mem_tlbinv(gt, create_smem, tlbinv_range);
+ if (err == 0)
+ err = mem_tlbinv(gt, create_lmem, tlbinv_range);
+ if (err == -ENODEV || err == -ENXIO)
+ err = 0;
+
+ return err;
+}
+
int intel_tlb_live_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
SUBTEST(invalidate_full),
+ SUBTEST(invalidate_range),
};
struct intel_gt *gt;
unsigned int i;
@@ -403,3 +438,56 @@ int intel_tlb_live_selftests(struct drm_i915_private *i915)
return 0;
}
+
+static int tlb_page_size(void *arg)
+{
+ int start, size, offset;
+
+ for (start = 0; start < 57; start++) {
+ for (size = 0; size <= 57 - start; size++) {
+ for (offset = 0; offset <= size; offset++) {
+ u64 len = BIT(size);
+ u64 addr = BIT(start) + len - BIT(offset);
+ u64 expected_start = addr;
+ u64 expected_end = addr + len - 1;
+ int err = 0;
+
+ if (addr + len < addr)
+ continue;
+
+ len = tlb_page_selective_size(&addr, len);
+ if (addr > expected_start) {
+ pr_err("(start:%d, size:%d, offset:%d, range:[%llx, %llx]) invalidate range:[%llx + %llx] after start:%llx\n",
+ start, size, offset,
+ expected_start, expected_end,
+ addr, len,
+ expected_start);
+ err = -EINVAL;
+ }
+
+ if (addr + len < expected_end) {
+ pr_err("(start:%d, size:%d, offset:%d, range:[%llx, %llx]) invalidate range:[%llx + %llx] before end:%llx\n",
+ start, size, offset,
+ expected_start, expected_end,
+ addr, len,
+ expected_end);
+ err = -EINVAL;
+ }
+
+ if (err)
+ return err;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int intel_tlb_mock_selftests(void)
+{
+ static const struct i915_subtest tests[] = {
+ SUBTEST(tlb_page_size),
+ };
+
+ return i915_subtests(tests, NULL);
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 0c22e0fc9059c..3e00cd2b6e53c 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -21,6 +21,7 @@ selftest(fence, i915_sw_fence_mock_selftests)
selftest(scatterlist, scatterlist_mock_selftests)
selftest(syncmap, i915_syncmap_mock_selftests)
selftest(uncore, intel_uncore_mock_selftests)
+selftest(tlb, intel_tlb_mock_selftests)
selftest(ring, intel_ring_mock_selftests)
selftest(engine, intel_engine_cs_mock_selftests)
selftest(timelines, intel_timeline_mock_selftests)
--
2.25.1
next prev parent reply other threads:[~2023-10-10 18:55 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-10 18:44 [Intel-gfx] [RFC PATCH 00/10] drm/i915: Implement range-based TLB Jonathan Cavitt
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 01/10] drm/i915: Add GuC TLB Invalidation device info flags Jonathan Cavitt
2023-10-10 18:44 ` [Intel-gfx] [PATCH dii-client 1/2] drm/i915: Add generic interface for tlb invalidation Jonathan Cavitt
2023-10-11 0:10 ` kernel test robot
2023-10-11 1:35 ` kernel test robot
2023-10-10 18:44 ` [Intel-gfx] [PATCH dii-client 2/2] drm/i915: Use selective tlb invalidations where supported Jonathan Cavitt
2023-10-10 19:37 ` Cavitt, Jonathan
2023-10-12 0:24 ` kernel test robot
2023-10-21 15:43 ` kernel test robot
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 02/10] drm/i915/guc: Add CT size delay helper Jonathan Cavitt
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 03/10] drm/i915: Define and use GuC and CTB TLB invalidation routines Jonathan Cavitt
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 04/10] drm/i915: No TLB invalidation on suspended GT Jonathan Cavitt
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 05/10] drm/i915: No TLB invalidation on wedged GT Jonathan Cavitt
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 06/10] drm/i915/gt: Increase sleep in gt_tlb selftest sanitycheck Jonathan Cavitt
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 07/10] drm/i915: Enable GuC TLB invalidations for MTL Jonathan Cavitt
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 08/10] drm/i915: Define GuC Based TLB invalidation routines Jonathan Cavitt
2023-10-10 18:44 ` Jonathan Cavitt [this message]
2023-10-10 18:44 ` [Intel-gfx] [RFC PATCH 10/10] drm/i915: Use selective tlb invalidations where supported Jonathan Cavitt
2023-10-11 8:16 ` Tvrtko Ursulin
-- strict thread matches above, loose matches on Subject: below --
2023-10-10 18:46 [Intel-gfx] [RFC PATCH 00/10] drm/i915: Implement range-based TLB Jonathan Cavitt
2023-10-10 18:46 ` [Intel-gfx] [RFC PATCH 09/10] drm/i915: Add generic interface for tlb invalidation Jonathan Cavitt
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=20231010184423.2118908-12-jonathan.cavitt@intel.com \
--to=jonathan.cavitt@intel.com \
--cc=andi.shyti@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=nirmoy.das@intel.com \
--cc=saurabhg.gupta@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