| From d76b1590e06a63a3d8697168cd0aabf1c4b3cb3a Mon Sep 17 00:00:00 2001 |
| From: Eric Dumazet <eric.dumazet@gmail.com> |
| Date: Thu, 3 Sep 2009 22:38:59 +0300 |
| Subject: slub: Fix kmem_cache_destroy() with SLAB_DESTROY_BY_RCU |
| |
| From: Eric Dumazet <eric.dumazet@gmail.com> |
| |
| commit d76b1590e06a63a3d8697168cd0aabf1c4b3cb3a upstream. |
| |
| kmem_cache_destroy() should call rcu_barrier() *after* kmem_cache_close() and |
| *before* sysfs_slab_remove() or risk rcu_free_slab() being called after |
| kmem_cache is deleted (kfreed). |
| |
| rmmod nf_conntrack can crash the machine because it has to kmem_cache_destroy() |
| a SLAB_DESTROY_BY_RCU enabled cache. |
| |
| Reported-by: Zdenek Kabelac <zdenek.kabelac@gmail.com> |
| Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> |
| Acked-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/slub.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/mm/slub.c |
| +++ b/mm/slub.c |
| @@ -2490,8 +2490,6 @@ static inline int kmem_cache_close(struc |
| */ |
| 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) { |
| @@ -2502,6 +2500,8 @@ void kmem_cache_destroy(struct kmem_cach |
| "still has objects.\n", s->name, __func__); |
| dump_stack(); |
| } |
| + if (s->flags & SLAB_DESTROY_BY_RCU) |
| + rcu_barrier(); |
| sysfs_slab_remove(s); |
| } else |
| up_write(&slub_lock); |