Add support to dump page table for debug purpose.
Here is an example dump. Format is,
[<page table index>] <start VA pfn>: <value>

Page Table dump start 0x0 len 0xffffffffffffffff
      [0x0fe] 0x7f0000000: 0x6b0003
              [0x1e6] 0x7f7980000: 0x6c0003
                      [0x16d] 0x7f79ada00: 0x5f0003
                              [0x000] 0x7f79ada00: 0x610803
                      [0x16e] 0x7f79adc00: 0x6d0003
                              [0x000] 0x7f79adc00: 0x630803
      [0x100] 0x800000000: 0x6f0003
              [0x000] 0x800000000: 0x700000
                      [0x000] 0x800000000: 0x710003
                              [0x000] 0x800000000: 0x5d0803

Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Cc: Jon Bloomfield <jon.bloomfi...@intel.com>
Cc: Daniel Vetter <daniel.vet...@intel.com>
Cc: Sudeep Dutt <sudeep.d...@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathap...@intel.com>
---
 drivers/gpu/drm/i915/Kconfig.debug            | 14 +++
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  1 +
 drivers/gpu/drm/i915/i915_gem_gtt.c           | 92 +++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.h           | 14 +++
 4 files changed, 121 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig.debug 
b/drivers/gpu/drm/i915/Kconfig.debug
index 1140525da75a..06953c1d6fd4 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -223,3 +223,17 @@ config DRM_I915_DEBUG_RUNTIME_PM
          driver loading, suspend and resume operations.
 
          If in doubt, say "N"
+
+config DRM_I915_DUMP_PPGTT
+        bool "Enable PPGTT Page Table dump support"
+        depends on DRM_I915
+        default n
+        help
+         Choose this option to enable PPGTT page table dump support.
+         The page table snapshot helps developers to debug page table
+         related issues. This will affect performance and dumps a lot of
+         information, so only recommended for developer debug.
+
+          Recommended for driver developers only.
+
+         If in doubt, say "N".
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index cbcfbf86ea61..c771659d72e2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2707,6 +2707,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
                intel_engine_pool_mark_active(eb.batch->private, eb.request);
 
        trace_i915_request_queue(eb.request, eb.batch_flags);
+       ppgtt_dump(eb.context->vm, 0, eb.context->vm->total);
        err = eb_submit(&eb);
 err_request:
        add_to_client(eb.request, file);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 08cbbb4d91cb..6a7348af5717 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1215,6 +1215,97 @@ static int gen8_ppgtt_alloc(struct i915_address_space 
*vm,
        return err;
 }
 
