[V11,2/4] LoongArch: Add sparse memory vmemmap support

Message ID 20221017024027.2389370-3-chenhuacai@loongson.cn
State New
Headers
Series mm/sparse-vmemmap: Generalise helpers and enable for LoongArch |

Commit Message

Huacai Chen Oct. 17, 2022, 2:40 a.m. UTC
  From: Feiyang Chen <chenfeiyang@loongson.cn>

Add sparse memory vmemmap support for LoongArch. SPARSEMEM_VMEMMAP
uses a virtually mapped memmap to optimise pfn_to_page and page_to_pfn
operations. This is the most efficient option when sufficient kernel
resources are available.

Signed-off-by: Min Zhou <zhoumin@loongson.cn>
Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/Kconfig                 |  1 +
 arch/loongarch/include/asm/pgtable.h   |  7 ++-
 arch/loongarch/include/asm/sparsemem.h |  6 +++
 arch/loongarch/mm/init.c               | 72 ++++++++++++++++++++++++--
 include/linux/mm.h                     |  2 +
 mm/sparse-vmemmap.c                    | 10 ++++
 6 files changed, 94 insertions(+), 4 deletions(-)
  

Comments

kernel test robot Oct. 19, 2022, 3:33 a.m. UTC | #1
Hi Huacai,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Huacai-Chen/mm-sparse-vmemmap-Generalise-helpers-and-enable-for-LoongArch/20221017-125816
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20221017024027.2389370-3-chenhuacai%40loongson.cn
patch subject: [PATCH V11 2/4] LoongArch: Add sparse memory vmemmap support
config: loongarch-randconfig-r015-20221017
compiler: loongarch64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/87c61ad70fe14588eea5f838b62863859b0f119b
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Huacai-Chen/mm-sparse-vmemmap-Generalise-helpers-and-enable-for-LoongArch/20221017-125816
        git checkout 87c61ad70fe14588eea5f838b62863859b0f119b
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=loongarch SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/loongarch/include/asm/uaccess.h:17,
                    from include/linux/uaccess.h:11,
                    from include/linux/sched/task.h:11,
                    from include/linux/sched/signal.h:9,
                    from include/linux/rcuwait.h:6,
                    from include/linux/percpu-rwsem.h:7,
                    from include/linux/fs.h:33,
                    from arch/loongarch/include/asm/elf.h:9,
                    from include/linux/elf.h:6,
                    from include/linux/module.h:19,
                    from include/linux/moduleloader.h:6,
                    from kernel/module/main.c:11:
   kernel/module/main.c: In function 'module_alloc':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   kernel/module/main.c:1612:61: note: in expansion of macro 'VMALLOC_END'
    1612 |         return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
         |                                                             ^~~~~~~~~~~
   arch/loongarch/include/asm/pgtable.h:91:119: note: each undeclared identifier is reported only once for each function it appears in
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   kernel/module/main.c:1612:61: note: in expansion of macro 'VMALLOC_END'
    1612 |         return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
         |                                                             ^~~~~~~~~~~
   kernel/module/main.c:1615:1: error: control reaches end of non-void function [-Werror=return-type]
    1615 | }
         | ^
   cc1: some warnings being treated as errors
--
   fs/proc/meminfo.c:22:28: warning: no previous prototype for 'arch_report_meminfo' [-Wmissing-prototypes]
      22 | void __attribute__((weak)) arch_report_meminfo(struct seq_file *m)
         |                            ^~~~~~~~~~~~~~~~~~~
   In file included from arch/loongarch/include/asm/uaccess.h:17,
                    from include/linux/uaccess.h:11,
                    from include/linux/sched/task.h:11,
                    from include/linux/sched/signal.h:9,
                    from include/linux/rcuwait.h:6,
                    from include/linux/percpu-rwsem.h:7,
                    from include/linux/fs.h:33,
                    from fs/proc/meminfo.c:2:
   fs/proc/meminfo.c: In function 'meminfo_proc_show':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   include/linux/vmalloc.h:286:24: note: in expansion of macro 'VMALLOC_END'
     286 | #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
         |                        ^~~~~~~~~~~
   fs/proc/meminfo.c:129:35: note: in expansion of macro 'VMALLOC_TOTAL'
     129 |                    (unsigned long)VMALLOC_TOTAL >> 10);
         |                                   ^~~~~~~~~~~~~
   arch/loongarch/include/asm/pgtable.h:91:119: note: each undeclared identifier is reported only once for each function it appears in
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   include/linux/vmalloc.h:286:24: note: in expansion of macro 'VMALLOC_END'
     286 | #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
         |                        ^~~~~~~~~~~
   fs/proc/meminfo.c:129:35: note: in expansion of macro 'VMALLOC_TOTAL'
     129 |                    (unsigned long)VMALLOC_TOTAL >> 10);
         |                                   ^~~~~~~~~~~~~
