aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Lameter <cl@linux.com>2012-09-04 23:38:33 +0000
committerPekka Enberg <penberg@kernel.org>2012-09-05 12:00:36 +0300
commit12c3667fb780e20360ad0bde32dfb3591ef609ad (patch)
treedbced65da22c85212bf632ff6953c0a94252c3ef
parent8f4c765c22deee766319ae9a1db68325f14816e6 (diff)
mm/sl[aou]b: Get rid of __kmem_cache_destroy
What is done there can be done in __kmem_cache_shutdown. This affects RCU handling somewhat. On rcu free all slab allocators do not refer to other management structures than the kmem_cache structure. Therefore these other structures can be freed before the rcu deferred free to the page allocator occurs. Reviewed-by: Joonsoo Kim <js1304@gmail.com> Signed-off-by: Christoph Lameter <cl@linux.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r--mm/slab.c46
-rw-r--r--mm/slab.h1
-rw-r--r--mm/slab_common.c1
-rw-r--r--mm/slob.c4
-rw-r--r--mm/slub.c10
5 files changed, 26 insertions, 36 deletions
diff --git a/mm/slab.c b/mm/slab.c
index 8ca6ec6301f..de961b48a6a 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2208,26 +2208,6 @@ static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp)
}
}
-void __kmem_cache_destroy(struct kmem_cache *cachep)
-{
- int i;
- struct kmem_list3 *l3;
-
- for_each_online_cpu(i)
- kfree(cachep->array[i]);
-
- /* NUMA: free the list3 structures */
- for_each_online_node(i) {
- l3 = cachep->nodelists[i];
- if (l3) {
- kfree(l3->shared);
- free_alien_cache(l3->alien);
- kfree(l3);
- }
- }
-}
-
-
/**
* calculate_slab_order - calculate size (page order) of slabs
* @cachep: pointer to the cache that is being created
@@ -2364,9 +2344,6 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep, gfp_t gfp)
* Cannot be called within a int, but can be interrupted.
* The @ctor is run when new pages are allocated by the cache.
*
- * @name must be valid until the cache is destroyed. This implies that
- * the module calling this has to destroy the cache before getting unloaded.
- *
* The flags are
*
* %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
@@ -2591,7 +2568,7 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
cachep->refcount = 1;
if (setup_cpu_cache(cachep, gfp)) {
- __kmem_cache_destroy(cachep);
+ __kmem_cache_shutdown(cachep);
return NULL;
}
@@ -2766,7 +2743,26 @@ EXPORT_SYMBOL(kmem_cache_shrink);
int __kmem_cache_shutdown(struct kmem_cache *cachep)
{
- return __cache_shrink(cachep);
+ int i;
+ struct kmem_list3 *l3;
+ int rc = __cache_shrink(cachep);
+
+ if (rc)
+ return rc;
+
+ for_each_online_cpu(i)
+ kfree(cachep->array[i]);
+
+ /* NUMA: free the list3 structures */
+ for_each_online_node(i) {
+ l3 = cachep->nodelists[i];
+ if (l3) {
+ kfree(l3->shared);
+ free_alien_cache(l3->alien);
+ kfree(l3);
+ }
+ }
+ return 0;
}
/*
diff --git a/mm/slab.h b/mm/slab.h
index 6724aa6f662..c4f9a361bd1 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -37,6 +37,5 @@ struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
size_t align, unsigned long flags, void (*ctor)(void *));
int __kmem_cache_shutdown(struct kmem_cache *);
-void __kmem_cache_destroy(struct kmem_cache *);
#endif
diff --git a/mm/slab_common.c b/mm/slab_common.c
index d6deae9108c..7df814e8fbe 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -153,7 +153,6 @@ void kmem_cache_destroy(struct kmem_cache *s)
if (s->flags & SLAB_DESTROY_BY_RCU)
rcu_barrier();
- __kmem_cache_destroy(s);
kmem_cache_free(kmem_cache, s);
} else {
list_add(&s->list, &slab_caches);
diff --git a/mm/slob.c b/mm/slob.c
index cb4ab967529..50f60532270 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -538,10 +538,6 @@ struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
return c;
}
-void __kmem_cache_destroy(struct kmem_cache *c)
-{
-}
-
void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
{
void *b;
diff --git a/mm/slub.c b/mm/slub.c
index 6f932f7a821..e5e09873f5e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3205,12 +3205,12 @@ static inline int kmem_cache_close(struct kmem_cache *s)
int __kmem_cache_shutdown(struct kmem_cache *s)
{
- return kmem_cache_close(s);
-}
+ int rc = kmem_cache_close(s);
-void __kmem_cache_destroy(struct kmem_cache *s)
-{
- sysfs_slab_remove(s);
+ if (!rc)
+ sysfs_slab_remove(s);
+
+ return rc;
}
/********************************************************************