diff options
author | Christoph Lameter <clameter@sgi.com> | 2006-03-25 06:06:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-25 11:22:49 -0500 |
commit | e00946fe2351307eb3eda7a3343530f6d2d1af2e (patch) | |
tree | 1567b4abe0ed56fbd960943da2c52278ea196c02 | |
parent | 3ded175a4b7a4548f3358dcf5f3ad65f63cdb4ed (diff) |
[PATCH] slab: Bypass free lists for __drain_alien_cache()
__drain_alien_cache() currently drains objects by freeing them to the
(remote) freelists of the original node. However, each node also has a
shared list containing objects to be used on any processor of that node.
We can avoid a number of remote node accesses by copying the pointers to
the free objects directly into the remote shared array.
And while we are at it: Skip alien draining if the alien cache spinlock is
already taken.
Kiran reported that this is a performance benefit.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | mm/slab.c | 11 |
1 files changed, 9 insertions, 2 deletions
@@ -971,6 +971,13 @@ static void __drain_alien_cache(struct kmem_cache *cachep, | |||
971 | 971 | ||
972 | if (ac->avail) { | 972 | if (ac->avail) { |
973 | spin_lock(&rl3->list_lock); | 973 | spin_lock(&rl3->list_lock); |
974 | /* | ||
975 | * Stuff objects into the remote nodes shared array first. | ||
976 | * That way we could avoid the overhead of putting the objects | ||
977 | * into the free lists and getting them back later. | ||
978 | */ | ||
979 | transfer_objects(rl3->shared, ac, ac->limit); | ||
980 | |||
974 | free_block(cachep, ac->entry, ac->avail, node); | 981 | free_block(cachep, ac->entry, ac->avail, node); |
975 | ac->avail = 0; | 982 | ac->avail = 0; |
976 | spin_unlock(&rl3->list_lock); | 983 | spin_unlock(&rl3->list_lock); |
@@ -986,8 +993,8 @@ static void reap_alien(struct kmem_cache *cachep, struct kmem_list3 *l3) | |||
986 | 993 | ||
987 | if (l3->alien) { | 994 | if (l3->alien) { |
988 | struct array_cache *ac = l3->alien[node]; | 995 | struct array_cache *ac = l3->alien[node]; |
989 | if (ac && ac->avail) { | 996 | |
990 | spin_lock_irq(&ac->lock); | 997 | if (ac && ac->avail && spin_trylock_irq(&ac->lock)) { |
991 | __drain_alien_cache(cachep, ac, node); | 998 | __drain_alien_cache(cachep, ac, node); |
992 | spin_unlock_irq(&ac->lock); | 999 | spin_unlock_irq(&ac->lock); |
993 | } | 1000 | } |