diff options
author | Michal Hocko <mhocko@suse.cz> | 2012-01-20 23:33:58 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-23 17:38:47 +0100 |
commit | 656a070629adfe23c12768e35ddf91feab469ff7 (patch) | |
tree | 42c001d079ec926186873b91d7d84bf66c54bcad /mm/page_alloc.c | |
parent | mm: fix NULL ptr dereference in __count_immobile_pages (diff) | |
download | linux-656a070629adfe23c12768e35ddf91feab469ff7.tar.xz linux-656a070629adfe23c12768e35ddf91feab469ff7.zip |
mm: __count_immobile_pages(): make sure the node is online
page_zone() requires an online node otherwise we are accessing NULL
NODE_DATA. This is not an issue at the moment because node_zones are
located at the structure beginning but this might change in the future
so better be careful about that.
Signed-off-by: Michal Hocko <mhocko@suse.cz>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Mel Gorman <mgorman@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 21c272d517bc..d2186ecb36f7 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5413,15 +5413,22 @@ __count_immobile_pages(struct zone *zone, struct page *page, int count) bool is_pageblock_removable_nolock(struct page *page) { - struct zone *zone = page_zone(page); - unsigned long pfn = page_to_pfn(page); + struct zone *zone; + unsigned long pfn; /* * We have to be careful here because we are iterating over memory * sections which are not zone aware so we might end up outside of * the zone but still within the section. + * We have to take care about the node as well. If the node is offline + * its NODE_DATA will be NULL - see page_zone. */ - if (!zone || zone->zone_start_pfn > pfn || + if (!node_online(page_to_nid(page))) + return false; + + zone = page_zone(page); + pfn = page_to_pfn(page); + if (zone->zone_start_pfn > pfn || zone->zone_start_pfn + zone->spanned_pages <= pfn) return false; |