|
@@ -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 *
|