--
   In file included from arch/loongarch/include/asm/uaccess.h:17,
                    from include/linux/uaccess.h:11,
                    from include/linux/sched/task.h:11,
                    from include/linux/sched/signal.h:9,
                    from include/linux/ptrace.h:7,
                    from include/linux/elfcore.h:11,
                    from include/linux/crash_core.h:6,
                    from fs/proc/kcore.c:13:
   fs/proc/kcore.c: In function 'add_modules_range':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   fs/proc/kcore.c:671:62: note: in expansion of macro 'VMALLOC_END'
     671 |         if (MODULES_VADDR != VMALLOC_START && MODULES_END != VMALLOC_END) {
         |                                                              ^~~~~~~~~~~
   arch/loongarch/include/asm/pgtable.h:91:119: note: each undeclared identifier is reported only once for each function it appears in
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   fs/proc/kcore.c:671:62: note: in expansion of macro 'VMALLOC_END'
     671 |         if (MODULES_VADDR != VMALLOC_START && MODULES_END != VMALLOC_END) {
         |                                                              ^~~~~~~~~~~
   fs/proc/kcore.c: In function 'proc_kcore_init':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   fs/proc/kcore.c:693:17: note: in expansion of macro 'VMALLOC_END'
     693 |                 VMALLOC_END - VMALLOC_START, KCORE_VMALLOC);
         |                 ^~~~~~~~~~~
--
   In file included from include/linux/pgtable.h:6,
                    from include/linux/mm.h:29,
                    from mm/util.c:2:
   mm/util.c: In function 'kvmalloc_node':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/util.c:606:61: note: in expansion of macro 'VMALLOC_END'
     606 |         return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
         |                                                             ^~~~~~~~~~~
   arch/loongarch/include/asm/pgtable.h:91:119: note: each undeclared identifier is reported only once for each function it appears in
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/util.c:606:61: note: in expansion of macro 'VMALLOC_END'
     606 |         return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
         |                                                             ^~~~~~~~~~~
   mm/util.c:609:1: error: control reaches end of non-void function [-Werror=return-type]
     609 | }
         | ^
   cc1: some warnings being treated as errors
