diff options
Diffstat (limited to 'mm/vmscan.c')
| -rw-r--r-- | mm/vmscan.c | 32 | 
1 files changed, 22 insertions, 10 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index 17497d0cd8b..6771ea70bfe 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1841,16 +1841,28 @@ static inline bool should_continue_reclaim(struct zone *zone,  	if (!(sc->reclaim_mode & RECLAIM_MODE_COMPACTION))  		return false; -	/* -	 * If we failed to reclaim and have scanned the full list, stop. -	 * NOTE: Checking just nr_reclaimed would exit reclaim/compaction far -	 *       faster but obviously would be less likely to succeed -	 *       allocation. If this is desirable, use GFP_REPEAT to decide -	 *       if both reclaimed and scanned should be checked or just -	 *       reclaimed -	 */ -	if (!nr_reclaimed && !nr_scanned) -		return false; +	/* Consider stopping depending on scan and reclaim activity */ +	if (sc->gfp_mask & __GFP_REPEAT) { +		/* +		 * For __GFP_REPEAT allocations, stop reclaiming if the +		 * full LRU list has been scanned and we are still failing +		 * to reclaim pages. This full LRU scan is potentially +		 * expensive but a __GFP_REPEAT caller really wants to succeed +		 */ +		if (!nr_reclaimed && !nr_scanned) +			return false; +	} else { +		/* +		 * For non-__GFP_REPEAT allocations which can presumably +		 * fail without consequence, stop if we failed to reclaim +		 * any pages from the last SWAP_CLUSTER_MAX number of +		 * pages that were scanned. This will return to the +		 * caller faster at the risk reclaim/compaction and +		 * the resulting allocation attempt fails +		 */ +		if (!nr_reclaimed) +			return false; +	}  	/*  	 * If we have not reclaimed enough pages for compaction and the  |