diff options
Diffstat (limited to 'mm/page_alloc.c')
| -rw-r--r-- | mm/page_alloc.c | 18 | 
1 files changed, 15 insertions, 3 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 90c1439549f..a873e61e312 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1088,8 +1088,10 @@ static void drain_pages(unsigned int cpu)  		pset = per_cpu_ptr(zone->pageset, cpu);  		pcp = &pset->pcp; -		free_pcppages_bulk(zone, pcp->count, pcp); -		pcp->count = 0; +		if (pcp->count) { +			free_pcppages_bulk(zone, pcp->count, pcp); +			pcp->count = 0; +		}  		local_irq_restore(flags);  	}  } @@ -2034,6 +2036,14 @@ restart:  	 */  	alloc_flags = gfp_to_alloc_flags(gfp_mask); +	/* +	 * Find the true preferred zone if the allocation is unconstrained by +	 * cpusets. +	 */ +	if (!(alloc_flags & ALLOC_CPUSET) && !nodemask) +		first_zones_zonelist(zonelist, high_zoneidx, NULL, +					&preferred_zone); +  	/* This is the last chance, in general, before the goto nopage. */  	page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist,  			high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS, @@ -2192,7 +2202,9 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,  	get_mems_allowed();  	/* The preferred zone is used for statistics later */ -	first_zones_zonelist(zonelist, high_zoneidx, nodemask, &preferred_zone); +	first_zones_zonelist(zonelist, high_zoneidx, +				nodemask ? : &cpuset_current_mems_allowed, +				&preferred_zone);  	if (!preferred_zone) {  		put_mems_allowed();  		return NULL;  |