--
   In file included from include/linux/pgtable.h:6,
                    from include/linux/mm.h:29,
                    from include/linux/memblock.h:12,
                    from mm/percpu.c:73:
   mm/percpu.c: In function 'pcpu_embed_first_chunk':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   include/linux/vmalloc.h:286:24: note: in expansion of macro 'VMALLOC_END'
     286 | #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
         |                        ^~~~~~~~~~~
   mm/percpu.c:3118:28: note: in expansion of macro 'VMALLOC_TOTAL'
    3118 |         if (max_distance > VMALLOC_TOTAL * 3 / 4) {
         |                            ^~~~~~~~~~~~~
   arch/loongarch/include/asm/pgtable.h:91:119: note: each undeclared identifier is reported only once for each function it appears in
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   include/linux/vmalloc.h:286:24: note: in expansion of macro 'VMALLOC_END'
     286 | #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
         |                        ^~~~~~~~~~~
   mm/percpu.c:3118:28: note: in expansion of macro 'VMALLOC_TOTAL'
    3118 |         if (max_distance > VMALLOC_TOTAL * 3 / 4) {
         |                            ^~~~~~~~~~~~~
--
   In file included from include/linux/pgtable.h:6,
                    from include/linux/mm.h:29,
                    from mm/vmalloc.c:12:
   mm/vmalloc.c: In function 'is_vmalloc_addr':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:79:48: note: in expansion of macro 'VMALLOC_END'
      79 |         return addr >= VMALLOC_START && addr < VMALLOC_END;
         |                                                ^~~~~~~~~~~
   arch/loongarch/include/asm/pgtable.h:91:119: note: each undeclared identifier is reported only once for each function it appears in
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:79:48: note: in expansion of macro 'VMALLOC_END'
      79 |         return addr >= VMALLOC_START && addr < VMALLOC_END;
         |                                                ^~~~~~~~~~~
   mm/vmalloc.c: In function 'new_vmap_block':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:1963:56: note: in expansion of macro 'VMALLOC_END'
    1963 |                                         VMALLOC_START, VMALLOC_END,
         |                                                        ^~~~~~~~~~~
   In file included from include/linux/build_bug.h:5,
                    from include/linux/container_of.h:5,
                    from include/linux/list.h:5,
                    from include/linux/preempt.h:11,
                    from include/linux/spinlock.h:56,
                    from include/linux/vmalloc.h:5,
                    from mm/vmalloc.c:11:
   mm/vmalloc.c: In function 'vm_unmap_ram':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   include/linux/compiler.h:78:45: note: in definition of macro 'unlikely'
      78 | # define unlikely(x)    __builtin_expect(!!(x), 0)
         |                                             ^
   mm/vmalloc.c:2214:9: note: in expansion of macro 'BUG_ON'
    2214 |         BUG_ON(addr > VMALLOC_END);
         |         ^~~~~~
   mm/vmalloc.c:2214:23: note: in expansion of macro 'VMALLOC_END'
    2214 |         BUG_ON(addr > VMALLOC_END);
         |                       ^~~~~~~~~~~
   mm/vmalloc.c: In function 'vm_map_ram':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:2261:48: note: in expansion of macro 'VMALLOC_END'
    2261 |                                 VMALLOC_START, VMALLOC_END, node, GFP_KERNEL);
         |                                                ^~~~~~~~~~~
   mm/vmalloc.c: In function 'vm_area_register_early':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   include/linux/compiler.h:78:45: note: in definition of macro 'unlikely'
      78 | # define unlikely(x)    __builtin_expect(!!(x), 0)
         |                                             ^
   mm/vmalloc.c:2357:9: note: in expansion of macro 'BUG_ON'
    2357 |         BUG_ON(addr > VMALLOC_END - vm->size);
         |         ^~~~~~
   mm/vmalloc.c:2357:23: note: in expansion of macro 'VMALLOC_END'
    2357 |         BUG_ON(addr > VMALLOC_END - vm->size);
         |                       ^~~~~~~~~~~
   mm/vmalloc.c: In function 'get_vm_area':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:2546:50: note: in expansion of macro 'VMALLOC_END'
    2546 |                                   VMALLOC_START, VMALLOC_END,
         |                                                  ^~~~~~~~~~~
   mm/vmalloc.c: In function 'get_vm_area_caller':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:2555:50: note: in expansion of macro 'VMALLOC_END'
    2555 |                                   VMALLOC_START, VMALLOC_END,
         |                                                  ^~~~~~~~~~~
   mm/vmalloc.c: In function '__vmalloc_node':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:3278:65: note: in expansion of macro 'VMALLOC_END'
    3278 |         return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END,
         |                                                                 ^~~~~~~~~~~
   mm/vmalloc.c: In function 'vmalloc_huge':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:3330:61: note: in expansion of macro 'VMALLOC_END'
    3330 |         return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
         |                                                             ^~~~~~~~~~~
   mm/vmalloc.c: In function 'vmalloc_user':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:3367:67: note: in expansion of macro 'VMALLOC_END'
    3367 |         return __vmalloc_node_range(size, SHMLBA,  VMALLOC_START, VMALLOC_END,
         |                                                                   ^~~~~~~~~~~
   mm/vmalloc.c: In function 'vmalloc_32_user':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:3451:67: note: in expansion of macro 'VMALLOC_END'
    3451 |         return __vmalloc_node_range(size, SHMLBA,  VMALLOC_START, VMALLOC_END,
         |                                                                   ^~~~~~~~~~~
   mm/vmalloc.c: In function 'pvm_determine_end_from_reverse':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:3736:37: note: in expansion of macro 'VMALLOC_END'
    3736 |         unsigned long vmalloc_end = VMALLOC_END & ~(align - 1);
         |                                     ^~~~~~~~~~~
   mm/vmalloc.c: In function 'pcpu_get_vm_areas':
>> arch/loongarch/include/asm/pgtable.h:91:119: error: 'VMEMMAP_SIZE' undeclared (first use in this function); did you mean 'VMEMMAP_END'?
      91 |          min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
         |                                                                                                                       ^~~~~~~~~~~~
   mm/vmalloc.c:3780:43: note: in expansion of macro 'VMALLOC_END'
    3780 |         const unsigned long vmalloc_end = VMALLOC_END & ~(align - 1);
         |                                           ^~~~~~~~~~~
   mm/vmalloc.c: In function 'is_vmalloc_addr':
   mm/vmalloc.c:80:1: error: control reaches end of non-void function [-Werror=return-type]
      80 | }
         | ^
   mm/vmalloc.c: In function 'get_vm_area':
   mm/vmalloc.c:2549:1: error: control reaches end of non-void function [-Werror=return-type]
    2549 | }
         | ^
   mm/vmalloc.c: In function 'get_vm_area_caller':
   mm/vmalloc.c:2557:1: error: control reaches end of non-void function [-Werror=return-type]
    2557 | }
         | ^
   mm/vmalloc.c: In function '__vmalloc_node':
   mm/vmalloc.c:3280:1: error: control reaches end of non-void function [-Werror=return-type]
    3280 | }
         | ^
   mm/vmalloc.c: In function 'vmalloc_huge':
   mm/vmalloc.c:3333:1: error: control reaches end of non-void function [-Werror=return-type]
    3333 | }
         | ^
   mm/vmalloc.c: In function 'vmalloc_user':
   mm/vmalloc.c:3371:1: error: control reaches end of non-void function [-Werror=return-type]
    3371 | }
         | ^
   mm/vmalloc.c: In function 'vmalloc_32_user':
   mm/vmalloc.c:3455:1: error: control reaches end of non-void function [-Werror=return-type]
    3455 | }
         | ^
   cc1: some warnings being treated as errors


