mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH] LoongArch: mm: avoid backing vmemmap beyond max_pfn
@ 2026-10-21  6:21 Wentao Guan
  2026-10-21  7:23 ` Muchun Song
  0 siblings, 1 reply; 3+ messages in thread
From: Wentao Guan @ 2026-10-21  6:21 UTC (permalink / raw)
  To: chenhuacai
  Cc: kernel, loongarch, linux-kernel, linux-mm, akpm, rppt, david,
	muchun.song, Wentao Guan

A PMD maps 32MiB of vmemmap on LoongArch with 16KiB base pages, while a
512MiB section only needs 2MiB.  vmemmap_populate() is called for each
section and vmemmap_populate_hugepages() installs a PMD mapping for the
whole PMD, so the last PMD also backs struct pages for PFNs beyond
max_pfn.

On a 34GiB system 160MiB of vmemmap is mapped although 136MiB is
needed.  The extra 24MiB describes PFNs that do not exist.

Other architectures handle this differently.  On x86, arm64 with 4KiB
pages, and riscv, the PMD covers exactly one section's vmemmap, so the
huge page path never maps beyond the populated range; x86 tracks
partially used PMDs with PAGE_UNUSED for memory hotremove.  arm64 uses
base pages for 16KiB and 64KiB kernels.  s390 deliberately keeps using
1MiB frames even for partially used PMDs because vmemmap_populate() is
called per section and falling back would add page tables.  powerpc
radix falls back to base pages only when the altmap cannot back a full
PMD or the allocation fails, and powerpc hash maps the vmemmap with the
linear mapping page size, which can exceed a section as well.

With 16KiB pages the LoongArch PMD is 16 times the vmemmap of one
section.  Moving the whole vmemmap to base pages, as arm64 does for
16KiB and 64KiB, would also remove the tail, but it would give up PMD
mappings for the 128MiB that is fully populated.  Use base pages only
for the PMD that extends beyond pfn_to_page(max_pfn) and keep huge
mappings for the rest.

The altmap case is left alone because max_pfn does not describe it.

Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
---
 arch/loongarch/mm/init.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index 4b46c5d30708d..bb7a17bdb0e51 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -146,6 +146,11 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end,
 #if CONFIG_PGTABLE_LEVELS == 2
 	return vmemmap_populate_basepages(start, end, node, NULL);
 #else
+	unsigned long vmemmap_end = (unsigned long)pfn_to_page(max_pfn);
+
+	if (!altmap && (start & PMD_MASK) + PMD_SIZE > vmemmap_end)
+		return vmemmap_populate_basepages(start, end, node, NULL);
+
 	return vmemmap_populate_hugepages(start, end, node, NULL);
 #endif
 }
-- 
2.39.5


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC PATCH] LoongArch: mm: avoid backing vmemmap beyond max_pfn
  2026-10-21  6:21 [RFC PATCH] LoongArch: mm: avoid backing vmemmap beyond max_pfn Wentao Guan
@ 2026-10-21  7:23 ` Muchun Song
  2026-10-21 10:13   ` Wentao Guan
  0 siblings, 1 reply; 3+ messages in thread
From: Muchun Song @ 2026-10-21  7:23 UTC (permalink / raw)
  To: Wentao Guan
  Cc: chenhuacai, kernel, loongarch, linux-kernel, linux-mm, akpm, rppt, david



> On Oct 21, 2026, at 14:21, Wentao Guan <guanwentao@uniontech.com> wrote:
> 
> A PMD maps 32MiB of vmemmap on LoongArch with 16KiB base pages, while a
> 512MiB section only needs 2MiB.  vmemmap_populate() is called for each
> section and vmemmap_populate_hugepages() installs a PMD mapping for the
> whole PMD, so the last PMD also backs struct pages for PFNs beyond
> max_pfn.
> 
> On a 34GiB system 160MiB of vmemmap is mapped although 136MiB is
> needed.  The extra 24MiB describes PFNs that do not exist.

Your commit messages are very detailed, but I don't really understand the
problem you're trying to solve. What issue did you run into, and what was
the resulting impact?

Thanks,
Muchun

> 
> Other architectures handle this differently.  On x86, arm64 with 4KiB
> pages, and riscv, the PMD covers exactly one section's vmemmap, so the
> huge page path never maps beyond the populated range; x86 tracks
> partially used PMDs with PAGE_UNUSED for memory hotremove.  arm64 uses
> base pages for 16KiB and 64KiB kernels.  s390 deliberately keeps using
> 1MiB frames even for partially used PMDs because vmemmap_populate() is
> called per section and falling back would add page tables.  powerpc
> radix falls back to base pages only when the altmap cannot back a full
> PMD or the allocation fails, and powerpc hash maps the vmemmap with the
> linear mapping page size, which can exceed a section as well.
> 
> With 16KiB pages the LoongArch PMD is 16 times the vmemmap of one
> section.  Moving the whole vmemmap to base pages, as arm64 does for
> 16KiB and 64KiB, would also remove the tail, but it would give up PMD
> mappings for the 128MiB that is fully populated.  Use base pages only
> for the PMD that extends beyond pfn_to_page(max_pfn) and keep huge
> mappings for the rest.
> 
> The altmap case is left alone because max_pfn does not describe it.
> 
> Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
> ---
> arch/loongarch/mm/init.c | 5 +++++
> 1 file changed, 5 insertions(+)
> 
> diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
> index 4b46c5d30708d..bb7a17bdb0e51 100644
> --- a/arch/loongarch/mm/init.c
> +++ b/arch/loongarch/mm/init.c
> @@ -146,6 +146,11 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end,
> #if CONFIG_PGTABLE_LEVELS == 2
> 	return vmemmap_populate_basepages(start, end, node, NULL);
> #else
> + 	unsigned long vmemmap_end = (unsigned long)pfn_to_page(max_pfn);
> +
> + 	if (!altmap && (start & PMD_MASK) + PMD_SIZE > vmemmap_end)
> + 		return vmemmap_populate_basepages(start, end, node, NULL);
> +
> 	return vmemmap_populate_hugepages(start, end, node, NULL);
> #endif
> }
> -- 
> 2.39.5
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC PATCH] LoongArch: mm: avoid backing vmemmap beyond max_pfn
  2026-10-21  7:23 ` Muchun Song
