From: Matthew Brost <matthew.brost@intel.com>
To: Matthew Auld <matthew.auld@intel.com>
Cc: intel-xe@lists.freedesktop.org,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
"Rodrigo Vivi" <rodrigo.vivi@intel.com>
Subject: Re: [PATCH 1/5] drm/xe/migrate: support 4K PTEs for identity map
Date: Fri, 28 Aug 2026 12:46:21 -0700 [thread overview]
Message-ID: <apHljQtQ+Ojgtw2P@gsse-cloud1.jf.intel.com> (raw)
In-Reply-To: <20260828151405.662533-8-matthew.auld@intel.com>
On Fri, Aug 28, 2026 at 04:14:07PM +0100, Matthew Auld wrote:
> When VRAM limit (usable_size) is no longer 2M aligned (e.g. because flat
> CCS storage size rounds it down to 4K), we must map the tail of the
> identity mapping using 4K pages.
>
> This removes the 2M alignment assert (which pops) and introduces a 4K
> fallback in the identity map programming loop to handle the last 2M
> chunk of usable VRAM.
>
> Might be possible to skip backporting this. The assert that pops should
> be harmless and is only on debug builds plus only a stray write would
> hit CCS, which technically get mapped.
>
This LGTM, better than what I had in mind. One question though.
> Assisted-by: Gemini:gemini-3.1-pro-preview
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> ---
> drivers/gpu/drm/xe/xe_migrate.c | 57 +++++++++++++++++++++------------
> 1 file changed, 37 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c
> index 75b83687f1b5..0bf000d7c901 100644
> --- a/drivers/gpu/drm/xe/xe_migrate.c
> +++ b/drivers/gpu/drm/xe/xe_migrate.c
> @@ -87,7 +87,7 @@ struct xe_migrate {
> #define MAX_PREEMPTDISABLE_TRANSFER SZ_8M /* Around 1ms. */
> #define MAX_CCS_LIMITED_TRANSFER SZ_4M /* XE_PAGE_SIZE * (FIELD_MAX(XE2_CCS_SIZE_MASK) + 1) */
> #define NUM_KERNEL_PDE 15
> -#define NUM_PT_SLOTS 32
> +#define NUM_PT_SLOTS 48
Why this change? Can't we just steal more PTs from user-space VM binds?
Did testing show that this was actually a problem?
Also, in general, power-of-two values are preferred.
Eventually, we'll be able to drop the need for these PTs once CPU binds
land as well [1].
Not blocker.
Matt
[1] https://patchwork.freedesktop.org/series/149888/
> #define LEVEL0_PAGE_TABLE_ENCODE_SIZE SZ_2M
> #define MAX_NUM_PTE 512
> #define IDENTITY_OFFSET 256ULL
> @@ -163,22 +163,20 @@ static u64 xe_migrate_vram_ofs(struct xe_device *xe, u64 addr, bool is_comp_pte)
> }
>
> static void xe_migrate_program_identity(struct xe_device *xe, struct xe_vm *vm, struct xe_bo *bo,
> - u64 map_ofs, u64 vram_offset, u16 pat_index, u64 pt_2m_ofs)
> + u64 map_ofs, u64 vram_offset, u16 pat_index, u64 pt_2m_ofs,
> + u64 pt_4k_ofs)
> {
> struct xe_vram_region *vram = xe->mem.vram;
> resource_size_t dpa_base = xe_vram_region_dpa_base(vram);
> u64 pos, ofs, flags;
> u64 entry;
> - /* XXX: Unclear if this should be usable_size? */
> - u64 vram_limit = xe_vram_region_actual_physical_size(vram) + dpa_base;
> + u64 vram_limit = xe_vram_region_usable_size(vram) + dpa_base;
> u32 level = 2;
>
> ofs = map_ofs + XE_PAGE_SIZE * level + vram_offset * 8;
> flags = vm->pt_ops->pte_encode_addr(xe, 0, pat_index, level,
> true, 0);
>
> - xe_assert(xe, IS_ALIGNED(xe_vram_region_usable_size(vram), SZ_2M));
> -
> /*
> * Use 1GB pages when possible, last chunk always use 2M
> * pages as mixing reserved memory (stolen, WOCPM) with a single
> @@ -196,8 +194,24 @@ static void xe_migrate_program_identity(struct xe_device *xe, struct xe_vm *vm,
> true, 0);
>
> for (ofs = pt_2m_ofs; pos < vram_limit;
> - pos += SZ_2M, ofs += 8)
> + pos += SZ_2M, ofs += 8) {
> + if (pos + SZ_2M > vram_limit) {
> + entry = vm->pt_ops->pde_encode_bo(bo, pt_4k_ofs);
> + xe_map_wr(xe, &bo->vmap, ofs, u64, entry);
> +
> + flags = vm->pt_ops->pte_encode_addr(xe, 0,
> + pat_index,
> + level - 2,
> + true, 0);
> +
> + for (ofs = pt_4k_ofs; pos < vram_limit;
> + pos += SZ_4K, ofs += 8)
> + xe_map_wr(xe, &bo->vmap, ofs, u64, pos | flags);
> + break;
> + }
> +
> xe_map_wr(xe, &bo->vmap, ofs, u64, pos | flags);
> + }
> break; /* Ensure pos == vram_limit assert correct */
> }
>
> @@ -242,16 +256,17 @@ static void xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
> u16 pat_index = xe_cache_pat_idx(xe, XE_CACHE_WB);
> u8 id = tile->id;
> u32 num_entries = NUM_PT_SLOTS, num_level = vm->pt_root[id]->level;
> -#define VRAM_IDENTITY_MAP_COUNT 2
> - u32 num_setup = num_level + VRAM_IDENTITY_MAP_COUNT;
> -#undef VRAM_IDENTITY_MAP_COUNT
> +#define VRAM_IDENTITY_MAP_PT_COUNT 4
> + u32 num_setup = num_level + VRAM_IDENTITY_MAP_PT_COUNT;
> +#undef VRAM_IDENTITY_MAP_PT_COUNT
> u32 map_ofs, level, i;
> struct xe_bo *bo = m->pt_bo, *batch = tile->mem.kernel_bb_pool->bo;
> - u64 entry, pt29_ofs;
> + u64 entry;
>
> - /* 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);
> + /* PT44..PT47 reserved for 4K and 2M identity map */
> + u64 l1_pt_ofs = xe_bo_size(bo) - 5 * XE_PAGE_SIZE;
> +
> + entry = vm->pt_ops->pde_encode_bo(bo, l1_pt_ofs);
> xe_pt_write(xe, &vm->pt_root[id]->bo->vmap, 0, entry);
>
> map_ofs = (num_entries - num_setup) * XE_PAGE_SIZE;
> @@ -347,11 +362,12 @@ static void xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
>
> /* Identity map the entire vram at 256GiB offset */
> if (IS_DGFX(xe)) {
> - u64 pt30_ofs = xe_bo_size(bo) - 2 * XE_PAGE_SIZE;
> + u64 pt46_ofs = xe_bo_size(bo) - 2 * XE_PAGE_SIZE;
> resource_size_t actual_phy_size = xe_vram_region_actual_physical_size(xe->mem.vram);
>
> + u64 pt44_ofs = xe_bo_size(bo) - 4 * XE_PAGE_SIZE;
> xe_migrate_program_identity(xe, vm, bo, map_ofs, IDENTITY_OFFSET,
> - pat_index, pt30_ofs);
> + pat_index, pt46_ofs, pt44_ofs);
> xe_assert(xe, actual_phy_size <= (MAX_NUM_PTE - IDENTITY_OFFSET) * SZ_1G);
>
> /*
> @@ -362,12 +378,13 @@ static void xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
> u16 comp_pat_index = xe_cache_pat_idx(xe, XE_CACHE_NONE_COMPRESSION);
> u64 vram_offset = IDENTITY_OFFSET +
> DIV_ROUND_UP_ULL(actual_phy_size, SZ_1G);
> - u64 pt31_ofs = xe_bo_size(bo) - XE_PAGE_SIZE;
> + u64 pt47_ofs = xe_bo_size(bo) - XE_PAGE_SIZE;
>
> xe_assert(xe, actual_phy_size <= (MAX_NUM_PTE - IDENTITY_OFFSET -
> IDENTITY_OFFSET / 2) * SZ_1G);
> + u64 pt45_ofs = xe_bo_size(bo) - 3 * XE_PAGE_SIZE;
> xe_migrate_program_identity(xe, vm, bo, map_ofs, vram_offset,
> - comp_pat_index, pt31_ofs);
> + comp_pat_index, pt47_ofs, pt45_ofs);
> }
> }
>
> @@ -381,8 +398,8 @@ static void xe_migrate_suballoc_manager_init(struct xe_migrate *m, u32 map_ofs)
> * Example layout created above, with root level = 3:
> * [PT0...PT7]: kernel PT's for copy/clear; 64 or 4KiB PTE's
> * [PT8]: Kernel PT for VM_BIND, 4 KiB PTE's
> - * [PT9...PT26]: Userspace PT's for VM_BIND, 4 KiB PTE's
> - * [PT27 = PDE 0] [PT28 = PDE 1] [PT29 = PDE 2] [PT30 & PT31 = 2M vram identity map]
> + * [PT9...PT40]: Userspace PT's for VM_BIND, 4 KiB PTE's
> + * [PT41 = PDE 0] [PT44...PT47 = 4K and 2M vram identity maps]
> *
> * This makes the lowest part of the VM point to the pagetables.
> * Hence the lowest 2M in the vm should point to itself, with a few writes
> --
> 2.55.0
>
next prev parent reply other threads:[~2026-08-28 19:46 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-28 15:14 [PATCH 0/5] VRAM health check + CCS fix Matthew Auld
2026-08-28 15:14 ` [PATCH 1/5] drm/xe/migrate: support 4K PTEs for identity map Matthew Auld
2026-08-28 19:46 ` Matthew Brost [this message]
2026-09-01 8:48 ` Matthew Auld
2026-09-01 20:07 ` Matthew Brost
2026-08-28 15:14 ` [PATCH 2/5] drm/xe: Don't hand out the flat CCS storage as usable VRAM Matthew Auld
2026-08-28 15:14 ` [PATCH 3/5] drm/xe/vram: report FLAT_CCS base misalignment Matthew Auld
2026-08-28 20:10 ` Matthew Brost
2026-09-01 8:23 ` Matthew Auld
2026-09-01 20:10 ` Matthew Brost
2026-08-28 15:14 ` [PATCH 4/5] drm/xe: add force option for global invalidation Matthew Auld
2026-09-01 20:29 ` Matthew Brost
2026-08-28 15:14 ` [PATCH 5/5] drm/xe/vram: add early VRAM health check Matthew Auld
2026-08-28 16:13 ` Linus Torvalds
2026-08-28 19:58 ` Matthew Brost
2026-08-28 20:32 ` Linus Torvalds
2026-08-31 20:50 ` Matthew Brost
2026-08-28 16:37 ` Summers, Stuart
2026-09-01 8:33 ` Matthew Auld
2026-09-02 7:45 ` Matthew Brost
2026-09-02 20:34 ` Summers, Stuart
2026-09-03 9:57 ` Matthew Auld
2026-08-28 15:21 ` ✓ CI.KUnit: success for VRAM health check + CCS fix Patchwork
2026-08-28 15:58 ` ✓ Xe.CI.BAT: " Patchwork
2026-08-28 17:06 ` ✓ Xe.CI.FULL: " Patchwork
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=apHljQtQ+Ojgtw2P@gsse-cloud1.jf.intel.com \
--to=matthew.brost@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=matthew.auld@intel.com \
--cc=rodrigo.vivi@intel.com \
--cc=thomas.hellstrom@linux.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