vim +91 arch/loongarch/include/asm/pgtable.h

    87	
    88	#define VMALLOC_START	MODULES_END
    89	#define VMALLOC_END	\
    90		(vm_map_base +	\
  > 91		 min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
    92
  

Patch

diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 903096bd87f8..6f7fa0c0ca08 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -487,6 +487,7 @@  config ARCH_FLATMEM_ENABLE
 
 config ARCH_SPARSEMEM_ENABLE
 	def_bool y
+	select SPARSEMEM_VMEMMAP_ENABLE
 	help
 	  Say Y to support efficient handling of sparse physical memory,
 	  for architectures which are either NUMA (Non-Uniform Memory Access)
diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
index 72eb8bc352fb..2e635dca2420 100644
--- a/arch/loongarch/include/asm/pgtable.h
+++ b/arch/loongarch/include/asm/pgtable.h
@@ -11,6 +11,7 @@ 
 
 #include <linux/compiler.h>
 #include <asm/addrspace.h>
+#include <asm/page.h>
 #include <asm/pgtable-bits.h>
 
 #if CONFIG_PGTABLE_LEVELS == 2
@@ -59,6 +60,7 @@ 
 #include <linux/mm_types.h>
 #include <linux/mmzone.h>
 #include <asm/fixmap.h>
+#include <asm/sparsemem.h>
 
 struct mm_struct;
 struct vm_area_struct;
@@ -86,7 +88,10 @@  extern unsigned long zero_page_mask;
 #define VMALLOC_START	MODULES_END
 #define VMALLOC_END	\
 	(vm_map_base +	\
-	 min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE)
+	 min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, (1UL << cpu_vabits)) - PMD_SIZE - VMEMMAP_SIZE)
+
+#define vmemmap		((struct page *)((VMALLOC_END + PMD_SIZE) & PMD_MASK))
+#define VMEMMAP_END	((unsigned long)vmemmap + VMEMMAP_SIZE - 1)
 
 #define pte_ERROR(e) \
 	pr_err("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
diff --git a/arch/loongarch/include/asm/sparsemem.h b/arch/loongarch/include/asm/sparsemem.h
index 3d18cdf1b069..ee55cdf933c6 100644
--- a/arch/loongarch/include/asm/sparsemem.h
+++ b/arch/loongarch/include/asm/sparsemem.h
@@ -11,6 +11,12 @@ 
 #define SECTION_SIZE_BITS	29 /* 2^29 = Largest Huge Page Size */
 #define MAX_PHYSMEM_BITS	48
 
+#ifndef CONFIG_SPARSEMEM_VMEMMAP
+#define VMEMMAP_SIZE	0
+#else
+#define VMEMMAP_SIZE	(sizeof(struct page) * (1UL << (cpu_pabits + 1 - PAGE_SHIFT)))
+#endif
+
 #endif /* CONFIG_SPARSEMEM */
 
 #ifdef CONFIG_MEMORY_HOTPLUG
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index 080061793c85..451d93667bcc 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -22,7 +22,7 @@ 
 #include <linux/pfn.h>
 #include <linux/hardirq.h>
 #include <linux/gfp.h>
-#include <linux/initrd.h>
+#include <linux/hugetlb.h>
 #include <linux/mmzone.h>
 
 #include <asm/asm-offsets.h>
@@ -152,6 +152,72 @@  EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 #endif
 #endif
 
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+static int __meminit vmemmap_populate_hugepages(unsigned long start, unsigned long end,
+						int node, struct vmem_altmap *altmap)
+{
+	unsigned long addr = start;
+	unsigned long next;
+	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
+	pmd_t *pmd;
+
+	for (addr = start; addr < end; addr = next) {
+		next = pmd_addr_end(addr, end);
+
+		pgd = vmemmap_pgd_populate(addr, node);
+		if (!pgd)
+			return -ENOMEM;
+		p4d = vmemmap_p4d_populate(pgd, addr, node);
+		if (!p4d)
+			return -ENOMEM;
+		pud = vmemmap_pud_populate(p4d, addr, node);
+		if (!pud)
+			return -ENOMEM;
+
+		pmd = pmd_offset(pud, addr);
+		if (pmd_none(*pmd)) {
+			void *p = NULL;
+
+			p = vmemmap_alloc_block_buf(PMD_SIZE, node, NULL);
+			if (p) {
+				pmd_t entry;
+
+				entry = pfn_pmd(virt_to_pfn(p), PAGE_KERNEL);
+				pmd_val(entry) |= _PAGE_HUGE | _PAGE_HGLOBAL;
+				set_pmd_at(&init_mm, addr, pmd, entry);
+
+				continue;
+			}
+		} else if (pmd_val(*pmd) & _PAGE_HUGE) {
+			vmemmap_verify((pte_t *)pmd, node, addr, next);
+			continue;
+		}
+		if (vmemmap_populate_basepages(addr, next, node, NULL))
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+int __meminit vmemmap_populate(unsigned long start, unsigned long end,
+			       int node, struct vmem_altmap *altmap)
+{
+#if CONFIG_PGTABLE_LEVELS == 2
+	return vmemmap_populate_basepages(start, end, node, NULL);
+#else
+	return vmemmap_populate_hugepages(start, end, node, NULL);
+#endif
+}
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+void vmemmap_free(unsigned long start, unsigned long end, struct vmem_altmap *altmap)
+{
+}
+#endif
+#endif
+
 static pte_t *fixmap_pte(unsigned long addr)
 {
 	pgd_t *pgd;
@@ -168,7 +234,7 @@  static pte_t *fixmap_pte(unsigned long addr)
 		new = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
 		pgd_populate(&init_mm, pgd, new);
 #ifndef __PAGETABLE_PUD_FOLDED
-		pud_init((unsigned long)new, (unsigned long)invalid_pmd_table);
+		pud_init(new);
 #endif
 	}
 
@@ -179,7 +245,7 @@  static pte_t *fixmap_pte(unsigned long addr)
 		new = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
 		pud_populate(&init_mm, pud, new);
 #ifndef __PAGETABLE_PMD_FOLDED
-		pmd_init((unsigned long)new, (unsigned long)invalid_pte_table);
+		pmd_init(new);
 #endif
 	}
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 8bbcccbc5565..45eb04c43c6b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3233,6 +3233,8 @@  void *sparse_buffer_alloc(unsigned long size);
 struct page * __populate_section_memmap(unsigned long pfn,
 		unsigned long nr_pages, int nid, struct vmem_altmap *altmap,
 		struct dev_pagemap *pgmap);
+void pmd_init(void *addr);
+void pud_init(void *addr);
 pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
 p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node);
 pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node);
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 46ae542118c0..797b30e9050c 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -196,6 +196,10 @@  pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
 	return pmd;
 }
 
+void __weak __meminit pmd_init(void *addr)
+{
+}
+
 pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node)
 {
 	pud_t *pud = pud_offset(p4d, addr);
@@ -203,11 +207,16 @@  pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node)
 		void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
 		if (!p)
 			return NULL;
+		pmd_init(p);
 		pud_populate(&init_mm, pud, p);
 	}
 	return pud;
 }
 
+void __weak __meminit pud_init(void *addr)
+{
+}
+
 p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node)
 {
 	p4d_t *p4d = p4d_offset(pgd, addr);
@@ -215,6 +224,7 @@  p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node)
 		void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
 		if (!p)
 			return NULL;
+		pud_init(p);
 		p4d_populate(&init_mm, p4d, p);
 	}
 	return p4d;