Commit e80d6a24 authored by Mel Gorman's avatar Mel Gorman Committed by Russell King

[ARM] Skip memory holes in FLATMEM when reading /proc/pagetypeinfo

Ordinarily, memory holes in flatmem still have a valid memmap and is safe
to use. However, an architecture (ARM) frees up the memmap backing memory
holes on the assumption it is never used. /proc/pagetypeinfo reads the
whole range of pages in a zone believing that the memmap is valid and that
pfn_valid will return false if it is not. On ARM, freeing the memmap breaks
the page->zone linkages even though pfn_valid() returns true and the kernel
can oops shortly afterwards due to accessing a bogus struct zone *.

This patch lets architectures say when FLATMEM can have holes in the
memmap. Rather than an expensive check for valid memory, /proc/pagetypeinfo
will confirm that the page linkages are still valid by checking page->zone
is still the expected zone. The lookup of page_zone is safe as there is a
limited range of memory that is accessed when calling page_zone.  Even if
page_zone happens to return the correct zone, the impact is that the counters
in /proc/pagetypeinfo are slightly off but fragmentation monitoring is
unlikely to be relevant on an embedded system.
Reported-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: default avatarMel Gorman <mel@csn.ul.ie>
Tested-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent f1bcf7e3
...@@ -810,6 +810,11 @@ config OABI_COMPAT ...@@ -810,6 +810,11 @@ config OABI_COMPAT
UNPREDICTABLE (in fact it can be predicted that it won't work UNPREDICTABLE (in fact it can be predicted that it won't work
at all). If in doubt say Y. at all). If in doubt say Y.
config ARCH_FLATMEM_HAS_HOLES
bool
default y
depends on FLATMEM
config ARCH_DISCONTIGMEM_ENABLE config ARCH_DISCONTIGMEM_ENABLE
bool bool
default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
......
...@@ -516,9 +516,26 @@ static void pagetypeinfo_showblockcount_print(struct seq_file *m, ...@@ -516,9 +516,26 @@ static void pagetypeinfo_showblockcount_print(struct seq_file *m,
continue; continue;
page = pfn_to_page(pfn); page = pfn_to_page(pfn);
#ifdef CONFIG_ARCH_FLATMEM_HAS_HOLES
/*
* Ordinarily, memory holes in flatmem still have a valid
* memmap for the PFN range. However, an architecture for
* embedded systems (e.g. ARM) can free up the memmap backing
* holes to save memory on the assumption the memmap is
* never used. The page_zone linkages are then broken even
* though pfn_valid() returns true. Skip the page if the
* linkages are broken. Even if this test passed, the impact
* is that the counters for the movable type are off but
* fragmentation monitoring is likely meaningless on small
* systems.
*/
if (page_zone(page) != zone)
continue;
#endif
mtype = get_pageblock_migratetype(page); mtype = get_pageblock_migratetype(page);
count[mtype]++; if (mtype < MIGRATE_TYPES)
count[mtype]++;
} }
/* Print counts */ /* Print counts */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment