> On Sep 21, 2026, at 21:09, Oscar Salvador (SUSE) <[email protected]> wrote:
>
> On Thu, Sep 03, 2026 at 08:21:26PM +0800, Muchun Song wrote:
>> FS-DAX registers persistent-memory ranges as ZONE_DEVICE memory, and the
>> kernel normally allocates and initializes vmemmap storage for every
>> advertised PFN up front. Sparse pmem images and workloads that only use the
>> DAX direct-access path may never need writable per-PFN state for most of
>> that range, but still pay the memory and initialization cost.
>>
>> Add an opt-in dev_pagemap mode that populates FS-DAX vmemmap PTEs from a
>> shared read-only metadata page. The shared page is initialized with the
>> common ZONE_DEVICE and dev_pagemap state, so every PFN still has a valid
>> struct page representation while private metadata allocation is deferred.
>>
>> This relies on sizeof(struct page) being a power of two, so each vmemmap
>> page contains a naturally aligned and repeatable set of struct page slots.
>> It also requires architecture support for runtime vmemmap remapping,
>> because shared mappings must be replaced with private writable pages before
>> a PFN can enter userspace mappings.
>>
>> The initial implementation is deliberately limited to a single
>> memory-block-aligned range. That is not a fundamental requirement, but keeps
>> the registration and teardown paths simple; support for multiple ranges or
>> less strict alignment can be added later.
>>
>> Provide vmemmap_materialize_page() to replace shared mappings in the
>> requested metadata range with private writable copies. A later patch will
>> call it from the FS-DAX fault path.
>>
>> No caller enables the mode yet.
> ...
>> +static int pgmap_vmemmap_shared_page_alloc(struct dev_pagemap *pgmap, int
>> nid)
>> +{
>> + const struct range *range = &pgmap->range;
>> +
>> + if (!is_power_of_2(sizeof(struct page)) ||
>> + !IS_ENABLED(CONFIG_ARCH_SUPPORTS_VMEMMAP_REMAP) ||
>> + !(pgmap->flags & PGMAP_VMEMMAP_OPTIMIZATION))
>> + return 0;
>> +
>> + if (pgmap->nr_range != 1 ||
>> + !IS_ALIGNED(range->start | range_len(range), MIN_MEMORY_BLOCK_SIZE))
>> + return 0;
>> +
>> + pgmap->vmemmap_shared_page = alloc_pages_node(nid, GFP_KERNEL, 0);
>> +
>> + return pgmap->vmemmap_shared_page ? 0 : -ENOMEM;
>
> I yet have to look into this with more detail, but this caught my eye.
> Should not this be a best-efford mode optimization? So, if we were
> unable to allocate the page, could not we treat this as a normal "cannot
> be optimized, follow by-default procedure" ?
>
>
My thinking is that if we fail to allocate memory here, the subsequent
vmemmap allocation will need way more memory than just this one page.
So it's very likely to fail anyway.
Thanks,
Muchun
>
> --
> Oscar Salvador
> SUSE Labs