@ 2026-10-21 10:13   ` Wentao Guan
  0 siblings, 0 replies; 3+ messages in thread
From: Wentao Guan @ 2026-10-21 10:13 UTC (permalink / raw)
  To: Muchun Song
  Cc: chenhuacai, WANG Xuerui, loongarch, linux-kernel, linux-mm, akpm,
	rppt, david

> > On Oct 21, 2026, at 14:21, Wentao Guan <guanwentao@uniontech.com> wrote:
> >
> > A PMD maps 32MiB of vmemmap on LoongArch with 16KiB base pages, while a
> > 512MiB section only needs 2MiB.  vmemmap_populate() is called for each
> > section and vmemmap_populate_hugepages() installs a PMD mapping for the
> > whole PMD, so the last PMD also backs struct pages for PFNs beyond
> > max_pfn.
> >
> > On a 34GiB system 160MiB of vmemmap is mapped although 136MiB is
> > needed.  The extra 24MiB describes PFNs that do not exist.
> 
> Your commit messages are very detailed, but I don't really understand the
> problem you're trying to solve. What issue did you run into, and what was
> the resulting impact?
The commit message is misunderstanding, the issue is point to save memory cost,

> > On a 34GiB system 160MiB of vmemmap is mapped although 136MiB is
> > needed.  The extra 24MiB describes PFNs that do not exist.
On a 32GiB system the platform memory map leaves a 2GiB MMIO window
(serial 10080000,ACPI 100d0000,LOON000x... etc,)
below 4GiB and RAM ends at 34GiB, so max_pfn spans 34GiB.  The vmemmap
for that PFN range is 136MiB, but 160MiB is mapped; the extra 24MiB
describes PFNs that do not exist. In 8GB system, the cost is 0.37% (30MB/8GB).

BRs
Wentao Guan

Log:
 cat /proc/iomem 
00200000-0edfffff : System RAM
  00200000-01b6ffff : Kernel code
  01b70000-03c113ff : Kernel data
  03c11400-03d36caf : Kernel bss
  03d36cb0-03d3ffff : Reserved
  03d40000-03f4bfff : Reserved
10080000-100800ff : serial
10080100-100801ff : serial
10080200-100802ff : serial
10080300-100803ff : serial
10090000-10090007 : LOON0004:00
  10090000-10090007 : LOON0004:00 LOON0004:00
10090100-10090107 : LOON0004:01
  10090100-10090107 : LOON0004:01 LOON0004:01
10090200-10090207 : LOON0004:02
  10090200-10090207 : LOON0004:02 LOON0004:02
10090300-10090307 : LOON0004:03
  10090300-10090307 : LOON0004:03 LOON0004:03
10090400-10090407 : LOON0004:04
  10090400-10090407 : LOON0004:04 LOON0004:04
10090500-10090507 : LOON0004:05
  10090500-10090507 : LOON0004:05 LOON0004:05
100a0000-100a000f : LOON0006:00
  100a0000-100a000f : LOON0006:00 LOON0006:00
100a0100-100a010f : LOON0006:01
  100a0100-100a010f : LOON0006:01 LOON0006:01
100a0200-100a020f : LOON0006:02
  100a0200-100a020f : LOON0006:02 LOON0006:02
100a0300-100a030f : LOON0006:03
  100a0300-100a030f : LOON0006:03 LOON0006:03
100d000c-100d0013 : ACPI PM1a_EVT_BLK
100d0014-100d0017 : ACPI PM1a_CNT_BLK
100d0018-100d001b : ACPI PM_TMR
100d0028-100d002f : ACPI GPE0_BLK
100d0100-100d01ff : LOON0001:00
  100d0100-100d01ff : LOON0001:00 LOON0001:00
100e0000-100e0bff : LOON0002:00
  100e0000-100e0bff : LOON0002:00 LOON0002:00
1fe001e0-1fe001e7 : serial
90400000-f9b7ffff : System RAM
  ea4f0000-f7a9ffff : Reserved
  f9acc000-f9acffff : Reserved
  f9b00000-f9b7ffff : Reserved
f9b90000-fdabffff : System RAM
  f9b90000-f9bbffff : Reserved
fe080000-87fffffff : System RAM
  873800000-874023fff : Reserved
  874400000-874423fff : Reserved
  874800000-874823fff : Reserved
  874c00000-874c23fff : Reserved
  875000000-875023fff : Reserved
  875400000-875423fff : Reserved
  875800000-875823fff : Reserved
  875c00000-875c23fff : Reserved
  876000000-87dffffff : Reserved
  87e240000-87ff93fff : Reserved
  87ff94000-87ff97fff : Reserved
  87ff98000-87ff9bfff : Reserved
  87ff9c000-87ff9ffff : Reserved
  87ffa0000-87ffa3fff : Reserved
  87ffa4000-87ffa7fff : Reserved
  87ffa8000-87ffabfff : Reserved
  87ffac000-87ffaffff : Reserved
  87ffb0000-87ffb3fff : Reserved
  87ffb4000-87ffb7fff : Reserved
  87ffb8000-87ffbbfff : Reserved
  87ffbc000-87ffbffff : Reserved
  87ffc0000-87ffc3fff : Reserved
  87ffc4000-87ffc7fff : Reserved
  87ffc8000-87ffcbfff : Reserved
  87ffcc000-87ffcffff : Reserved
  87ffd0000-87ffd3fff : Reserved
  87ffd4000-87ffd7fff : Reserved
  87ffd8000-87ffdbfff : Reserved
  87ffdc000-87ffdffff : Reserved
  87ffe0000-87ffe3fff : Reserved
  87ffe4000-87ffe7fff : Reserved
  87ffe8000-87ffebfff : Reserved
  87ffec000-87ffeffff : Reserved
  87fff0000-87fff3fff : Reserved
  87fff4000-87fff7fff : Reserved
  87fff8000-87fffbfff : Reserved
  87fffc000-87fffffff : Reserved
e0030000000-e007fffffff : PCI Bus 0000:00
  e0030000000-e00300fffff : PCI Bus 0000:02
    e0030000000-e0030003fff : 0000:02:00.0
    e0030004000-e0030004fff : 0000:02:00.0
      e0030004000-e0030004fff : r8169
  e0030100000-e00301007ff : 0000:00:1a.0
  e0030100800-e0030100bff : 0000:00:08.0
    e0030100800-e0030100bff : ahci
e8000000000-efcffffffff : PCI Bus 0000:00
  e8000000000-e800fffffff : 0000:00:06.0
    e8000000000-e80007ebfff : BOOTFB
      e8000000000-e80007ebfff : simpledrm
  e8010000000-e8013ffffff : 0000:00:1a.0
  e8014000000-e8014ffffff : 0000:00:16.0
  e8015000000-e80150fffff : 0000:00:19.0
    e8015000000-e80150fffff : xhci-hcd
  e8015100000-e801510ffff : 0000:00:06.0
  e8015110000-e801511ffff : 0000:00:06.1
  e8015120000-e801512ffff : 0000:00:06.2
    e8015120000-e801512ffff : ICH HD audio
  e8015130000-e801513ffff : 0000:00:07.0
    e8015130000-e801513ffff : ICH HD audio
  e8015140000-e8015147fff : 0000:00:03.0
    e8015140000-e8015147fff : dwmac-loongson-pci
  e8015148000-e801514ffff : 0000:00:04.0
    e8015148000-e801514ffff : ohci_hcd
  e8015150000-e8015157fff : 0000:00:04.1
    e8015150000-e8015157fff : ehci_hcd
  e8015158000-e801515ffff : 0000:00:05.0
    e8015158000-e801515ffff : ohci_hcd
  e8015160000-e8015167fff : 0000:00:05.1
    e8015160000-e8015167fff : ehci_hcd
  e8015168000-e8015168fff : 0000:00:09.0
  e8015169000-e8015169fff : 0000:00:0a.0
  e801516a000-e801516afff : 0000:00:0b.0
  e801516b000-e801516bfff : 0000:00:0c.0
  e801516c000-e801516cfff : 0000:00:0d.0
  e801516d000-e801516dfff : 0000:00:0f.0
  e801516e000-e801516efff : 0000:00:10.0
  e801516f000-e801516ffff : 0000:00:13.0
  e8015170000-e8015170fff : 0000:00:16.0
    e8015170000-e8015170fff : 0000:00:16.0
  e8015171000-e80151713ff : 0000:00:1a.0
  e8015171400-e80151714ff : 0000:00:06.0
efe00000000-efe1fffffff : PCI ECAM

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-21 10:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21  6:21 [RFC PATCH] LoongArch: mm: avoid backing vmemmap beyond max_pfn Wentao Guan
2026-10-21  7:23 ` Muchun Song
2026-10-21 10:13   ` Wentao Guan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®