|
@@ -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);
|
|
@@ -264,9 +264,7 @@ unsigned long shrink_slab(struct shrink_control *shrink,
|
|
|
* 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;
|
|
|
delta = (4 * nr_pages_scanned) / shrinker->seeks;
|
|
@@ -328,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);
|
|
|
}
|