diff options
Diffstat (limited to 'mm/page_alloc.c')
| -rw-r--r-- | mm/page_alloc.c | 20 | 
1 files changed, 19 insertions, 1 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 0027d8f4a1b..d2186ecb36f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5413,7 +5413,25 @@ __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); +	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 (!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; +  	return __count_immobile_pages(zone, page, 0);  }  |