Skip to content

Commit

Permalink
css_put imbalance
Browse files Browse the repository at this point in the history
Signed-off-by: Tadeusz Struk <tadeusz.struk@linaro.org>
Change-Id: Iaeb4843ec0b4b181e0c969e8af0a94757e5c8187
  • Loading branch information
tstruk committed Jun 2, 2022
1 parent 17d8e3d commit 1de342b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
3 changes: 3 additions & 0 deletions include/linux/cgroup-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ struct cgroup_subsys_state {
struct work_struct destroy_work;
struct rcu_work destroy_rwork;

/* To serialize kill and release paths for the css */
struct completion complete;

/*
* PI: the parent css. Placed here for cache proximity to following
* fields of the containing structure.
Expand Down
33 changes: 32 additions & 1 deletion kernel/cgroup/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1592,6 +1592,13 @@ void cgroup_kn_unlock(struct kernfs_node *kn)
mutex_unlock(&cgroup_mutex);

kernfs_unbreak_active_protection(kn);
/* If css_kill started for this css wait for it to finish */
if (cgrp->self.flags & CSS_DYING) {
printk("!!!! cgroup_kn_unlock WAITING for comp !!! \n");
WARN(!wait_for_completion_timeout(&cgrp->self.complete, msecs_to_jiffies(1000)),
"Timed out waiting for css_killed_ref_fn to finish");
}

cgroup_put(cgrp);
}

Expand Down Expand Up @@ -1992,7 +1999,8 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
int i, ret;

lockdep_assert_held(&cgroup_mutex);

printk("!!! cgroup_setup_root init_comp %llx !!! \n", &root_cgrp->self);
init_completion(&root_cgrp->self.complete);
ret = percpu_ref_init(&root_cgrp->self.refcnt, css_release,
0, GFP_KERNEL);
if (ret)
Expand Down Expand Up @@ -5109,6 +5117,7 @@ static void css_free_rwork_fn(struct work_struct *work)
struct cgroup_subsys *ss = css->ss;
struct cgroup *cgrp = css->cgroup;

printk("!!!!!!!!! css_free_rwork_fn css = %llx !!!!!!\n", css);
percpu_ref_exit(&css->refcnt);

if (ss) {
Expand Down Expand Up @@ -5210,6 +5219,7 @@ static void css_release(struct percpu_ref *ref)
struct cgroup_subsys_state *css =
container_of(ref, struct cgroup_subsys_state, refcnt);

printk("!!!! css_release css = %llx !!!\n", css);
INIT_WORK(&css->destroy_work, css_release_work_fn);
queue_work(cgroup_destroy_wq, &css->destroy_work);
}
Expand Down Expand Up @@ -5307,6 +5317,8 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
if (IS_ERR(css))
return css;

printk("!!! css_create init_comp %llx !!! \n", css);
init_completion(&css->complete);
init_and_link_css(css, ss, cgrp);

err = percpu_ref_init(&css->refcnt, css_release, 0, GFP_KERNEL);
Expand All @@ -5331,6 +5343,7 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
err_list_del:
list_del_rcu(&css->sibling);
err_free_css:
printk("!!! css_create ERROR init_comp %llx !!! \n", css);
list_del_rcu(&css->rstat_css_node);
INIT_RCU_WORK(&css->destroy_rwork, css_free_rwork_fn);
queue_rcu_work(cgroup_destroy_wq, &css->destroy_rwork);
Expand Down Expand Up @@ -5373,6 +5386,8 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
}
cgrp->kn = kn;

printk("!!! cgroup_create init_comp %llx !!! \n", &cgrp->self);
init_completion(&cgrp->self.complete);
init_cgroup_housekeeping(cgrp);

cgrp->self.parent = &parent->self;
Expand Down Expand Up @@ -5549,6 +5564,13 @@ static void css_killed_work_fn(struct work_struct *work)
container_of(work, struct cgroup_subsys_state, destroy_work);

mutex_lock(&cgroup_mutex);
printk("!!!! css_killed_work_fn css = %llx comp %llx !!!\n", css, &css->complete);

if (!(css->flags & CSS_RELEASED)) {
complete(&css->complete);
} else {
printk("!!!! css_killed_work_fn css = %llx comp %llx ALREADY RELEASED !!!\n", css, &css->complete);
}

do {
offline_css(css);
Expand All @@ -5566,9 +5588,12 @@ static void css_killed_ref_fn(struct percpu_ref *ref)
struct cgroup_subsys_state *css =
container_of(ref, struct cgroup_subsys_state, refcnt);

printk("!!!! css_killed_ref_fn css = %llx !!!\n", css);
if (atomic_dec_and_test(&css->online_cnt)) {
INIT_WORK(&css->destroy_work, css_killed_work_fn);
queue_work(cgroup_destroy_wq, &css->destroy_work);
} else {
complete(&css->complete);
}
}

Expand All @@ -5588,6 +5613,8 @@ static void kill_css(struct cgroup_subsys_state *css)
if (css->flags & CSS_DYING)
return;

printk("!!! kill_css reinit_comp %llx !!! \n", css);
init_completion(&css->complete);
css->flags |= CSS_DYING;

/*
Expand Down Expand Up @@ -5772,6 +5799,8 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
* newly registered, all tasks and hence the
* init_css_set is in the subsystem's root cgroup. */
init_css_set.subsys[ss->id] = css;
printk("!!! cgroup_init_subsys init_comp %llx !!! \n", css);
init_completion(&css->complete);

have_fork_callback |= (bool)ss->fork << ss->id;
have_exit_callback |= (bool)ss->exit << ss->id;
Expand Down Expand Up @@ -5875,6 +5904,8 @@ int __init cgroup_init(void)
cgroup_init_subsys(ss, false);
}

printk("!!! cgroup_init init_comp %llx !!! \n", &init_css_set.subsys[ssid]);
init_completion(&init_css_set.subsys[ssid]->complete);
list_add_tail(&init_css_set.e_cset_node[ssid],
&cgrp_dfl_root.cgrp.e_csets[ssid]);

Expand Down
1 change: 0 additions & 1 deletion kernel/sched/completion.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
void complete(struct completion *x)
{
unsigned long flags;

raw_spin_lock_irqsave(&x->wait.lock, flags);

if (x->done != UINT_MAX)
Expand Down

0 comments on commit 1de342b

Please sign in to comment.