Skip to content

Commit

Permalink
slab: clean up kmem_cache_create_memcg() error handling
Browse files Browse the repository at this point in the history
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 <vdavydov@parallels.com>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Glauber Costa <glommer@gmail.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Christoph Lameter <cl@linux.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Vladimir Davydov authored and Linus Torvalds committed Jan 24, 2014
1 parent 309381f commit 3965fc3
Showing 1 changed file with 31 additions and 34 deletions.
65 changes: 31 additions & 34 deletions mm/slab_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -236,11 +230,14 @@ kmem_cache_create_memcg(struct mem_cgroup *memcg, const char *name, size_t size,
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 *
Expand Down

0 comments on commit 3965fc3

Please sign in to comment.