Commit 01e586598b224d1a427acd8a7afa0b21e879d3a7

Authored by Vladimir Davydov
Committed by Linus Torvalds
1 parent 426589f571

cgroup: release css->id after css_free

Currently, we release css->id in css_release_work_fn, right before calling
css_free callback, so that when css_free is called, the id may have
already been reused for a new cgroup.

I am going to use css->id to create unique names for per memcg kmem
caches.  Since kmem caches are destroyed only on css_free, I need css->id
to be freed after css_free was called to avoid name clashes.  This patch
therefore moves css->id removal to css_free_work_fn.  To prevent
css_from_id from returning a pointer to a stale css, it makes
css_release_work_fn replace the css ptr at css_idr:css->id with NULL.

Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Acked-by: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 7 additions and 3 deletions Side-by-side Diff

... ... @@ -4373,16 +4373,20 @@
4373 4373 {
4374 4374 struct cgroup_subsys_state *css =
4375 4375 container_of(work, struct cgroup_subsys_state, destroy_work);
  4376 + struct cgroup_subsys *ss = css->ss;
4376 4377 struct cgroup *cgrp = css->cgroup;
4377 4378  
4378 4379 percpu_ref_exit(&css->refcnt);
4379 4380  
4380   - if (css->ss) {
  4381 + if (ss) {
4381 4382 /* css free path */
  4383 + int id = css->id;
  4384 +
4382 4385 if (css->parent)
4383 4386 css_put(css->parent);
4384 4387  
4385   - css->ss->css_free(css);
  4388 + ss->css_free(css);
  4389 + cgroup_idr_remove(&ss->css_idr, id);
4386 4390 cgroup_put(cgrp);
4387 4391 } else {
4388 4392 /* cgroup free path */
... ... @@ -4434,7 +4438,7 @@
4434 4438  
4435 4439 if (ss) {
4436 4440 /* css release path */
4437   - cgroup_idr_remove(&ss->css_idr, css->id);
  4441 + cgroup_idr_replace(&ss->css_idr, NULL, css->id);
4438 4442 if (ss->css_released)
4439 4443 ss->css_released(css);
4440 4444 } else {