Skip to contentSkip to conversation

mm/page_alloc: fix memory map initialization for descending nodes

PATCH In review Mike Rapoport 2 participants 3 messages Jun 24, 2021 – Jun 25, 2021

Subsystems (3)
lore
Share & tools
lore

Mike Rapoport

author reviewer
#0 lore raw

PATCH 1/1 mm/page_alloc: fix memory map initialization for descending nodes

From: Mike Rapoport <[email protected]>

On systems with memory nodes sorted in descending order, for instance Dell Precision WorkStation T5500, the struct pages for higher PFNs and respectively lower nodes, could be overwritten by the initialization of struct pages corresponding to the holes in the memory sections.

For example for the below memory layout

[    0.245624] Early memory node ranges
[    0.248496]   node   1: [mem 0x0000000000001000-0x0000000000090fff]
[    0.251376]   node   1: [mem 0x0000000000100000-0x00000000dbdf8fff]
[    0.254256]   node   1: [mem 0x0000000100000000-0x0000001423ffffff]
[    0.257144]   node   0: [mem 0x0000001424000000-0x0000002023ffffff]

the range 0x1424000000 - 0x1428000000 in the beginning of node 0 starts in the middle of a section and will be considered as a hole during the initialization of the last section in node 1.

Reorder order of the memory map initialization so that the outer loop will always iterate over populated memory regions in the ascending order and the inner loop will select the zone corresponding to the PFN range.

This way initialization of the struct pages for the memory holes will be always done for the ranges that are actually not populated.

Fixes 0740a50b9baa ("mm/page_alloc.c: refactor initialization of struct page for holes in memory layout")
---
 include/linux/mm.h |  1 -
 mm/page_alloc.c    | 94 ++++++++++++++++++++++++++++------------------
 2 files changed, 58 insertions(+), 37 deletions(-)
include/linux/mm.h +0 -1
index 8ae31622deef..9afb8998e7e5 100644
@@ -2474,7 +2474,6 @@ extern void set_dma_reserve(unsigned long new_dma_reserve);
 extern void memmap_init_range(unsigned long, int, unsigned long,
 		unsigned long, unsigned long, enum meminit_context,
 		struct vmem_altmap *, int migratetype);
-extern void memmap_init_zone(struct zone *zone);
 extern void setup_per_zone_wmarks(void);
 extern int __meminit init_per_zone_wmark_min(void);
 extern void mem_init(void);
mm/page_alloc.c +58 -36

150 lines not on this page · raw message

Signature · 1 line
2.28.0
maintainer
#1 lore raw
Quoted 19 lines · On Thu, 24 Jun 2021 09:23:05 +0300 Mike Rapoport <[email protected]> wrote:

From: Mike Rapoport <[email protected]>

On systems with memory nodes sorted in descending order, for instance Dell Precision WorkStation T5500, the struct pages for higher PFNs and respectively lower nodes, could be overwritten by the initialization of struct pages corresponding to the holes in the memory sections.

For example for the below memory layout

[    0.245624] Early memory node ranges
[    0.248496]   node   1: [mem 0x0000000000001000-0x0000000000090fff]
[    0.251376]   node   1: [mem 0x0000000000100000-0x00000000dbdf8fff]
[    0.254256]   node   1: [mem 0x0000000100000000-0x0000001423ffffff]
[    0.257144]   node   0: [mem 0x0000001424000000-0x0000002023ffffff]

the range 0x1424000000 - 0x1428000000 in the beginning of node 0 starts in the middle of a section and will be considered as a hole during the initialization of the last section in node 1.

Quoted 6 lines

Reorder order of the memory map initialization so that the outer loop will always iterate over populated memory regions in the ascending order and the inner loop will select the zone corresponding to the PFN range.

This way initialization of the struct pages for the memory holes will be always done for the ranges that are actually not populated.

Changelog doesn't tell us what are the user-visible effects of the bug.

Quoted 1 line

But that does. Panic during boot.

Quoted 2 lines
Fixes 0740a50b9baa ("mm/page_alloc.c: refactor initialization of struct page for holes in memory layout")

So I think we want a cc:stable here?

author reviewer
#2 lore raw
Quoted 25 lines · Andrew Morton
Quoted 23 lines · On Thu, 24 Jun 2021 09:23:05 +0300 Mike Rapoport <[email protected]> wrote:

From: Mike Rapoport <[email protected]>

On systems with memory nodes sorted in descending order, for instance Dell Precision WorkStation T5500, the struct pages for higher PFNs and respectively lower nodes, could be overwritten by the initialization of struct pages corresponding to the holes in the memory sections.

For example for the below memory layout

[    0.245624] Early memory node ranges
[    0.248496]   node   1: [mem 0x0000000000001000-0x0000000000090fff]
[    0.251376]   node   1: [mem 0x0000000000100000-0x00000000dbdf8fff]
[    0.254256]   node   1: [mem 0x0000000100000000-0x0000001423ffffff]
[    0.257144]   node   0: [mem 0x0000001424000000-0x0000002023ffffff]

the range 0x1424000000 - 0x1428000000 in the beginning of node 0 starts in the middle of a section and will be considered as a hole during the initialization of the last section in node 1.

Reorder order of the memory map initialization so that the outer loop will always iterate over populated memory regions in the ascending order and the inner loop will select the zone corresponding to the PFN range.

Quoted 8 lines
Quoted 2 lines

This way initialization of the struct pages for the memory holes will be always done for the ranges that are actually not populated.

Changelog doesn't tell us what are the user-visible effects of the bug.

Quoted 1 line

But that does. Panic during boot.

Below is v2 with a sentence about the panic added to the changelog, and the fix of "is is" typo.

Quoted 4 lines
Quoted 2 lines
Fixes 0740a50b9baa ("mm/page_alloc.c: refactor initialization of struct page for holes in memory layout")

So I think we want a cc:stable here?

Right, I've added cc:stable to the patch. Considering how close we are to the merge window I think this is anyway v5.14 material.

From bec1b8fe385487928b4be720dc2ac88af7d36e74 Mon Sep 17 00:00:00 2001
From: Mike Rapoport <[email protected]>
Date: Wed, 23 Jun 2021 09:24:01 +0300
Subject: [PATCH v2] mm/page_alloc: fix memory map initialization for
descending nodes

On systems with memory nodes sorted in descending order, for instance Dell Precision WorkStation T5500, the struct pages for higher PFNs and respectively lower nodes, could be overwritten by the initialization of struct pages corresponding to the holes in the memory sections.

For example for the below memory layout

[    0.245624] Early memory node ranges
[    0.248496]   node   1: [mem 0x0000000000001000-0x0000000000090fff]
[    0.251376]   node   1: [mem 0x0000000000100000-0x00000000dbdf8fff]
[    0.254256]   node   1: [mem 0x0000000100000000-0x0000001423ffffff]
[    0.257144]   node   0: [mem 0x0000001424000000-0x0000002023ffffff]

the range 0x1424000000 - 0x1428000000 in the beginning of node 0 starts in the middle of a section and will be considered as a hole during the initialization of the last section in node 1.

The wrong initialization of the memory map causes panic on boot when CONFIG_DEBUG_VM is enabled.

Reorder loop order of the memory map initialization so that the outer loop will always iterate over populated memory regions in the ascending order and the inner loop will select the zone corresponding to the PFN range.

This way initialization of the struct pages for the memory holes will be always done for the ranges that are actually not populated.

Fixes 0740a50b9baa ("mm/page_alloc.c: refactor initialization of struct page for holes in memory layout")
---
 include/linux/mm.h |  1 -
 mm/page_alloc.c    | 94 ++++++++++++++++++++++++++++------------------
 2 files changed, 58 insertions(+), 37 deletions(-)
include/linux/mm.h +0 -1
index 8ae31622deef..9afb8998e7e5 100644
@@ -2474,7 +2474,6 @@ extern void set_dma_reserve(unsigned long new_dma_reserve);
 extern void memmap_init_range(unsigned long, int, unsigned long,
 		unsigned long, unsigned long, enum meminit_context,
 		struct vmem_altmap *, int migratetype);
-extern void memmap_init_zone(struct zone *zone);
 extern void setup_per_zone_wmarks(void);
 extern int __meminit init_per_zone_wmark_min(void);
 extern void mem_init(void);
mm/page_alloc.c +58 -36

150 lines not on this page · raw message

Signature · 7 lines
2.28.0

 

-- 
Sincerely yours,
Mike.