From 365d4675cf4ade601fdafcf25edee04b31b94583 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sat, 25 Mar 2006 03:06:44 -0800 Subject: [PATCH] --- yaml --- r: 23508 b: refs/heads/master c: 3ded175a4b7a4548f3358dcf5f3ad65f63cdb4ed h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/mm/slab.c | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index 313118f23055..a776a8454c5f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c5e3b83e97be4e09961c0af101644643e5d03d17 +refs/heads/master: 3ded175a4b7a4548f3358dcf5f3ad65f63cdb4ed diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 6a3760e0353c..dee857a8680b 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -898,6 +898,30 @@ static struct array_cache *alloc_arraycache(int node, int entries, return nc; } +/* + * Transfer objects in one arraycache to another. + * Locking must be handled by the caller. + * + * Return the number of entries transferred. + */ +static int transfer_objects(struct array_cache *to, + struct array_cache *from, unsigned int max) +{ + /* Figure out how many entries to transfer */ + int nr = min(min(from->avail, max), to->limit - to->avail); + + if (!nr) + return 0; + + memcpy(to->entry + to->avail, from->entry + from->avail -nr, + sizeof(void *) *nr); + + from->avail -= nr; + to->avail += nr; + to->touched = 1; + return nr; +} + #ifdef CONFIG_NUMA static void *__cache_alloc_node(struct kmem_cache *, gfp_t, int); static void *alternate_node_alloc(struct kmem_cache *, gfp_t); @@ -2680,20 +2704,10 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) BUG_ON(ac->avail > 0 || !l3); spin_lock(&l3->list_lock); - if (l3->shared) { - struct array_cache *shared_array = l3->shared; - if (shared_array->avail) { - if (batchcount > shared_array->avail) - batchcount = shared_array->avail; - shared_array->avail -= batchcount; - ac->avail = batchcount; - memcpy(ac->entry, - &(shared_array->entry[shared_array->avail]), - sizeof(void *) * batchcount); - shared_array->touched = 1; - goto alloc_done; - } - } + /* See if we can refill from the shared array */ + if (l3->shared && transfer_objects(ac, l3->shared, batchcount)) + goto alloc_done; + while (batchcount > 0) { struct list_head *entry; struct slab *slabp;