Skip to content

Commit

Permalink
cgroup: kill and release paths serialize
Browse files Browse the repository at this point in the history
Signed-off-by: Tadeusz Struk <tadeusz.struk@linaro.org>
Change-Id: Ibb30852f14b5e1cb6715eb30da7bbfbcd876c24b
  • Loading branch information
tstruk committed Jun 3, 2022
1 parent 17d8e3d commit c0f1b2f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/linux/cgroup-defs.h
Expand Up @@ -53,6 +53,8 @@ enum {
CSS_RELEASED = (1 << 2), /* refcnt reached zero, released */
CSS_VISIBLE = (1 << 3), /* css is visible to userland */
CSS_DYING = (1 << 4), /* css is dying */
CSS_KILL_ENQED = (1 << 5), /* css is dying */
CSS_NEED_RELESE = (1 << 6), /* css is dying */
};

/* bits in struct cgroup flags field */
Expand Down
22 changes: 19 additions & 3 deletions kernel/cgroup/cgroup.c
Expand Up @@ -5210,8 +5210,14 @@ static void css_release(struct percpu_ref *ref)
struct cgroup_subsys_state *css =
container_of(ref, struct cgroup_subsys_state, refcnt);

INIT_WORK(&css->destroy_work, css_release_work_fn);
queue_work(cgroup_destroy_wq, &css->destroy_work);
if (!(css->flags & CSS_KILL_ENQED)) {
printk("!!!! css_release css %llx release enqueue\n", css);
INIT_WORK(&css->destroy_work, css_release_work_fn);
queue_work(cgroup_destroy_wq, &css->destroy_work);
} else {
printk("!!!! css_release css %llx release postopne\n", css);
css->flags |= CSS_NEED_RELESE;
}
}

static void init_and_link_css(struct cgroup_subsys_state *css,
Expand Down Expand Up @@ -5545,10 +5551,12 @@ int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode)
*/
static void css_killed_work_fn(struct work_struct *work)
{
struct cgroup_subsys_state *css =
struct cgroup_subsys_state *css_killed, *css =
container_of(work, struct cgroup_subsys_state, destroy_work);

mutex_lock(&cgroup_mutex);
css_killed = css;
css_killed->flags &= ~CSS_KILL_ENQED;

do {
offline_css(css);
Expand All @@ -5557,6 +5565,13 @@ static void css_killed_work_fn(struct work_struct *work)
css = css->parent;
} while (css && atomic_dec_and_test(&css->online_cnt));

if (css_killed->flags & CSS_NEED_RELESE) {
printk("!!!! css_killed now releasing css %llx \n", css_killed);
INIT_WORK(&css_killed->destroy_work, css_release_work_fn);
queue_work(cgroup_destroy_wq, &css_killed->destroy_work);
css_killed->flags &= ~CSS_NEED_RELESE;
}

mutex_unlock(&cgroup_mutex);
}

Expand All @@ -5567,6 +5582,7 @@ static void css_killed_ref_fn(struct percpu_ref *ref)
container_of(ref, struct cgroup_subsys_state, refcnt);

if (atomic_dec_and_test(&css->online_cnt)) {
css->flags |= CSS_KILL_ENQED;
INIT_WORK(&css->destroy_work, css_killed_work_fn);
queue_work(cgroup_destroy_wq, &css->destroy_work);
}
Expand Down

0 comments on commit c0f1b2f

Please sign in to comment.