Re: [PATCH 01/11] mm/sparse-vmemmap: introduce CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION

Muchun Song <[email protected]>
Newsgroups gmane.linux.ports.ppc.embedded
Message-ID <9BB960A5-E8C8-4094-BD28-87FE483AB680__47186.1585787096$1788170205$gmane$org@linux.dev>

> On Aug 31, 2026, at 17:44, Qi Zheng <[email protected]> wrote:
> 
> 
> 
> On 8/31/26 3:53 PM, Muchun Song wrote:
>> The section-based vmemmap optimization infrastructure is still guarded by
>> CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP, but it also can be used by device
>> DAX. Introduce CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION as a common config
>> for the shared infrastructure.
>> Select the new option from HUGETLB_PAGE_OPTIMIZE_VMEMMAP and from
>> DEV_DAX when the architecture opts in to DAX vmemmap optimization, and
>> use it to guard the generic sparse-vmemmap state and helpers.
>> Signed-off-by: Muchun Song <[email protected]>
>> ---
>>  arch/x86/entry/vdso/vdso32/fake_32bit_build.h |  2 +-
>>  drivers/dax/Kconfig                           |  1 +
>>  fs/Kconfig                                    |  1 +
>>  include/linux/mm.h                            |  3 +++
>>  include/linux/mmzone.h                        | 13 +++++++------
>>  include/linux/page-flags.h                    |  5 ++---
>>  mm/Kconfig                                    |  3 +++
>>  mm/sparse.h                                   |  4 ++--
>>  8 files changed, 20 insertions(+), 12 deletions(-)
>> diff --git a/arch/x86/entry/vdso/vdso32/fake_32bit_build.h b/arch/x86/entry/vdso/vdso32/fake_32bit_build.h
>> index bc3e549795c3..5f8424eade2b 100644
>> --- a/arch/x86/entry/vdso/vdso32/fake_32bit_build.h
>> +++ b/arch/x86/entry/vdso/vdso32/fake_32bit_build.h
>> @@ -11,7 +11,7 @@
>>  #undef CONFIG_PGTABLE_LEVELS
>>  #undef CONFIG_ILLEGAL_POINTER_VALUE
>>  #undef CONFIG_SPARSEMEM_VMEMMAP
>> -#undef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>> +#undef CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION
>>  #undef CONFIG_NR_CPUS
>>  #undef CONFIG_PARAVIRT_XXL
>>  diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig
>> index 602f9a0839a9..85ad4c135cdd 100644
>> --- a/drivers/dax/Kconfig
>> +++ b/drivers/dax/Kconfig
>> @@ -8,6 +8,7 @@ if DAX
>>  config DEV_DAX
>>   tristate "Device DAX: direct access mapping device"
>>   depends on TRANSPARENT_HUGEPAGE
>> + select SPARSEMEM_VMEMMAP_OPTIMIZATION if ARCH_WANT_OPTIMIZE_DAX_VMEMMAP
>>   help
>>     Support raw access to differentiated (persistence, bandwidth,
>>     latency...) memory via an mmap(2) capable character
>> diff --git a/fs/Kconfig b/fs/Kconfig
>> index d1c210c6508f..9b32ce79cc80 100644
>> --- a/fs/Kconfig
>> +++ b/fs/Kconfig
>> @@ -278,6 +278,7 @@ config HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>>   def_bool HUGETLB_PAGE
>>   depends on ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
>>   depends on SPARSEMEM_VMEMMAP
>> + select SPARSEMEM_VMEMMAP_OPTIMIZATION
>>    config HUGETLB_PMD_PAGE_TABLE_SHARING
>>   def_bool HUGETLB_PAGE
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index a9fbe26536f4..edadd7549b72 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -5188,6 +5188,9 @@ static inline bool __vmemmap_can_optimize(struct vmem_altmap *altmap,
>>   	unsigned long nr_pages;
>>   	unsigned long nr_vmemmap_pages;
>> + 	if (!IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION))
>> + 		return false;
>> +
>>   	if (!pgmap || !is_power_of_2(sizeof(struct page)))
>>   		return false;
>>  diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
>> index c9ae7991a8b2..e9b54ea0eff0 100644
>> --- a/include/linux/mmzone.h
>> +++ b/include/linux/mmzone.h
>> @@ -102,9 +102,9 @@
>>   *
>>   * HVO which is only active if the size of struct page is a power of 2.
>>   */
>> -#define MAX_FOLIO_VMEMMAP_ALIGN \
>> - 	(IS_ENABLED(CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP) && \
>> -  	is_power_of_2(sizeof(struct page)) ? \
>> +#define MAX_FOLIO_VMEMMAP_ALIGN \
>> + 	(IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION) && \
>> +  	is_power_of_2(sizeof(struct page)) ? \
>>    	MAX_FOLIO_NR_PAGES * sizeof(struct page) : 0)
>>    /* The number of retained vmemmap pages with HVO enabled. */
>> @@ -116,7 +116,8 @@
>>  #define __VMEMMAP_OPTIMIZATION_NR_ORDERS \
>>   (MAX_FOLIO_ORDER - VMEMMAP_OPTIMIZATION_MIN_ORDER + 1)
>>  #define VMEMMAP_OPTIMIZATION_NR_ORDERS \
>> - 	(__VMEMMAP_OPTIMIZATION_NR_ORDERS > 0 ? __VMEMMAP_OPTIMIZATION_NR_ORDERS : 0)
>> + 	((__VMEMMAP_OPTIMIZATION_NR_ORDERS > 0 && \
>> +   	IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION)) ? __VMEMMAP_OPTIMIZATION_NR_ORDERS : 0)
>>    enum migratetype {
>>   MIGRATE_UNMOVABLE,
>> @@ -1155,7 +1156,7 @@ struct zone {
>>   	/* Zone statistics */
>>   	atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
>>   	atomic_long_t vm_numa_event[NR_VM_NUMA_EVENT_ITEMS];
>> -#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>> +#ifdef CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION
>>   	struct page *vmemmap_tails[VMEMMAP_OPTIMIZATION_NR_ORDERS];
>>  #endif
>>  } ____cacheline_internodealigned_in_smp;
>> @@ -2019,7 +2020,7 @@ struct mem_section {
>>   	unsigned long section_mem_map;
>>     	struct mem_section_usage *usage;
>> -#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>> +#ifdef CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION
>>   	/*
>>   	 * Normally, sections hold regular (order-0) pages. However, for
>>   	 * sections with HVO enabled, this tracks the compound page order
>> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
>> index ae2ebaed6d4d..de3c06062bc6 100644
>> --- a/include/linux/page-flags.h
>> +++ b/include/linux/page-flags.h
>> @@ -208,14 +208,13 @@ enum pageflags {
>>  static __always_inline bool compound_info_has_mask(void)
>>  {
>>   	/*
>> - 	 * Limit mask usage to HugeTLB vmemmap optimization (HVO) where it
>> - 	 * makes a difference.
>> + 	 * Limit mask usage to HVO where it makes a difference.
>>   	 *
>>   	 * The approach with mask would work in the wider set of conditions,
>>   	 * but it requires validating that struct pages are naturally aligned
>>   	 * for all orders up to the MAX_FOLIO_ORDER, which can be tricky.
>>   	 */
>> - 	if (!IS_ENABLED(CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP))
>> + 	if (!IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION))
>>   		return false;
>>     	return is_power_of_2(sizeof(struct page));
>> diff --git a/mm/Kconfig b/mm/Kconfig
>> index c1ddf59c0d71..b5f8372cd164 100644
>> --- a/mm/Kconfig
>> +++ b/mm/Kconfig
>> @@ -461,6 +461,9 @@ config SPARSEMEM_VMEMMAP
>>     pfn_to_page and page_to_pfn operations.  This is the most
>>     efficient option when sufficient kernel resources are available.
>>  +config SPARSEMEM_VMEMMAP_OPTIMIZATION
>> + bool
> 
> As sashiko was concerned about [1], it seems we need to add
> 
>        depends on SPARSEMEM_VMEMMAP
> 
> here.

You are right. Besides that, we also need DEV_DAX to depend on
ZONE_DEVICE explicitly.

> 
> Apart from that, LGTM. With this fix included:
> 
> Acked-by: Qi Zheng <[email protected]>

Thanks.

> 
> Thanks,
> Qi
> 
> [1]. https://sashiko.dev/#/patchset/20260831075342.57563-1-songmuchun%40bytedance.com
> 
>> +
>>  #
>>  # Select this config option from the architecture Kconfig, if it is preferred
>>  # to enable the feature of HugeTLB/dev_dax vmemmap optimization.
>> diff --git a/mm/sparse.h b/mm/sparse.h
>> index 049272aba84e..b408d15baf7b 100644
>> --- a/mm/sparse.h
>> +++ b/mm/sparse.h
>> @@ -10,7 +10,7 @@
>>    #include <linux/mmzone.h>
>>  -#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>> +#ifdef CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION
>>  static inline unsigned int section_order(const struct mem_section *section)
>>  {
>>   	return section->order;
>> @@ -72,7 +72,7 @@ static inline bool vmemmap_optimizable_pfn(unsigned long pfn)
>>    static inline bool vmemmap_optimizable_order(unsigned int order)
>>  {
>> - 	if (!IS_ENABLED(CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP))
>> + 	if (!IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP_OPTIMIZATION))
>>   		return false;
>>     	if (!is_power_of_2(sizeof(struct page)))
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.