aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorKonstantin Khlebnikov <khlebnikov@openvz.org>2011-12-08 17:33:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-12-09 10:50:27 -0500
commit83aeeada7c69f35e5100b27ec354335597a7a488 (patch)
tree44644e68f303368feba7c8ba3e0e0991d6238ada /mm
parent635697c663f38106063d5659f0cf2e45afcd4bb5 (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')
-rw-r--r--mm/vmscan.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f5255442ae2..f54a05b7a61 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 */
184void register_shrinker(struct shrinker *shrinker) 184void 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 }