Stable Archive on
 help / color / Atom feed
* + mm-page_alloc-move_freepages-should-not-examine-struct-page-of-reserved-memory.patch added to -mm tree
@ 2019-08-13 21:39 akpm
  0 siblings, 0 replies; only message in thread
From: akpm @ 2019-08-13 21:39 UTC (permalink / raw)
  To: mm-commits, vbabka, stable, pavel.tatashin, osalvador,
	n-horiguchi, m.mizuma, mgorman, rientjes

The patch titled
     Subject: mm, page_alloc: move_freepages should not examine struct page of reserved memory
has been added to the -mm tree.  Its filename is

This patch should soon appear at
and later at

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next and is updated
there every 3-4 working days

From: David Rientjes <>
Subject: mm, page_alloc: move_freepages should not examine struct page of reserved memory

After commit 907ec5fca3dc ("mm: zero remaining unavailable struct pages"),
struct page of reserved memory is zeroed.  This causes page->flags to be 0
and fixes issues related to reading /proc/kpageflags, for example, of
reserved memory.

The VM_BUG_ON() in move_freepages_block(), however, assumes that
page_zone() is meaningful even for reserved memory.  That assumption is no
longer true after the aforementioned commit.

There's no reason why move_freepages_block() should be testing the
legitimacy of page_zone() for reserved memory; its scope is limited only
to pages on the zone's freelist.

Note that pfn_valid() can be true for reserved memory: there is a backing
struct page.  The check for page_to_nid(page) is also buggy but reserved
memory normally only appears on node 0 so the zeroing doesn't affect this.

Move the debug checks to after verifying PageBuddy is true.  This isolates
the scope of the checks to only be for buddy pages which are on the zone's
freelist which move_freepages_block() is operating on.  In this case, an
incorrect node or zone is a bug worthy of being warned about (and the
examination of struct page is acceptable bcause this memory is not

Why does move_freepages_block() gets called on reserved memory?  It's
simply math after finding a valid free page from the per-zone free area to
use as fallback.  We find the beginning and end of the pageblock of the
valid page and that can bring us into memory that was reserved per the
e820.  pfn_valid() is still true (it's backed by a struct page), but since
it's zero'd we shouldn't make any inferences here about comparing its node
or zone.  The current node check just happens to succeed most of the time
by luck because reserved memory typically appears on node 0.

The fix here is to validate that we actually have buddy pages before
testing if there's any type of zone or node strangeness going on.

Fixes: 907ec5fca3dc ("mm: zero remaining unavailable struct pages")
Signed-off-by: David Rientjes <>
Cc: Naoya Horiguchi <>
Cc: Masayoshi Mizuma <>
Cc: Oscar Salvador <>
Cc: Pavel Tatashin <>
Cc: Vlastimil Babka <>
Cc: Naoya Horiguchi <>
Cc: Mel Gorman <>
Cc: <>
Signed-off-by: Andrew Morton <>

 mm/page_alloc.c |   19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

--- a/mm/page_alloc.c~mm-page_alloc-move_freepages-should-not-examine-struct-page-of-reserved-memory
+++ a/mm/page_alloc.c
@@ -2238,27 +2238,12 @@ static int move_freepages(struct zone *z
 	unsigned int order;
 	int pages_moved = 0;
-	/*
-	 * page_zone is not safe to call in this context when
-	 * CONFIG_HOLES_IN_ZONE is set. This bug check is probably redundant
-	 * anyway as we check zone boundaries in move_freepages_block().
-	 * Remove at a later date when no bug reports exist related to
-	 * grouping pages by mobility
-	 */
-	VM_BUG_ON(pfn_valid(page_to_pfn(start_page)) &&
-	          pfn_valid(page_to_pfn(end_page)) &&
-	          page_zone(start_page) != page_zone(end_page));
 	for (page = start_page; page <= end_page;) {
 		if (!pfn_valid_within(page_to_pfn(page))) {
-		/* Make sure we are not inadvertently changing nodes */
-		VM_BUG_ON_PAGE(page_to_nid(page) != zone_to_nid(zone), page);
 		if (!PageBuddy(page)) {
 			 * We assume that pages that could be isolated for
@@ -2273,6 +2258,10 @@ static int move_freepages(struct zone *z
+		/* Make sure we are not inadvertently changing nodes */
+		VM_BUG_ON_PAGE(page_to_nid(page) != zone_to_nid(zone), page);
+		VM_BUG_ON_PAGE(page_zone(page) != zone, page);
 		order = page_order(page);
 		move_to_free_area(page, &zone->free_area[order], migratetype);
 		page += 1 << order;

Patches currently in -mm which might be from are


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-13 21:39 + mm-page_alloc-move_freepages-should-not-examine-struct-page-of-reserved-memory.patch added to -mm tree akpm

Stable Archive on

Archives are clonable:
	git clone --mirror stable/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 stable stable/ \
	public-inbox-index stable

Newsgroup available over NNTP:

AGPL code for this site: git clone public-inbox