fix RCU-callback-after-kmem_cache_destroy problem in sl[aou]b
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Thu, 25 Jun 2009 19:31:37 +0000 (12:31 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 30 Jul 2009 23:05:58 +0000 (16:05 -0700)
commit 7ed9f7e5db58c6e8c2b4b738a75d5dcd8e17aad5 upstream.

Jesper noted that kmem_cache_destroy() invokes synchronize_rcu() rather than
rcu_barrier() in the SLAB_DESTROY_BY_RCU case, which could result in RCU
callbacks accessing a kmem_cache after it had been destroyed.

Acked-by: Matt Mackall <mpm@selenic.com>
Reported-by: Jesper Dangaard Brouer <hawk@comx.dk>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
mm/slab.c
mm/slob.c
mm/slub.c

index e76eee4..600e864 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2580,7 +2580,7 @@ void kmem_cache_destroy(struct kmem_cache *cachep)
        }
 
        if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
-               synchronize_rcu();
+               rcu_barrier();
 
        __kmem_cache_destroy(cachep);
        mutex_unlock(&cache_chain_mutex);
index cb675d1..ed04252 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -561,6 +561,8 @@ EXPORT_SYMBOL(kmem_cache_create);
 
 void kmem_cache_destroy(struct kmem_cache *c)
 {
+       if (c->flags & SLAB_DESTROY_BY_RCU)
+               rcu_barrier();
        slob_free(c, sizeof(struct kmem_cache));
 }
 EXPORT_SYMBOL(kmem_cache_destroy);
index 0c83e6a..f0175b4 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2447,6 +2447,8 @@ static inline int kmem_cache_close(struct kmem_cache *s)
  */
 void kmem_cache_destroy(struct kmem_cache *s)
 {
+       if (s->flags & SLAB_DESTROY_BY_RCU)
+               rcu_barrier();
        down_write(&slub_lock);
        s->refcount--;
        if (!s->refcount) {