slub: Zero initial memory segment for kmem_cache and kmem_cache_node
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / slub.c
index 724adea..2258ed8 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -210,11 +210,7 @@ static void sysfs_slab_remove(struct kmem_cache *);
 static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
 static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p)
                                                        { return 0; }
-static inline void sysfs_slab_remove(struct kmem_cache *s)
-{
-       kfree(s->name);
-       kmem_cache_free(kmem_cache, s);
-}
+static inline void sysfs_slab_remove(struct kmem_cache *s) { }
 
 #endif
 
@@ -3035,17 +3031,9 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
 
 }
 
-static int kmem_cache_open(struct kmem_cache *s,
-               const char *name, size_t size,
-               size_t align, unsigned long flags,
-               void (*ctor)(void *))
+static int kmem_cache_open(struct kmem_cache *s, unsigned long flags)
 {
-       memset(s, 0, kmem_size);
-       s->name = name;
-       s->ctor = ctor;
-       s->object_size = size;
-       s->align = align;
-       s->flags = kmem_cache_flags(size, flags, name, ctor);
+       s->flags = kmem_cache_flags(s->size, flags, s->name, s->ctor);
        s->reserved = 0;
 
        if (need_reserve_slab_rcu && (s->flags & SLAB_DESTROY_BY_RCU))
@@ -3107,7 +3095,6 @@ static int kmem_cache_open(struct kmem_cache *s,
        else
                s->cpu_partial = 30;
 
-       s->refcount = 1;
 #ifdef CONFIG_NUMA
        s->remote_node_defrag_ratio = 1000;
 #endif
@@ -3115,16 +3102,16 @@ static int kmem_cache_open(struct kmem_cache *s,
                goto error;
 
        if (alloc_kmem_cache_cpus(s))
-               return 1;
+               return 0;
 
        free_kmem_cache_nodes(s);
 error:
        if (flags & SLAB_PANIC)
                panic("Cannot create slab %s size=%lu realsize=%u "
                        "order=%u offset=%u flags=%lx\n",
-                       s->name, (unsigned long)size, s->size, oo_order(s->oo),
+                       s->name, (unsigned long)s->size, s->size, oo_order(s->oo),
                        s->offset, flags);
-       return 0;
+       return -EINVAL;
 }
 
 /*
@@ -3206,12 +3193,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;
 }
 
 /********************************************************************
@@ -3221,8 +3208,6 @@ void __kmem_cache_destroy(struct kmem_cache *s)
 struct kmem_cache *kmalloc_caches[SLUB_PAGE_SHIFT];
 EXPORT_SYMBOL(kmalloc_caches);
 
-static struct kmem_cache *kmem_cache;
-
 #ifdef CONFIG_ZONE_DMA
 static struct kmem_cache *kmalloc_dma_caches[SLUB_PAGE_SHIFT];
 #endif
@@ -3268,14 +3253,17 @@ static struct kmem_cache *__init create_kmalloc_cache(const char *name,
 {
        struct kmem_cache *s;
 
-       s = kmem_cache_alloc(kmem_cache, GFP_NOWAIT);
+       s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
+
+       s->name = name;
+       s->size = s->object_size = size;
+       s->align = ARCH_KMALLOC_MINALIGN;
 
        /*
         * This function is called with IRQs disabled during early-boot on
         * single CPU so there's no need to take slab_mutex here.
         */
-       if (!kmem_cache_open(s, name, size, ARCH_KMALLOC_MINALIGN,
-                                                               flags, NULL))
+       if (kmem_cache_open(s, flags))
                goto panic;
 
        list_add(&s->list, &slab_caches);
@@ -3714,12 +3702,12 @@ void __init kmem_cache_init(void)
                slub_max_order = 0;
 
        kmem_size = offsetof(struct kmem_cache, node) +
-                               nr_node_ids * sizeof(struct kmem_cache_node *);
+                       nr_node_ids * sizeof(struct kmem_cache_node *);
 
        /* Allocate two kmem_caches from the page allocator */
        kmalloc_size = ALIGN(kmem_size, cache_line_size());
        order = get_order(2 * kmalloc_size);
-       kmem_cache = (void *)__get_free_pages(GFP_NOWAIT, order);
+       kmem_cache = (void *)__get_free_pages(GFP_NOWAIT | __GFP_ZERO, order);
 
        /*
         * Must first have the slab cache available for the allocations of the
@@ -3728,9 +3716,10 @@ void __init kmem_cache_init(void)
         */
        kmem_cache_node = (void *)kmem_cache + kmalloc_size;
 
-       kmem_cache_open(kmem_cache_node, "kmem_cache_node",
-               sizeof(struct kmem_cache_node),
-               0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
+       kmem_cache_node->name = "kmem_cache_node";
+       kmem_cache_node->size = kmem_cache_node->object_size =
+               sizeof(struct kmem_cache_node);
+       kmem_cache_open(kmem_cache_node, SLAB_HWCACHE_ALIGN | SLAB_PANIC);
 
        hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
 
@@ -3738,8 +3727,10 @@ void __init kmem_cache_init(void)
        slab_state = PARTIAL;
 
        temp_kmem_cache = kmem_cache;
-       kmem_cache_open(kmem_cache, "kmem_cache", kmem_size,
-               0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
+       kmem_cache->name = "kmem_cache";
+       kmem_cache->size = kmem_cache->object_size = kmem_size;
+       kmem_cache_open(kmem_cache, SLAB_HWCACHE_ALIGN | SLAB_PANIC);
+
        kmem_cache = kmem_cache_alloc(kmem_cache, GFP_NOWAIT);
        memcpy(kmem_cache, temp_kmem_cache, kmem_size);
 
@@ -3928,11 +3919,10 @@ static struct kmem_cache *find_mergeable(size_t size,
        return NULL;
 }
 
-struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
+struct kmem_cache *__kmem_cache_alias(const char *name, size_t size,
                size_t align, unsigned long flags, void (*ctor)(void *))
 {
        struct kmem_cache *s;
-       char *n;
 
        s = find_mergeable(size, align, flags, name, ctor);
        if (s) {
@@ -3946,34 +3936,29 @@ struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
 
                if (sysfs_slab_alias(s, name)) {
                        s->refcount--;
-                       return NULL;
+                       s = NULL;
                }
-               return s;
        }
 
-       n = kstrdup(name, GFP_KERNEL);
-       if (!n)
-               return NULL;
+       return s;
+}
 
-       s = kmem_cache_alloc(kmem_cache, GFP_KERNEL);
-       if (s) {
-               if (kmem_cache_open(s, n,
-                               size, align, flags, ctor)) {
-                       int r;
+int __kmem_cache_create(struct kmem_cache *s, unsigned long flags)
+{
+       int err;
 
-                       mutex_unlock(&slab_mutex);
-                       r = sysfs_slab_add(s);
-                       mutex_lock(&slab_mutex);
+       err = kmem_cache_open(s, flags);
+       if (err)
+               return err;
 
-                       if (!r)
-                               return s;
+       mutex_unlock(&slab_mutex);
+       err = sysfs_slab_add(s);
+       mutex_lock(&slab_mutex);
 
-                       kmem_cache_close(s);
-               }
-               kmem_cache_free(kmem_cache, s);
-       }
-       kfree(n);
-       return NULL;
+       if (err)
+               kmem_cache_close(s);
+
+       return err;
 }
 
 #ifdef CONFIG_SMP
@@ -5203,14 +5188,6 @@ static ssize_t slab_attr_store(struct kobject *kobj,
        return err;
 }
 
-static void kmem_cache_release(struct kobject *kobj)
-{
-       struct kmem_cache *s = to_slab(kobj);
-
-       kfree(s->name);
-       kmem_cache_free(kmem_cache, s);
-}
-
 static const struct sysfs_ops slab_sysfs_ops = {
        .show = slab_attr_show,
        .store = slab_attr_store,
@@ -5218,7 +5195,6 @@ static const struct sysfs_ops slab_sysfs_ops = {
 
 static struct kobj_type slab_ktype = {
        .sysfs_ops = &slab_sysfs_ops,
-       .release = kmem_cache_release
 };
 
 static int uevent_filter(struct kset *kset, struct kobject *kobj)