Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Konstantin Khlebnikov and committed by
Linus Torvalds
83aeeada 635697c6

+10 -12
+1 -1
include/linux/fs.h
··· 393 393 #include <linux/semaphore.h> 394 394 #include <linux/fiemap.h> 395 395 #include <linux/rculist_bl.h> 396 - #include <linux/shrinker.h> 397 396 #include <linux/atomic.h> 397 + #include <linux/shrinker.h> 398 398 399 399 #include <asm/byteorder.h> 400 400
+1
include/linux/mm.h
··· 10 10 #include <linux/mmzone.h> 11 11 #include <linux/rbtree.h> 12 12 #include <linux/prio_tree.h> 13 + #include <linux/atomic.h> 13 14 #include <linux/debug_locks.h> 14 15 #include <linux/mm_types.h> 15 16 #include <linux/range.h>
+1 -1
include/linux/shrinker.h
··· 35 35 36 36 /* These are for internal use */ 37 37 struct list_head list; 38 - long nr; /* objs pending delete */ 38 + atomic_long_t nr_in_batch; /* objs pending delete */ 39 39 }; 40 40 #define DEFAULT_SEEKS 2 /* A good number if you don't know better. */ 41 41 extern void register_shrinker(struct shrinker *);
+7 -10
mm/vmscan.c
··· 183 183 */ 184 184 void register_shrinker(struct shrinker *shrinker) 185 185 { 186 - shrinker->nr = 0; 186 + atomic_long_set(&shrinker->nr_in_batch, 0); 187 187 down_write(&shrinker_rwsem); 188 188 list_add_tail(&shrinker->list, &shrinker_list); 189 189 up_write(&shrinker_rwsem); ··· 264 264 * and zero it so that other concurrent shrinker invocations 265 265 * don't also do this scanning work. 266 266 */ 267 - do { 268 - nr = shrinker->nr; 269 - } while (cmpxchg(&shrinker->nr, nr, 0) != nr); 267 + nr = atomic_long_xchg(&shrinker->nr_in_batch, 0); 270 268 271 269 total_scan = nr; 272 270 delta = (4 * nr_pages_scanned) / shrinker->seeks; ··· 326 328 * manner that handles concurrent updates. If we exhausted the 327 329 * scan, there is no need to do an update. 328 330 */ 329 - do { 330 - nr = shrinker->nr; 331 - new_nr = total_scan + nr; 332 - if (total_scan <= 0) 333 - break; 334 - } while (cmpxchg(&shrinker->nr, nr, new_nr) != nr); 331 + if (total_scan > 0) 332 + new_nr = atomic_long_add_return(total_scan, 333 + &shrinker->nr_in_batch); 334 + else 335 + new_nr = atomic_long_read(&shrinker->nr_in_batch); 335 336 336 337 trace_mm_shrink_slab_end(shrinker, shrink_ret, nr, new_nr); 337 338 }