Commit 3ded175a authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds
Browse files

[PATCH] slab: add transfer_objects() function



slabr_objects() can be used to transfer objects between various object
caches of the slab allocator.  It is currently only used during
__cache_alloc() to retrieve elements from the shared array.  We will be
using it soon to transfer elements from the alien caches to the remote
shared array.

Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c5e3b83e
...@@ -898,6 +898,30 @@ static struct array_cache *alloc_arraycache(int node, int entries, ...@@ -898,6 +898,30 @@ static struct array_cache *alloc_arraycache(int node, int entries,
return nc; 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 #ifdef CONFIG_NUMA
static void *__cache_alloc_node(struct kmem_cache *, gfp_t, int); static void *__cache_alloc_node(struct kmem_cache *, gfp_t, int);
static void *alternate_node_alloc(struct kmem_cache *, gfp_t); static void *alternate_node_alloc(struct kmem_cache *, gfp_t);
...@@ -2680,20 +2704,10 @@ retry: ...@@ -2680,20 +2704,10 @@ retry:
BUG_ON(ac->avail > 0 || !l3); BUG_ON(ac->avail > 0 || !l3);
spin_lock(&l3->list_lock); spin_lock(&l3->list_lock);
if (l3->shared) { /* See if we can refill from the shared array */
struct array_cache *shared_array = l3->shared; if (l3->shared && transfer_objects(ac, l3->shared, batchcount))
if (shared_array->avail) { goto alloc_done;
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;
}
}
while (batchcount > 0) { while (batchcount > 0) {
struct list_head *entry; struct list_head *entry;
struct slab *slabp; struct slab *slabp;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment