mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* slab: Add transfer_objects() function
@ 2006-03-21 23:10 Christoph Lameter
  2006-03-21 23:12 ` slab: Bypass free lists for __drain_alien_cache() Christoph Lameter
  2006-03-22  0:21 ` slab: Add transfer_objects() function Andrew Morton
  0 siblings, 2 replies; 4+ messages in thread
From: Christoph Lameter @ 2006-03-21 23:10 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, kiran, alokk, Pekka Enberg

transfer_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: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.16-rc6-mm2/mm/slab.c
===================================================================
--- linux-2.6.16-rc6-mm2.orig/mm/slab.c	2006-03-21 14:52:47.000000000 -0800
+++ linux-2.6.16-rc6-mm2/mm/slab.c	2006-03-21 14:53:40.000000000 -0800
@@ -901,6 +901,30 @@ static struct array_cache *alloc_arrayca
 	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, 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);
@@ -2684,20 +2708,10 @@ retry:
 	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;

^ permalink raw reply	[flat|nested] 4+ messages in thread

* slab: Bypass free lists for __drain_alien_cache()
  2006-03-21 23:10 slab: Add transfer_objects() function Christoph Lameter
@ 2006-03-21 23:12 ` Christoph Lameter
  2006-03-22  0:21 ` slab: Add transfer_objects() function Andrew Morton
  1 sibling, 0 replies; 4+ messages in thread
From: Christoph Lameter @ 2006-03-21 23:12 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, kiran, alokk, Pekka Enberg

__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.

Depends on the earlier patch that introduces the transfer_objects() function.

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>

Index: linux-2.6.16-rc6-mm2/mm/slab.c
===================================================================
--- linux-2.6.16-rc6-mm2.orig/mm/slab.c	2006-03-21 14:53:40.000000000 -0800
+++ linux-2.6.16-rc6-mm2/mm/slab.c	2006-03-21 14:55:09.000000000 -0800
@@ -974,6 +974,13 @@ static void __drain_alien_cache(struct k
 
 	if (ac->avail) {
 		spin_lock(&rl3->list_lock);
+		/*
+		 * Stuff objects into the remote nodes shared array first.
+		 * That way we could avoid the overhead of putting the objects
+		 * into the free lists and getting them back later.
+		 */
+		transfer_objects(rl3->shared, ac, ac->limit);
+
 		free_block(cachep, ac->entry, ac->avail, node);
 		ac->avail = 0;
 		spin_unlock(&rl3->list_lock);
@@ -989,8 +996,8 @@ static void reap_alien(struct kmem_cache
 
 	if (l3->alien) {
 		struct array_cache *ac = l3->alien[node];
-		if (ac && ac->avail) {
-			spin_lock_irq(&ac->lock);
+
+		if (ac && ac->avail && spin_trylock_irq(&ac->lock)) {
 			__drain_alien_cache(cachep, ac, node);
 			spin_unlock_irq(&ac->lock);
 		}


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: slab: Add transfer_objects() function
  2006-03-21 23:10 slab: Add transfer_objects() function Christoph Lameter
  2006-03-21 23:12 ` slab: Bypass free lists for __drain_alien_cache() Christoph Lameter
@ 2006-03-22  0:21 ` Andrew Morton
  2006-03-22  0:24   ` Christoph Lameter
  1 sibling, 1 reply; 4+ messages in thread
From: Andrew Morton @ 2006-03-22  0:21 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-kernel, kiran, alokk, penberg

Christoph Lameter <clameter@sgi.com> wrote:
>
> +static int transfer_objects(struct array_cache *to,
> +		struct array_cache *from, int max)

Does this ever get called if !CONFIG_NUMA?

If not, can we provide a non-numa version which just goes BUG and saves
some text?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: slab: Add transfer_objects() function
  2006-03-22  0:21 ` slab: Add transfer_objects() function Andrew Morton
@ 2006-03-22  0:24   ` Christoph Lameter
  0 siblings, 0 replies; 4+ messages in thread
From: Christoph Lameter @ 2006-03-22  0:24 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, kiran, alokk, penberg

On Tue, 21 Mar 2006, Andrew Morton wrote:

> Christoph Lameter <clameter@sgi.com> wrote:
> >
> > +static int transfer_objects(struct array_cache *to,
> > +		struct array_cache *from, int max)
> 
> Does this ever get called if !CONFIG_NUMA?

Yes. See later in the patch.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-03-22  0:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-21 23:10 slab: Add transfer_objects() function Christoph Lameter
2006-03-21 23:12 ` slab: Bypass free lists for __drain_alien_cache() Christoph Lameter
2006-03-22  0:21 ` slab: Add transfer_objects() function Andrew Morton
2006-03-22  0:24   ` Christoph Lameter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®