]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/xe: rework PDE PAT index selection
authorMatthew Auld <matthew.auld@intel.com>
Fri, 8 Aug 2025 10:34:56 +0000 (11:34 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Nov 2025 20:36:58 +0000 (15:36 -0500)
[ Upstream commit 17593a69b75f098280ad88b625f2d8c5bfe4c6a1 ]

For non-leaf paging structures we end up selecting a random index
between [0, 3], depending on the first user if the page-table is shared,
since non-leaf structures only have two bits in the HW for encoding the
PAT index, and here we are just passing along the full user provided
index, which can be an index as large as ~31 on xe2+. The user provided
index is meant for the leaf node, which maps the actual BO pages where
we have more PAT bits, and not the non-leaf nodes which are only mapping
other paging structures, and so only needs a minimal PAT index range.
Also the chosen index might need to consider how the driver mapped the
paging structures on the host side, like wc vs wb, which is separate
from the user provided index.

With that move the PDE PAT index selection under driver control. For now
just use a coherent index on platforms with page-tables that are cached
on host side, and incoherent otherwise. Using a coherent index could
potentially be expensive, and would be overkill if we know the page-table
is always uncached on host side.

v2 (Stuart):
  - Add some documentation and split into separate helper.

BSpec: 59510
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Stuart Summers <stuart.summers@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Stuart Summers <stuart.summers@intel.com>
Link: https://lore.kernel.org/r/20250808103455.462424-2-matthew.auld@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/xe/xe_migrate.c
drivers/gpu/drm/xe/xe_pt.c
drivers/gpu/drm/xe/xe_pt_types.h
drivers/gpu/drm/xe/xe_vm.c

index 13e287e0370967d56cbfe8b75b827383673e1655..9b1e3dce1aea35ca6218831b0719e80cf1fa8ce7 100644 (file)
@@ -163,8 +163,7 @@ static void xe_migrate_program_identity(struct xe_device *xe, struct xe_vm *vm,
        for (pos = dpa_base; pos < vram_limit;
             pos += SZ_1G, ofs += 8) {
                if (pos + SZ_1G >= vram_limit) {
-                       entry = vm->pt_ops->pde_encode_bo(bo, pt_2m_ofs,
-                                                         pat_index);
+                       entry = vm->pt_ops->pde_encode_bo(bo, pt_2m_ofs);
                        xe_map_wr(xe, &bo->vmap, ofs, u64, entry);
 
                        flags = vm->pt_ops->pte_encode_addr(xe, 0,
@@ -218,7 +217,7 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
 
        /* PT30 & PT31 reserved for 2M identity map */
        pt29_ofs = xe_bo_size(bo) - 3 * XE_PAGE_SIZE;
-       entry = vm->pt_ops->pde_encode_bo(bo, pt29_ofs, pat_index);
+       entry = vm->pt_ops->pde_encode_bo(bo, pt29_ofs);
        xe_pt_write(xe, &vm->pt_root[id]->bo->vmap, 0, entry);
 
        map_ofs = (num_entries - num_setup) * XE_PAGE_SIZE;
@@ -286,15 +285,14 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
                        flags = XE_PDE_64K;
 
                entry = vm->pt_ops->pde_encode_bo(bo, map_ofs + (u64)(level - 1) *
-                                                 XE_PAGE_SIZE, pat_index);
+                                                 XE_PAGE_SIZE);
                xe_map_wr(xe, &bo->vmap, map_ofs + XE_PAGE_SIZE * level, u64,
                          entry | flags);
        }
 
        /* Write PDE's that point to our BO. */
        for (i = 0; i < map_ofs / PAGE_SIZE; i++) {
-               entry = vm->pt_ops->pde_encode_bo(bo, (u64)i * XE_PAGE_SIZE,
-                                                 pat_index);
+               entry = vm->pt_ops->pde_encode_bo(bo, (u64)i * XE_PAGE_SIZE);
 
                xe_map_wr(xe, &bo->vmap, map_ofs + XE_PAGE_SIZE +
                          (i + 1) * 8, u64, entry);
index c8e63bd23300e37865d429bd3d8c48dc576476b7..eb9774a8f683cd386b570be4ab86bad4cfabb2b9 100644 (file)
@@ -69,7 +69,7 @@ static u64 __xe_pt_empty_pte(struct xe_tile *tile, struct xe_vm *vm,
 
        if (level > MAX_HUGEPTE_LEVEL)
                return vm->pt_ops->pde_encode_bo(vm->scratch_pt[id][level - 1]->bo,
-                                                0, pat_index);
+                                                0);
 
        return vm->pt_ops->pte_encode_addr(xe, 0, pat_index, level, IS_DGFX(xe), 0) |
                XE_PTE_NULL;
@@ -616,7 +616,7 @@ xe_pt_stage_bind_entry(struct xe_ptw *parent, pgoff_t offset,
                        xe_child->is_compact = true;
                }
 
-               pte = vm->pt_ops->pde_encode_bo(xe_child->bo, 0, pat_index) | flags;
+               pte = vm->pt_ops->pde_encode_bo(xe_child->bo, 0) | flags;
                ret = xe_pt_insert_entry(xe_walk, xe_parent, offset, xe_child,
                                         pte);
        }
index 69eab6f37cfe638cb25e187e252185d8e4596868..17cdd7c7e9f5e1bcbeb1b4c5dda843f45c4c41af 100644 (file)
@@ -45,8 +45,7 @@ struct xe_pt_ops {
        u64 (*pte_encode_addr)(struct xe_device *xe, u64 addr,
                               u16 pat_index,
                               u32 pt_level, bool devmem, u64 flags);
-       u64 (*pde_encode_bo)(struct xe_bo *bo, u64 bo_offset,
-                            u16 pat_index);
+       u64 (*pde_encode_bo)(struct xe_bo *bo, u64 bo_offset);
 };
 
 struct xe_pt_entry {
index bf44cd5bf49c0f855423e46f8c8a4811c961c55d..30c32717a980e5c91a7de895dfea306c6df464b0 100644 (file)
@@ -1547,14 +1547,39 @@ static u64 pte_encode_ps(u32 pt_level)
        return 0;
 }
 
-static u64 xelp_pde_encode_bo(struct xe_bo *bo, u64 bo_offset,
-                             const u16 pat_index)
+static u16 pde_pat_index(struct xe_bo *bo)
+{
+       struct xe_device *xe = xe_bo_device(bo);
+       u16 pat_index;
+
+       /*
+        * We only have two bits to encode the PAT index in non-leaf nodes, but
+        * these only point to other paging structures so we only need a minimal
+        * selection of options. The user PAT index is only for encoding leaf
+        * nodes, where we have use of more bits to do the encoding. The
+        * non-leaf nodes are instead under driver control so the chosen index
+        * here should be distict from the user PAT index. Also the
+        * corresponding coherency of the PAT index should be tied to the
+        * allocation type of the page table (or at least we should pick
+        * something which is always safe).
+        */
+       if (!xe_bo_is_vram(bo) && bo->ttm.ttm->caching == ttm_cached)
+               pat_index = xe->pat.idx[XE_CACHE_WB];
+       else
+               pat_index = xe->pat.idx[XE_CACHE_NONE];
+
+       xe_assert(xe, pat_index <= 3);
+
+       return pat_index;
+}
+
+static u64 xelp_pde_encode_bo(struct xe_bo *bo, u64 bo_offset)
 {
        u64 pde;
 
        pde = xe_bo_addr(bo, bo_offset, XE_PAGE_SIZE);
        pde |= XE_PAGE_PRESENT | XE_PAGE_RW;
-       pde |= pde_encode_pat_index(pat_index);
+       pde |= pde_encode_pat_index(pde_pat_index(bo));
 
        return pde;
 }
@@ -2085,8 +2110,7 @@ struct xe_vm *xe_vm_lookup(struct xe_file *xef, u32 id)
 
 u64 xe_vm_pdp4_descriptor(struct xe_vm *vm, struct xe_tile *tile)
 {
-       return vm->pt_ops->pde_encode_bo(vm->pt_root[tile->id]->bo, 0,
-                                        tile_to_xe(tile)->pat.idx[XE_CACHE_WB]);
+       return vm->pt_ops->pde_encode_bo(vm->pt_root[tile->id]->bo, 0);
 }
 
 static struct xe_exec_queue *