diff options
Diffstat (limited to 'mm/vmscan.c')
| -rw-r--r-- | mm/vmscan.c | 26 | 
1 files changed, 13 insertions, 13 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index a1893c050795..f54a05b7a61d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -183,7 +183,7 @@ static unsigned long zone_nr_lru_pages(struct zone *zone,   */  void register_shrinker(struct shrinker *shrinker)  { -	shrinker->nr = 0; +	atomic_long_set(&shrinker->nr_in_batch, 0);  	down_write(&shrinker_rwsem);  	list_add_tail(&shrinker->list, &shrinker_list);  	up_write(&shrinker_rwsem); @@ -247,25 +247,26 @@ unsigned long shrink_slab(struct shrink_control *shrink,  	list_for_each_entry(shrinker, &shrinker_list, list) {  		unsigned long long delta; -		unsigned long total_scan; -		unsigned long max_pass; +		long total_scan; +		long max_pass;  		int shrink_ret = 0;  		long nr;  		long new_nr;  		long batch_size = shrinker->batch ? shrinker->batch  						  : SHRINK_BATCH; +		max_pass = do_shrinker_shrink(shrinker, shrink, 0); +		if (max_pass <= 0) +			continue; +  		/*  		 * copy the current shrinker scan count into a local variable  		 * and zero it so that other concurrent shrinker invocations  		 * don't also do this scanning work.  		 */ -		do { -			nr = shrinker->nr; -		} while (cmpxchg(&shrinker->nr, nr, 0) != nr); +		nr = atomic_long_xchg(&shrinker->nr_in_batch, 0);  		total_scan = nr; -		max_pass = do_shrinker_shrink(shrinker, shrink, 0);  		delta = (4 * nr_pages_scanned) / shrinker->seeks;  		delta *= max_pass;  		do_div(delta, lru_pages + 1); @@ -325,12 +326,11 @@ unsigned long shrink_slab(struct shrink_control *shrink,  		 * manner that handles concurrent updates. If we exhausted the  		 * scan, there is no need to do an update.  		 */ -		do { -			nr = shrinker->nr; -			new_nr = total_scan + nr; -			if (total_scan <= 0) -				break; -		} while (cmpxchg(&shrinker->nr, nr, new_nr) != nr); +		if (total_scan > 0) +			new_nr = atomic_long_add_return(total_scan, +					&shrinker->nr_in_batch); +		else +			new_nr = atomic_long_read(&shrinker->nr_in_batch);  		trace_mm_shrink_slab_end(shrinker, shrink_ret, nr, new_nr);  	}  | 
