]> Git Repo - linux.git/commitdiff
slab: clean up kmem_cache_create_memcg() error handling
authorVladimir Davydov <[email protected]>
Thu, 23 Jan 2014 23:52:55 +0000 (15:52 -0800)
committerLinus Torvalds <[email protected]>
Fri, 24 Jan 2014 00:36:50 +0000 (16:36 -0800)
Currently kmem_cache_create_memcg() backoffs on failure inside
conditionals, without using gotos.  This results in the rollback code
duplication, which makes the function look cumbersome even though on
error we should only free the allocated cache.  Since in the next patch
I am going to add yet another rollback function call on error path
there, let's employ labels instead of conditionals for undoing any
changes on failure to keep things clean.

Signed-off-by: Vladimir Davydov <[email protected]>
Reviewed-by: Pekka Enberg <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Glauber Costa <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: Christoph Lameter <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
mm/slab_common.c

index 0b7bb399b0e46af8ac8b96fbedb67aef413e5cb7..f70df3ef6f1a1075e4ccc55d3bd84e4fd079ab45 100644 (file)
@@ -171,13 +171,14 @@ kmem_cache_create_memcg(struct mem_cgroup *memcg, const char *name, size_t size,
                        struct kmem_cache *parent_cache)
 {
        struct kmem_cache *s = NULL;
-       int err = 0;
+       int err;
 
        get_online_cpus();
        mutex_lock(&slab_mutex);
 
-       if (!kmem_cache_sanity_check(memcg, name, size) == 0)
-               goto out_locked;
+       err = kmem_cache_sanity_check(memcg, name, size);
+       if (err)
+               goto out_unlock;
 
        /*
         * Some allocators will constraint the set of valid flags to a subset
@@ -189,45 +190,38 @@ kmem_cache_create_memcg(struct mem_cgroup *memcg, const char *name, size_t size,
 
        s = __kmem_cache_alias(memcg, name, size, align, flags, ctor);
        if (s)
-               goto out_locked;
+               goto out_unlock;
 
+       err = -ENOMEM;
        s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL);
-       if (s) {
-               s->object_size = s->size = size;
-               s->align = calculate_alignment(flags, align, size);
-               s->ctor = ctor;
+       if (!s)
+               goto out_unlock;
 
-               if (memcg_register_cache(memcg, s, parent_cache)) {
-                       kmem_cache_free(kmem_cache, s);
-                       err = -ENOMEM;
-                       goto out_locked;
-               }
+       s->object_size = s->size = size;
+       s->align = calculate_alignment(flags, align, size);
+       s->ctor = ctor;
 
-               s->name = kstrdup(name, GFP_KERNEL);
-               if (!s->name) {
-                       kmem_cache_free(kmem_cache, s);
-                       err = -ENOMEM;
-                       goto out_locked;
-               }
+       s->name = kstrdup(name, GFP_KERNEL);
+       if (!s->name)
+               goto out_free_cache;
 
-               err = __kmem_cache_create(s, flags);
-               if (!err) {
-                       s->refcount = 1;
-                       list_add(&s->list, &slab_caches);
-                       memcg_cache_list_add(memcg, s);
-               } else {
-                       kfree(s->name);
-                       kmem_cache_free(kmem_cache, s);
-               }
-       } else
-               err = -ENOMEM;
+       err = memcg_register_cache(memcg, s, parent_cache);
+       if (err)
+               goto out_free_cache;
+
+       err = __kmem_cache_create(s, flags);
+       if (err)
+               goto out_free_cache;
+
+       s->refcount = 1;
+       list_add(&s->list, &slab_caches);
+       memcg_cache_list_add(memcg, s);
 
-out_locked:
+out_unlock:
        mutex_unlock(&slab_mutex);
        put_online_cpus();
 
        if (err) {
-
                if (flags & SLAB_PANIC)
                        panic("kmem_cache_create: Failed to create slab '%s'. Error %d\n",
                                name, err);
@@ -236,11 +230,14 @@ out_locked:
                                name, err);
                        dump_stack();
                }
-
                return NULL;
        }
-
        return s;
+
+out_free_cache:
+       kfree(s->name);
+       kmem_cache_free(kmem_cache, s);
+       goto out_unlock;
 }
 
 struct kmem_cache *
This page took 0.059105 seconds and 4 git commands to generate.