aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/slab_common.c65
1 files changed, 31 insertions, 34 deletions
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 0b7bb399b0e4..f70df3ef6f1a 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -171,13 +171,14 @@ kmem_cache_create_memcg(struct mem_cgroup *memcg, const char *name, size_t size,
171 struct kmem_cache *parent_cache) 171 struct kmem_cache *parent_cache)
172{ 172{
173 struct kmem_cache *s = NULL; 173 struct kmem_cache *s = NULL;
174 int err = 0; 174 int err;
175 175
176 get_online_cpus(); 176 get_online_cpus();
177 mutex_lock(&slab_mutex); 177 mutex_lock(&slab_mutex);
178 178
179 if (!kmem_cache_sanity_check(memcg, name, size) == 0) 179 err = kmem_cache_sanity_check(memcg, name, size);
180 goto out_locked; 180 if (err)
181 goto out_unlock;
181 182
182 /* 183 /*
183 * Some allocators will constraint the set of valid flags to a subset 184 * 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,
189 190
190 s = __kmem_cache_alias(memcg, name, size, align, flags, ctor); 191 s = __kmem_cache_alias(memcg, name, size, align, flags, ctor);
191 if (s) 192 if (s)
192 goto out_locked; 193 goto out_unlock;
193 194
195 err = -ENOMEM;
194 s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL); 196 s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL);
195 if (s) { 197 if (!s)
196 s->object_size = s->size = size; 198 goto out_unlock;
197 s->align = calculate_alignment(flags, align, size);
198 s->ctor = ctor;
199 199
200 if (memcg_register_cache(memcg, s, parent_cache)) { 200 s->object_size = s->size = size;
201 kmem_cache_free(kmem_cache, s); 201 s->align = calculate_alignment(flags, align, size);
202 err = -ENOMEM; 202 s->ctor = ctor;
203 goto out_locked;
204 }
205 203
206 s->name = kstrdup(name, GFP_KERNEL); 204 s->name = kstrdup(name, GFP_KERNEL);
207 if (!s->name) { 205 if (!s->name)
208 kmem_cache_free(kmem_cache, s); 206 goto out_free_cache;
209 err = -ENOMEM;
210 goto out_locked;
211 }
212 207
213 err = __kmem_cache_create(s, flags); 208 err = memcg_register_cache(memcg, s, parent_cache);
214 if (!err) { 209 if (err)
215 s->refcount = 1; 210 goto out_free_cache;
216 list_add(&s->list, &slab_caches); 211
217 memcg_cache_list_add(memcg, s); 212 err = __kmem_cache_create(s, flags);
218 } else { 213 if (err)
219 kfree(s->name); 214 goto out_free_cache;
220 kmem_cache_free(kmem_cache, s); 215
221 } 216 s->refcount = 1;
222 } else 217 list_add(&s->list, &slab_caches);
223 err = -ENOMEM; 218 memcg_cache_list_add(memcg, s);
224 219
225out_locked: 220out_unlock:
226 mutex_unlock(&slab_mutex); 221 mutex_unlock(&slab_mutex);
227 put_online_cpus(); 222 put_online_cpus();
228 223
229 if (err) { 224 if (err) {
230
231 if (flags & SLAB_PANIC) 225 if (flags & SLAB_PANIC)
232 panic("kmem_cache_create: Failed to create slab '%s'. Error %d\n", 226 panic("kmem_cache_create: Failed to create slab '%s'. Error %d\n",
233 name, err); 227 name, err);
@@ -236,11 +230,14 @@ out_locked:
236 name, err); 230 name, err);
237 dump_stack(); 231 dump_stack();
238 } 232 }
239
240 return NULL; 233 return NULL;
241 } 234 }
242
243 return s; 235 return s;
236
237out_free_cache:
238 kfree(s->name);
239 kmem_cache_free(kmem_cache, s);
240 goto out_unlock;
244} 241}
245 242
246struct kmem_cache * 243struct kmem_cache *