aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorVladimir Davydov <vdavydov@parallels.com>2014-04-07 18:39:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-07 19:36:12 -0400
commit5722d094ad2b56fa2c1cb3adaf40071a55bbf242 (patch)
treefbae9cdc8bf4d92d2ac268cf761b5f25c5ad6ef9 /mm
parenta44cb9449182fd7b25bf5f1cc38b7f19e0b96f6d (diff)
memcg, slab: cleanup memcg cache creation
This patch cleans up the memcg cache creation path as follows: - Move memcg cache name creation to a separate function to be called from kmem_cache_create_memcg(). This allows us to get rid of the mutex protecting the temporary buffer used for the name formatting, because the whole cache creation path is protected by the slab_mutex. - Get rid of memcg_create_kmem_cache(). This function serves as a proxy to kmem_cache_create_memcg(). After separating the cache name creation path, it would be reduced to a function call, so let's inline it. Signed-off-by: Vladimir Davydov <vdavydov@parallels.com> Cc: Michal Hocko <mhocko@suse.cz> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: David Rientjes <rientjes@google.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: Glauber Costa <glommer@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c89
-rw-r--r--mm/slab_common.c5
2 files changed, 43 insertions, 51 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index e33b1d09eb1f..32c7342df4bf 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3094,6 +3094,29 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups)
3094 return 0; 3094 return 0;
3095} 3095}
3096 3096
3097char *memcg_create_cache_name(struct mem_cgroup *memcg,
3098 struct kmem_cache *root_cache)
3099{
3100 static char *buf = NULL;
3101
3102 /*
3103 * We need a mutex here to protect the shared buffer. Since this is
3104 * expected to be called only on cache creation, we can employ the
3105 * slab_mutex for that purpose.
3106 */
3107 lockdep_assert_held(&slab_mutex);
3108
3109 if (!buf) {
3110 buf = kmalloc(NAME_MAX + 1, GFP_KERNEL);
3111 if (!buf)
3112 return NULL;
3113 }
3114
3115 cgroup_name(memcg->css.cgroup, buf, NAME_MAX + 1);
3116 return kasprintf(GFP_KERNEL, "%s(%d:%s)", root_cache->name,
3117 memcg_cache_id(memcg), buf);
3118}
3119
3097int memcg_alloc_cache_params(struct mem_cgroup *memcg, struct kmem_cache *s, 3120int memcg_alloc_cache_params(struct mem_cgroup *memcg, struct kmem_cache *s,
3098 struct kmem_cache *root_cache) 3121 struct kmem_cache *root_cache)
3099{ 3122{
@@ -3298,46 +3321,6 @@ void mem_cgroup_destroy_cache(struct kmem_cache *cachep)
3298 schedule_work(&cachep->memcg_params->destroy); 3321 schedule_work(&cachep->memcg_params->destroy);
3299} 3322}
3300 3323
3301static struct kmem_cache *memcg_create_kmem_cache(struct mem_cgroup *memcg,
3302 struct kmem_cache *s)
3303{
3304 struct kmem_cache *new = NULL;
3305 static char *tmp_path = NULL, *tmp_name = NULL;
3306 static DEFINE_MUTEX(mutex); /* protects tmp_name */
3307
3308 BUG_ON(!memcg_can_account_kmem(memcg));
3309
3310 mutex_lock(&mutex);
3311 /*
3312 * kmem_cache_create_memcg duplicates the given name and
3313 * cgroup_name for this name requires RCU context.
3314 * This static temporary buffer is used to prevent from
3315 * pointless shortliving allocation.
3316 */
3317 if (!tmp_path || !tmp_name) {
3318 if (!tmp_path)
3319 tmp_path = kmalloc(PATH_MAX, GFP_KERNEL);
3320 if (!tmp_name)
3321 tmp_name = kmalloc(NAME_MAX + 1, GFP_KERNEL);
3322 if (!tmp_path || !tmp_name)
3323 goto out;
3324 }
3325
3326 cgroup_name(memcg->css.cgroup, tmp_name, NAME_MAX + 1);
3327 snprintf(tmp_path, PATH_MAX, "%s(%d:%s)", s->name,
3328 memcg_cache_id(memcg), tmp_name);
3329
3330 new = kmem_cache_create_memcg(memcg, tmp_path, s->object_size, s->align,
3331 (s->flags & ~SLAB_PANIC), s->ctor, s);
3332 if (new)
3333 new->allocflags |= __GFP_KMEMCG;
3334 else
3335 new = s;
3336out:
3337 mutex_unlock(&mutex);
3338 return new;
3339}
3340
3341void kmem_cache_destroy_memcg_children(struct kmem_cache *s) 3324void kmem_cache_destroy_memcg_children(struct kmem_cache *s)
3342{ 3325{
3343 struct kmem_cache *c; 3326 struct kmem_cache *c;
@@ -3384,12 +3367,6 @@ void kmem_cache_destroy_memcg_children(struct kmem_cache *s)
3384 mutex_unlock(&activate_kmem_mutex); 3367 mutex_unlock(&activate_kmem_mutex);
3385} 3368}
3386 3369
3387struct create_work {
3388 struct mem_cgroup *memcg;
3389 struct kmem_cache *cachep;
3390 struct work_struct work;
3391};
3392
3393static void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg) 3370static void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg)
3394{ 3371{
3395 struct kmem_cache *cachep; 3372 struct kmem_cache *cachep;
@@ -3407,13 +3384,25 @@ static void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg)
3407 mutex_unlock(&memcg->slab_caches_mutex); 3384 mutex_unlock(&memcg->slab_caches_mutex);
3408} 3385}
3409 3386
3387struct create_work {
3388 struct mem_cgroup *memcg;
3389 struct kmem_cache *cachep;
3390 struct work_struct work;
3391};
3392
3410static void memcg_create_cache_work_func(struct work_struct *w) 3393static void memcg_create_cache_work_func(struct work_struct *w)
3411{ 3394{
3412 struct create_work *cw; 3395 struct create_work *cw = container_of(w, struct create_work, work);
3396 struct mem_cgroup *memcg = cw->memcg;
3397 struct kmem_cache *cachep = cw->cachep;
3398 struct kmem_cache *new;
3413 3399
3414 cw = container_of(w, struct create_work, work); 3400 new = kmem_cache_create_memcg(memcg, cachep->name,
3415 memcg_create_kmem_cache(cw->memcg, cw->cachep); 3401 cachep->object_size, cachep->align,
3416 css_put(&cw->memcg->css); 3402 cachep->flags & ~SLAB_PANIC, cachep->ctor, cachep);
3403 if (new)
3404 new->allocflags |= __GFP_KMEMCG;
3405 css_put(&memcg->css);
3417 kfree(cw); 3406 kfree(cw);
3418} 3407}
3419 3408
diff --git a/mm/slab_common.c b/mm/slab_common.c
index e77b51eb7347..11857abf7057 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -215,7 +215,10 @@ kmem_cache_create_memcg(struct mem_cgroup *memcg, const char *name, size_t size,
215 s->align = calculate_alignment(flags, align, size); 215 s->align = calculate_alignment(flags, align, size);
216 s->ctor = ctor; 216 s->ctor = ctor;
217 217
218 s->name = kstrdup(name, GFP_KERNEL); 218 if (memcg)
219 s->name = memcg_create_cache_name(memcg, parent_cache);
220 else
221 s->name = kstrdup(name, GFP_KERNEL);
219 if (!s->name) 222 if (!s->name)
220 goto out_free_cache; 223 goto out_free_cache;
221 224