Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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
Loading
Loading
Loading
Loading
+28 −14
Original line number Diff line number Diff line
@@ -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;
	/* 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;