mm/page_owner: Don't access uninitialized memmaps when reading /proc/pagetypeinfo
Subsystems (2)
PATCH v2 1/1 mm/page_owner: Don't access uninitialized memmaps when reading /proc/pagetypeinfo
From: Qian Cai <[email protected]>
Uninitialized memmaps contain garbage and in the worst case trigger kernel BUGs, especially with CONFIG_PAGE_POISONING. They should not get touched.
For example, when not onlining a memory block that is spanned by a zone and reading /proc/pagetypeinfo with CONFIG_DEBUG_VM_PGFLAGS and CONFIG_PAGE_POISONING, we can trigger a kernel BUG:
:/# echo 1 > /sys/devices/system/memory/memory40/online :/# echo 1 > /sys/devices/system/memory/memory42/online :/# cat /proc/pagetypeinfo > test.file [ 42.489856] page:fffff2c585200000 is uninitialized and poisoned [ 42.489861] raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff [ 42.492235] raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff [ 42.493501] page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) [ 42.494533] There is not page extension available. [ 42.495358] ------------[ cut here ]------------ [ 42.496163] kernel BUG at include/linux/mm.h:1107! [ 42.497069] invalid opcode: 0000 [#1] SMP NOPTI
Please not that this change does not affect ZONE_DEVICE, because pagetypeinfo_showmixedcount_print() is called from mm/vmstat.c:pagetypeinfo_showmixedcount() only for populated zones, and ZONE_DEVICE is never populated (zone->present_pages always 0).
---
Cai asked me to follow up on:
[PATCH] mm/page_owner: fix a crash after memory offline
--- mm/page_owner.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
mm/page_owner.c +3 -2
@@ -284,7 +284,8 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,* not matter as the mixed block count will still be correct */ for (; pfn < end_pfn; ) { -if (!pfn_valid (pfn)) { + page =pfn_to_online_page (pfn); +if (!page) { pfn =ALIGN (pfn +1 ,MAX_ORDER_NR_PAGES );continue ; }
@@ -292,13 +293,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m, block_end_pfn =ALIGN (pfn +1 , pageblock_nr_pages); block_end_pfn =min (block_end_pfn, end_pfn); - page =pfn_to_page (pfn); pageblock_mt =get_pageblock_migratetype (page);for (; pfn < block_end_pfn; pfn++) {if (!pfn_valid_within (pfn))continue ; +/* The pageblock is online, no need to recheck. */ page =pfn_to_page (pfn);if (page_zone (page) != zone)
Signature · 1 line
2.21.0
Quoted 27 lines · David Hildenbrand
From: Qian Cai <[email protected]>
Uninitialized memmaps contain garbage and in the worst case trigger kernel BUGs, especially with
CONFIG_PAGE_POISONING. They should not get touched.For example, when not onlining a memory block that is spanned by a zone and reading
/proc/pagetypeinfowithCONFIG_DEBUG_VM_PGFLAGSandCONFIG_PAGE_POISONING, we can trigger a kernel BUG::/# echo 1 > /sys/devices/system/memory/memory40/online :/# echo 1 > /sys/devices/system/memory/memory42/online :/# cat /proc/pagetypeinfo > test.file [ 42.489856] page:fffff2c585200000 is uninitialized and poisoned [ 42.489861] raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff [ 42.492235] raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff [ 42.493501] page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) [ 42.494533] There is not page extension available. [ 42.495358] ------------[ cut here ]------------ [ 42.496163] kernel BUG at include/linux/mm.h:1107! [ 42.497069] invalid opcode: 0000 [#1] SMP NOPTIPlease not that this change does not affect
ZONE_DEVICE, becausepagetypeinfo_showmixedcount_print()is called from mm/vmstat.c:pagetypeinfo_showmixedcount() only for populated zones, andZONE_DEVICEis never populated (zone->present_pagesalways 0).
Quoted 13 lines
Fixes f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") # visible after d0dc12e86b319Signed-off-by Qian Cai <[email protected]>Cc Andrew Morton <[email protected]>Cc Vlastimil Babka <[email protected]>Cc Michal Hocko <[email protected]>Cc Thomas Gleixner <[email protected]>Cc "Peter Zijlstra (Intel)" <[email protected]>Cc Miles Chen <[email protected]>Cc Mike Rapoport <[email protected]>Cc Qian Cai <[email protected]>Cc Greg Kroah-Hartman <[email protected]>[ move check to outer loop, add comment, rephrase description ]Signed-off-by David Hildenbrand <[email protected]>
Quoted 39 lines
---
Cai asked me to follow up on:
[PATCH]mm/page_owner: fix a crash after memory offline--- mm/page_owner.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)mm/page_owner.c +3
-2@@ -284,7 +284,8 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,* not matter as the mixed block count will still be correct */ for (; pfn < end_pfn; ) { -if (!pfn_valid (pfn)) { + page =pfn_to_online_page (pfn); +if (!page) { pfn =ALIGN (pfn +1 ,MAX_ORDER_NR_PAGES );continue ; }@@ -292,13 +293,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m, block_end_pfn =ALIGN (pfn +1 , pageblock_nr_pages); block_end_pfn =min (block_end_pfn, end_pfn); - page =pfn_to_page (pfn); pageblock_mt =get_pageblock_migratetype (page);for (; pfn < block_end_pfn; pfn++) {if (!pfn_valid_within (pfn))continue ; +/* The pageblock is online, no need to recheck. */ page =pfn_to_page (pfn);if (page_zone (page) != zone)
Quoted 69 lines · David Hildenbrand
From: Qian Cai <[email protected]>
Uninitialized memmaps contain garbage and in the worst case trigger kernel BUGs, especially with
CONFIG_PAGE_POISONING. They should not get touched.For example, when not onlining a memory block that is spanned by a zone and reading
/proc/pagetypeinfowithCONFIG_DEBUG_VM_PGFLAGSandCONFIG_PAGE_POISONING, we can trigger a kernel BUG::/# echo 1 > /sys/devices/system/memory/memory40/online :/# echo 1 > /sys/devices/system/memory/memory42/online :/# cat /proc/pagetypeinfo > test.file [ 42.489856] page:fffff2c585200000 is uninitialized and poisoned [ 42.489861] raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff [ 42.492235] raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff [ 42.493501] page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) [ 42.494533] There is not page extension available. [ 42.495358] ------------[ cut here ]------------ [ 42.496163] kernel BUG at include/linux/mm.h:1107! [ 42.497069] invalid opcode: 0000 [#1] SMP NOPTIPlease not that this change does not affect
ZONE_DEVICE, becausepagetypeinfo_showmixedcount_print()is called from mm/vmstat.c:pagetypeinfo_showmixedcount() only for populated zones, andZONE_DEVICEis never populated (zone->present_pagesalways 0).Fixes f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") # visible after d0dc12e86b319Signed-off-by Qian Cai <[email protected]>Cc Andrew Morton <[email protected]>Cc Vlastimil Babka <[email protected]>Cc Michal Hocko <[email protected]>Cc Thomas Gleixner <[email protected]>Cc "Peter Zijlstra (Intel)" <[email protected]>Cc Miles Chen <[email protected]>Cc Mike Rapoport <[email protected]>Cc Qian Cai <[email protected]>Cc Greg Kroah-Hartman <[email protected]>[ move check to outer loop, add comment, rephrase description ]Signed-off-by David Hildenbrand <[email protected]>---
Cai asked me to follow up on:
[PATCH]mm/page_owner: fix a crash after memory offline--- mm/page_owner.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)mm/page_owner.c +2
-2@@ -284,7 +284,8 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,* not matter as the mixed block count will still be correct */ for (; pfn < end_pfn; ) { -if (!pfn_valid (pfn)) { + page =pfn_to_online_page (pfn); +if (!page) { pfn =ALIGN (pfn +1 ,MAX_ORDER_NR_PAGES );continue ; }@@ -292,13 +293,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m, block_end_pfn =ALIGN (pfn +1 , pageblock_nr_pages); block_end_pfn =min (block_end_pfn, end_pfn); - page =pfn_to_page (pfn);
mm/page_owner.c void pagetypeinfo_showmixedcount_print(struct seq_file *m, · line 305
Quoted 10 lines
mm/page_owner.c +1
-0pageblock_mt =get_pageblock_migratetype (page);for (; pfn < block_end_pfn; pfn++) {if (!pfn_valid_within (pfn))continue ; +/* The pageblock is online, no need to recheck. */ page =pfn_to_page (pfn);if (page_zone (page) != zone)
I guess it's best to just
here as well. Can be cheery-picked.
@Andrew, can you add that?
Signature · 3 lines
Thanks, David / dhildenb
Quoted 27 lines · David Hildenbrand
From: Qian Cai <[email protected]>
Uninitialized memmaps contain garbage and in the worst case trigger kernel BUGs, especially with
CONFIG_PAGE_POISONING. They should not get touched.For example, when not onlining a memory block that is spanned by a zone and reading
/proc/pagetypeinfowithCONFIG_DEBUG_VM_PGFLAGSandCONFIG_PAGE_POISONING, we can trigger a kernel BUG::/# echo 1 > /sys/devices/system/memory/memory40/online :/# echo 1 > /sys/devices/system/memory/memory42/online :/# cat /proc/pagetypeinfo > test.file [ 42.489856] page:fffff2c585200000 is uninitialized and poisoned [ 42.489861] raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff [ 42.492235] raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff [ 42.493501] page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) [ 42.494533] There is not page extension available. [ 42.495358] ------------[ cut here ]------------ [ 42.496163] kernel BUG at include/linux/mm.h:1107! [ 42.497069] invalid opcode: 0000 [#1] SMP NOPTIPlease not that this change does not affect
ZONE_DEVICE, becausepagetypeinfo_showmixedcount_print()is called from mm/vmstat.c:pagetypeinfo_showmixedcount() only for populated zones, andZONE_DEVICEis never populated (zone->present_pagesalways 0).
Quoted 13 lines
Fixes f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") # visible after d0dc12e86b319Signed-off-by Qian Cai <[email protected]>Cc Andrew Morton <[email protected]>Cc Vlastimil Babka <[email protected]>Cc Michal Hocko <[email protected]>Cc Thomas Gleixner <[email protected]>Cc "Peter Zijlstra (Intel)" <[email protected]>Cc Miles Chen <[email protected]>Cc Mike Rapoport <[email protected]>Cc Qian Cai <[email protected]>Cc Greg Kroah-Hartman <[email protected]>[ move check to outer loop, add comment, rephrase description ]Signed-off-by David Hildenbrand <[email protected]>
Thanks!
Quoted 41 lines
---
Cai asked me to follow up on:
[PATCH]mm/page_owner: fix a crash after memory offline--- mm/page_owner.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)mm/page_owner.c +3
-2@@ -284,7 +284,8 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,* not matter as the mixed block count will still be correct */ for (; pfn < end_pfn; ) { -if (!pfn_valid (pfn)) { + page =pfn_to_online_page (pfn); +if (!page) { pfn =ALIGN (pfn +1 ,MAX_ORDER_NR_PAGES );continue ; }@@ -292,13 +293,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m, block_end_pfn =ALIGN (pfn +1 , pageblock_nr_pages); block_end_pfn =min (block_end_pfn, end_pfn); - page =pfn_to_page (pfn); pageblock_mt =get_pageblock_migratetype (page);for (; pfn < block_end_pfn; pfn++) {if (!pfn_valid_within (pfn))continue ; +/* The pageblock is online, no need to recheck. */ page =pfn_to_page (pfn);if (page_zone (page) != zone)Signature · 1 line
2.21.0
Signature · 2 lines
Michal Hocko SUSE Labs