cgroup: use a standalone workqueue for killing css
Upstream: pending A race is observed when V1 and V2 is comounted, queued work on cgroup_destroy_wq may get over written before get executed, leave cgroup dying without being offlined, and hung the system. Avoid such problem by using a standalone queue. Signed-off-by: Kairui Song <kasong@tencent.com>
This commit is contained in:
parent
d7a3720248
commit
5411485b92
|
@ -192,6 +192,7 @@ struct cgroup_subsys_state {
|
|||
atomic_t online_cnt;
|
||||
|
||||
/* percpu_ref killing and RCU release */
|
||||
struct work_struct kill_work;
|
||||
struct work_struct destroy_work;
|
||||
struct rcu_work destroy_rwork;
|
||||
|
||||
|
|
|
@ -125,6 +125,7 @@ DEFINE_PERCPU_RWSEM(cgroup_threadgroup_rwsem);
|
|||
* which may lead to deadlock.
|
||||
*/
|
||||
static struct workqueue_struct *cgroup_destroy_wq;
|
||||
static struct workqueue_struct *cgroup_kill_wq;
|
||||
|
||||
/* generate an array of cgroup subsystem pointers */
|
||||
#define SUBSYS(_x) [_x ## _cgrp_id] = &_x ## _cgrp_subsys,
|
||||
|
@ -3077,7 +3078,6 @@ restart:
|
|||
cgroup_get_live(dsct);
|
||||
prepare_to_wait(&dsct->offline_waitq, &wait,
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
|
||||
cgroup_unlock();
|
||||
schedule();
|
||||
finish_wait(&dsct->offline_waitq, &wait);
|
||||
|
@ -5511,6 +5511,7 @@ static void offline_css(struct cgroup_subsys_state *css)
|
|||
ss->css_offline(css);
|
||||
|
||||
css->flags &= ~CSS_ONLINE;
|
||||
|
||||
RCU_INIT_POINTER(css->cgroup->subsys[ss->id], NULL);
|
||||
|
||||
wake_up_all(&css->cgroup->offline_waitq);
|
||||
|
@ -5778,7 +5779,7 @@ out_unlock:
|
|||
static void css_killed_work_fn(struct work_struct *work)
|
||||
{
|
||||
struct cgroup_subsys_state *css =
|
||||
container_of(work, struct cgroup_subsys_state, destroy_work);
|
||||
container_of(work, struct cgroup_subsys_state, kill_work);
|
||||
|
||||
cgroup_lock();
|
||||
|
||||
|
@ -5799,8 +5800,8 @@ 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)) {
|
||||
INIT_WORK(&css->destroy_work, css_killed_work_fn);
|
||||
queue_work(cgroup_destroy_wq, &css->destroy_work);
|
||||
INIT_WORK(&css->kill_work, css_killed_work_fn);
|
||||
queue_work(cgroup_kill_wq, &css->kill_work);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6173,6 +6174,8 @@ static int __init cgroup_wq_init(void)
|
|||
*/
|
||||
cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1);
|
||||
BUG_ON(!cgroup_destroy_wq);
|
||||
cgroup_kill_wq = alloc_workqueue("cgroup_kill", 0, 1);
|
||||
BUG_ON(!cgroup_kill_wq);
|
||||
return 0;
|
||||
}
|
||||
core_initcall(cgroup_wq_init);
|
||||
|
|
Loading…
Reference in New Issue