+#ifdef CONFIG_DRM_I915_DUMP_PPGTT
+static void __gen8_ppgtt_dump(struct i915_address_space * const vm,
+                             struct i915_page_directory * const pd,
+                             u64 start, u64 end, int lvl)
+{
+       char *prefix[4] = { "\t\t\t\t", "\t\t\t", "\t\t", "\t"};
+       char *format = "%s [0x%03x] 0x%llx: 0x%llx\n";
+       unsigned int idx, len;
+       gen8_pte_t *vaddr;
+       unsigned int pdpe;
+       bool is_large;
+
+       GEM_BUG_ON(end > vm->total >> GEN8_PTE_SHIFT);
+
+       len = gen8_pd_range(start, end, lvl--, &idx);
+       GEM_BUG_ON(!len || (idx + len - 1) >> gen8_pd_shift(1));
+
+       spin_lock(&pd->lock);
+       GEM_BUG_ON(!atomic_read(px_used(pd))); /* Must be pinned! */
+       do {
+               struct i915_page_table *pt = pd->entry[idx];
+
+               if (!pt) {
+                       start += (1 << gen8_pd_shift(lvl + 1));
+                       continue;
+               }
+
+               vaddr = kmap_atomic_px(&pd->pt);
+               pdpe = gen8_pd_index(start, lvl + 1);
+               DRM_DEBUG_DRIVER(format, prefix[lvl + 1], pdpe,
+                                start, vaddr[pdpe]);
+               is_large = (vaddr[pdpe] & GEN8_PDE_PS_2M);
+               kunmap_atomic(vaddr);
+               if (is_large) {
+                       start += (1 << gen8_pd_shift(lvl + 1));
+                       continue;
+               }
+
+               if (lvl) {
+                       atomic_inc(&pt->used);
+                       spin_unlock(&pd->lock);
+
+                       __gen8_ppgtt_dump(vm, as_pd(pt),
+                                         start, end, lvl);
+
+                       start += (1 << gen8_pd_shift(lvl + 1));
+                       spin_lock(&pd->lock);
+                       atomic_dec(&pt->used);
+                       GEM_BUG_ON(!atomic_read(&pt->used));
+               } else {
+                       unsigned int count = gen8_pt_count(start, end);
+
+                       pdpe = gen8_pd_index(start, lvl);
+                       vaddr = kmap_atomic_px(pt);
+                       while (count) {
+                               if (vaddr[pdpe] != vm->scratch[lvl].encode)
+                                       DRM_DEBUG_DRIVER(format, prefix[lvl],
+                                                        pdpe, start,
+                                                        vaddr[pdpe]);
+                               start++;
+                               count--;
+                               pdpe++;
+                       }
+
+                       kunmap_atomic(vaddr);
+                       GEM_BUG_ON(atomic_read(&pt->used) > I915_PDES);
+               }
+       } while (idx++, --len);
+       spin_unlock(&pd->lock);
+}
+
+static void gen8_ppgtt_dump(struct i915_address_space *vm,
+                           u64 start, u64 length)
+{
+       GEM_BUG_ON(!IS_ALIGNED(start, BIT_ULL(GEN8_PTE_SHIFT)));
+       GEM_BUG_ON(!IS_ALIGNED(length, BIT_ULL(GEN8_PTE_SHIFT)));
+       GEM_BUG_ON(range_overflows(start, length, vm->total));
+
+       start >>= GEN8_PTE_SHIFT;
+       length >>= GEN8_PTE_SHIFT;
+       GEM_BUG_ON(length == 0);
+
+       DRM_DEBUG_DRIVER("PPGTT dump: start 0x%llx length 0x%llx\n",
+                        start, length);
+       __gen8_ppgtt_dump(vm, i915_vm_to_ppgtt(vm)->pd,
+                         start, start + length, vm->top);
+}
+#else
+#define gen8_ppgtt_dump   NULL
+#endif
+
 static inline struct sgt_dma {
        struct scatterlist *sg;
        dma_addr_t dma, max;
@@ -1584,6 +1675,7 @@ static struct i915_ppgtt *gen8_ppgtt_create(struct 
drm_i915_private *i915)
        ppgtt->vm.insert_entries = gen8_ppgtt_insert;
        ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc;
        ppgtt->vm.clear_range = gen8_ppgtt_clear;
+       ppgtt->vm.dump_va_range = gen8_ppgtt_dump;
 
        if (intel_vgpu_active(i915))
                gen8_ppgtt_notify_vgt(ppgtt, true);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 722b1e7ce291..a4358fb1c711 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -367,6 +367,8 @@ struct i915_address_space {
                                 u64 start, u64 length);
        void (*clear_range)(struct i915_address_space *vm,
                            u64 start, u64 length);
+       void (*dump_va_range)(struct i915_address_space *vm,
+                             u64 start, u64 length);
        void (*insert_page)(struct i915_address_space *vm,
                            dma_addr_t addr,
                            u64 offset,
@@ -683,6 +685,18 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 
 #define PIN_OFFSET_MASK                (-I915_GTT_PAGE_SIZE)
 
+#ifdef CONFIG_DRM_I915_DUMP_PPGTT
+static inline void ppgtt_dump(struct i915_address_space *vm,
+                             u64 start, u64 length)
+{
+       if (vm->dump_va_range)
+               vm->dump_va_range(vm, start, length);
+}
+#else
+static inline void ppgtt_dump(struct i915_address_space *vm,
+                             u64 start, u64 length) { }
+#endif
+
 /* SVM API */
 #define I915_GTT_SVM_READONLY  BIT(0)
 
-- 
2.21.0.rc0.32.g243a4c7e27

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to