diff options
author | Konstantin Khlebnikov <khlebnikov@openvz.org> | 2011-12-08 17:33:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-09 10:50:27 -0500 |
commit | 83aeeada7c69f35e5100b27ec354335597a7a488 (patch) | |
tree | 44644e68f303368feba7c8ba3e0e0991d6238ada /mm/vmscan.c | |
parent | 635697c663f38106063d5659f0cf2e45afcd4bb5 (diff) |
vmscan: use atomic-long for shrinker batching
Use atomic-long operations instead of looping around cmpxchg().
[akpm@linux-foundation.org: massage atomic.h inclusions]
Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r-- | mm/vmscan.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index f5255442ae2b..f54a05b7a61d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -183,7 +183,7 @@ static unsigned long zone_nr_lru_pages(struct zone *zone, | |||
183 | */ | 183 | */ |
184 | void register_shrinker(struct shrinker *shrinker) | 184 | void register_shrinker(struct shrinker *shrinker) |
185 | { | 185 | { |
186 | shrinker->nr = 0; | 186 | atomic_long_set(&shrinker->nr_in_batch, 0); |
187 | down_write(&shrinker_rwsem); | 187 | down_write(&shrinker_rwsem); |
188 | list_add_tail(&shrinker->list, &shrinker_list); | 188 | list_add_tail(&shrinker->list, &shrinker_list); |
189 | up_write(&shrinker_rwsem); | 189 | up_write(&shrinker_rwsem); |
@@ -264,9 +264,7 @@ unsigned long shrink_slab(struct shrink_control *shrink, | |||
264 | * and zero it so that other concurrent shrinker invocations | 264 | * and zero it so that other concurrent shrinker invocations |
265 | * don't also do this scanning work. | 265 | * don't also do this scanning work. |
266 | */ | 266 | */ |
267 | do { | 267 | nr = atomic_long_xchg(&shrinker->nr_in_batch, 0); |
268 | nr = shrinker->nr; | ||
269 | } while (cmpxchg(&shrinker->nr, nr, 0) != nr); | ||
270 | 268 | ||
271 | total_scan = nr; | 269 | total_scan = nr; |
272 | delta = (4 * nr_pages_scanned) / shrinker->seeks; | 270 | delta = (4 * nr_pages_scanned) / shrinker->seeks; |
@@ -328,12 +326,11 @@ unsigned long shrink_slab(struct shrink_control *shrink, | |||
328 | * manner that handles concurrent updates. If we exhausted the | 326 | * manner that handles concurrent updates. If we exhausted the |
329 | * scan, there is no need to do an update. | 327 | * scan, there is no need to do an update. |
330 | */ | 328 | */ |
331 | do { | 329 | if (total_scan > 0) |
332 | nr = shrinker->nr; | 330 | new_nr = atomic_long_add_return(total_scan, |
333 | new_nr = total_scan + nr; | 331 | &shrinker->nr_in_batch); |
334 | if (total_scan <= 0) | 332 | else |
335 | break; | 333 | new_nr = atomic_long_read(&shrinker->nr_in_batch); |
336 | } while (cmpxchg(&shrinker->nr, nr, new_nr) != nr); | ||
337 | 334 | ||
338 | trace_mm_shrink_slab_end(shrinker, shrink_ret, nr, new_nr); | 335 | trace_mm_shrink_slab_end(shrinker, shrink_ret, nr, new_nr); |
339 | } | 336 | } |