Re: [patch 00/12] Slab defragmentation V3

Christoph Lameter
2007-06-08T20:48:57Z

On Fri, 8 Jun 2007, Michal Piotrowski wrote:

> > Could you remove the trylock patch and see how this one fares? We may need
> > both but this should avoid taking the slub_lock around any possible alloc of
> > sysfs.
> It's a bit tricky

Hmmm... Yes that version was aginst 4-mm1 instead after the defrag
patchset. The difference is only the "ops" parameter...

Rediff to apply after defrag patchset.

SLUB: Move sysfs operations outside of slub_lock

Sysfs can do a gazillion things when called. Make sure that we do
not call any sysfs functions while holding the slub_lock. Let sysfs
fend for itself locking wise.

Just protect the essentials: The modifications to the slab lists
and the ref counters of the slabs.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

---
mm/slub.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)

Index: slub/mm/slub.c
===================================================================
--- slub.orig/mm/slub.c 2007-06-08 13:47:32.000000000 -0700
+++ slub/mm/slub.c 2007-06-08 13:48:07.000000000 -0700
@@ -2193,12 +2193,13 @@ void kmem_cache_destroy(struct kmem_cach
s->refcount--;
if (!s->refcount) {
list_del(&s->list);
+ up_write(&slub_lock);
if (kmem_cache_close(s))
WARN_ON(1);
sysfs_slab_remove(s);
kfree(s);
- }
- up_write(&slub_lock);
+ } else
+ up_write(&slub_lock);
}
EXPORT_SYMBOL(kmem_cache_destroy);

@@ -2956,26 +2957,33 @@ struct kmem_cache *kmem_cache_create(con
*/
s->objsize = max(s->objsize, (int)size);
s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
+ up_write(&slub_lock);
+
if (sysfs_slab_alias(s, name))
goto err;
- } else {
- s = kmalloc(kmem_size, GFP_KERNEL);
- if (s && kmem_cache_open(s, GFP_KERNEL, name,
+
+ return s;
+ }
+
+ s = kmalloc(kmem_size, GFP_KERNEL);
+ if (s) {
+ if (kmem_cache_open(s, GFP_KERNEL, name,
size, align, flags, ctor, ops)) {
- if (sysfs_slab_add(s)) {
- kfree(s);
- goto err;
- }
list_add(&s->list, &slab_caches);
+ up_write(&slub_lock);
raise_kswapd_order(s->order);
- } else
- kfree(s);
+
+ if (sysfs_slab_add(s))
+ goto err;
+
+ return s;
+
+ }
+ kfree(s);
}
up_write(&slub_lock);
- return s;

err:
- up_write(&slub_lock);
if (flags & SLAB_PANIC)
panic("Cannot create slabcache %s\n", name);
else