On 7/14/26 10:44 AM, Muchun Song wrote:
>
>
> On 2026/7/9 19:25, Li Zhe wrote:
>> memmap_init_zone_device() currently mixes refcount policy and core
>> ZONE_DEVICE page setup in a single helper.
>>
>> Factor the refcount-reset predicate into pagemap_resets_refcount(), move
>> the common page initialization into __zone_device_page_init(), and wrap
>> the existing slow path in zone_device_page_init_slow().
>
> Hi,
>
> Sorry if this has been discussed before, but I'm still curious—what
> is the significance of the 'slow' suffix here? I don't think I quite
> understand why this is called the 'slow path' here. Is there also a
> 'fast path' for initializing struct page?
>
> Thanks. 

The "slow" suffix here is relative to the template-copy fast path added
later in patch 4.

Patch 2 factors the existing per-page initialization path into a helper
so that the later patches can reuse it as the fallback path when
template copying is not used. In that sense, this helper is the slow
path, while the fast path is introduced later in the series.

Thanks,
Zhe

>>
>> This keeps the slow-path behaviour unchanged and gives later patches
>> reusable helper boundaries.
>>
>> No functional change intended.
>>
>> Signed-off-by: Li Zhe <[email protected]>
>> Reviewed-by: Mike Rapoport (Microsoft) <[email protected]>
>> ---
>>   mm/mm_init.c | 56 ++++++++++++++++++++++++++++++++++------------------
>>   1 file changed, 37 insertions(+), 19 deletions(-)
>>
>> diff --git a/mm/mm_init.c b/mm/mm_init.c
>> index 95808ab5cfdb..5fccfbacf855 100644
>> --- a/mm/mm_init.c
>> +++ b/mm/mm_init.c
>> @@ -1005,11 +1005,37 @@ static void __init memmap_init(void)
>>   }
>>     #ifdef CONFIG_ZONE_DEVICE
>> -static void __ref __init_zone_device_page(struct page *page, 
>> unsigned long pfn,
>> +/*
>> + * Return true when the free path for this pagemap type restores the 
>> page
>> + * refcount to 1, so memmap_init_zone_device() can keep the count 
>> set by
>> + * __init_single_page(). Otherwise initialize the refcount to 0 and 
>> leave
>> + * it to the allocator or pgmap callbacks to raise it when the page is
>> + * handed out again.
>> + */
>> +static inline bool pagemap_resets_refcount(const struct dev_pagemap 
>> *pgmap)
>> +{
>> +    /*
>> +     * MEMORY_DEVICE_GENERIC pages regain a refcount of 1 in the free
>> +     * path. The remaining ZONE_DEVICE types start from 0 here and 
>> raise
>> +     * the count again when the allocator or driver hands the page out.
>> +     */
>> +    switch (pgmap->type) {
>> +    case MEMORY_DEVICE_FS_DAX:
>> +    case MEMORY_DEVICE_PRIVATE:
>> +    case MEMORY_DEVICE_COHERENT:
>> +    case MEMORY_DEVICE_PCI_P2PDMA:
>> +        return false;
>> +    case MEMORY_DEVICE_GENERIC:
>> +        return true;
>> +    }
>> +
>> +    return true;
>> +}
>> +
>> +static void __ref __zone_device_page_init(struct page *page, 
>> unsigned long pfn,
>>                         unsigned long zone_idx, int nid,
>>                         struct dev_pagemap *pgmap)
>>   {
>> -
>>       __init_single_page(page, pfn, zone_idx, nid);
>>
>>       /*
>> @@ -1028,23 +1054,15 @@ static void __ref 
>> __init_zone_device_page(struct page *page, unsigned long pfn,
>>        */
>>       page_folio(page)->pgmap = pgmap;
>>       page->zone_device_data = NULL;
>> +}
>>
>> -    /*
>> -     * MEMORY_DEVICE_GENERIC pages regain a refcount of 1 in the free
>> -     * path. The remaining ZONE_DEVICE types start from 0 here and 
>> raise
>> -     * the count again when the allocator or driver hands the page out.
>> -     */
>> -    switch (pgmap->type) {
>> -    case MEMORY_DEVICE_FS_DAX:
>> -    case MEMORY_DEVICE_PRIVATE:
>> -    case MEMORY_DEVICE_COHERENT:
>> -    case MEMORY_DEVICE_PCI_P2PDMA:
>> +static void __ref zone_device_page_init_slow(struct page *page,
>> +        unsigned long pfn, unsigned long zone_idx, int nid,
>> +        struct dev_pagemap *pgmap)
>> +{
>> +    __zone_device_page_init(page, pfn, zone_idx, nid, pgmap);
>> +    if (!pagemap_resets_refcount(pgmap))
>>           set_page_count(page, 0);
>> -        break;
>> -
>> -    case MEMORY_DEVICE_GENERIC:
>> -        break;
>> -    }
>>   }
>>
>>   /*
>> @@ -1090,7 +1108,7 @@ static void __ref memmap_init_compound(struct 
>> page *head,
>>       for (pfn = head_pfn + 1; pfn < end_pfn; pfn++) {
>>           struct page *page = pfn_to_page(pfn);
>>
>> -        __init_zone_device_page(page, pfn, zone_idx, nid, pgmap);
>> +        zone_device_page_init_slow(page, pfn, zone_idx, nid, pgmap);
>>           prep_compound_tail(page, head, order);
>>           set_page_count(page, 0);
>>       }
>> @@ -1126,7 +1144,7 @@ void __ref memmap_init_zone_device(struct zone 
>> *zone,
>>       for (pfn = start_pfn; pfn < end_pfn; pfn += pfns_per_compound) {
>>           struct page *page = pfn_to_page(pfn);
>>
>> -        __init_zone_device_page(page, pfn, zone_idx, nid, pgmap);
>> +        zone_device_page_init_slow(page, pfn, zone_idx, nid, pgmap);
>>
>>           if (IS_ALIGNED(pfn, PAGES_PER_SECTION))
>>               cond_resched();
>> -- 
>> 2.20.1
>

Reply via email to