Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Revert "mm/page_alloc: fix memmap_init_zone pageblock alignment"

This reverts commit 864b75f9d6b0100bb24fdd9a20d156e7cda9b5ae.

Commit 864b75f9d6b0 ("mm/page_alloc: fix memmap_init_zone pageblock
alignment") modified the logic in memmap_init_zone() to initialize
struct pages associated with invalid PFNs, to appease a VM_BUG_ON()
in move_freepages(), which is redundant by its own admission, and
dereferences struct page fields to obtain the zone without checking
whether the struct pages in question are valid to begin with.

Commit 864b75f9d6b0 only makes it worse, since the rounding it does
may cause pfn assume the same value it had in a prior iteration of
the loop, resulting in an infinite loop and a hang very early in the
boot. Also, since it doesn't perform the same rounding on start_pfn
itself but only on intermediate values following an invalid PFN, we
may still hit the same VM_BUG_ON() as before.

So instead, let's fix this at the core, and ensure that the BUG
check doesn't dereference struct page fields of invalid pages.

Fixes: 864b75f9d6b0 ("mm/page_alloc: fix memmap_init_zone pageblock alignment")
Tested-by: Jan Glauber <jglauber@cavium.com>
Tested-by: Shanker Donthineni <shankerd@codeaurora.org>
Cc: Daniel Vacek <neelx@redhat.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Pavel Tatashin <pasha.tatashin@oracle.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ard Biesheuvel and committed by
Linus Torvalds
3e04040d 274a1ff0

+5 -8
+5 -8
mm/page_alloc.c
··· 1910 1910 * Remove at a later date when no bug reports exist related to 1911 1911 * grouping pages by mobility 1912 1912 */ 1913 - VM_BUG_ON(page_zone(start_page) != page_zone(end_page)); 1913 + VM_BUG_ON(pfn_valid(page_to_pfn(start_page)) && 1914 + pfn_valid(page_to_pfn(end_page)) && 1915 + page_zone(start_page) != page_zone(end_page)); 1914 1916 #endif 1915 1917 1916 1918 if (num_movable) ··· 5361 5359 /* 5362 5360 * Skip to the pfn preceding the next valid one (or 5363 5361 * end_pfn), such that we hit a valid pfn (or end_pfn) 5364 - * on our next iteration of the loop. Note that it needs 5365 - * to be pageblock aligned even when the region itself 5366 - * is not. move_freepages_block() can shift ahead of 5367 - * the valid region but still depends on correct page 5368 - * metadata. 5362 + * on our next iteration of the loop. 5369 5363 */ 5370 - pfn = (memblock_next_valid_pfn(pfn, end_pfn) & 5371 - ~(pageblock_nr_pages-1)) - 1; 5364 + pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1; 5372 5365 #endif 5373 5366 continue; 5374 5367 }