From: Matthew Auld <matthew.auld@intel.com>
To: Matthew Brost <matthew.brost@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: Tue, 1 Sep 2026 09:48:14 +0100 [thread overview]
Message-ID: <5dd32f3a-901a-4fb0-9517-6298a1f71eac@intel.com> (raw)
In-Reply-To: <apHljQtQ+Ojgtw2P@gsse-cloud1.jf.intel.com>
On 28/08/2026 20:46, Matthew Brost wrote:
> 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?
Yeah, my local v1 did exactly that. But I got doubts since it felt a bit
scary taking away slots from userspace and wasn't sure if there could be
some impact.
Can revert back to that approach if you prefer? It should be somewhere
in my reflog.
>
> Also, in general, power-of-two values are preferred.
Yeah, I think it was just the assert:
/* Must be a multiple of 64K to support all platforms */
BUILD_BUG_ON(NUM_PT_SLOTS * XE_PAGE_SIZE % SZ_64K);
So just went with the minimal to satisfy that. Will make this a
power-of-two instead if 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-09-01 8:48 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
2026-09-01 8:48 ` Matthew Auld [this message]
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=5dd32f3a-901a-4fb0-9517-6298a1f71eac@intel.com \
--to=matthew.auld@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=matthew.brost@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