Skip to content

Commit 74dc629

Browse files
Sebastian Andrzej Siewiorjnettlet
authored andcommitted
cgroups: use simple wait in css_release()
To avoid: |BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:914 |in_atomic(): 1, irqs_disabled(): 0, pid: 92, name: rcuc/11 |2 locks held by rcuc/11/92: | #0: (rcu_callback){......}, at: [<ffffffff810e037e>] rcu_cpu_kthread+0x3de/0x940 | #1: (rcu_read_lock_sched){......}, at: [<ffffffff81328390>] percpu_ref_call_confirm_rcu+0x0/0xd0 |Preemption disabled at:[<ffffffff813284e2>] percpu_ref_switch_to_atomic_rcu+0x82/0xc0 |CPU: 11 PID: 92 Comm: rcuc/11 Not tainted 3.18.7-rt0+ #1 | ffff8802398cdf80 ffff880235f0bc28 ffffffff815b3a12 0000000000000000 | 0000000000000000 ffff880235f0bc48 ffffffff8109aa16 0000000000000000 | ffff8802398cdf80 ffff880235f0bc78 ffffffff815b8dd4 000000000000df80 |Call Trace: | [<ffffffff815b3a12>] dump_stack+0x4f/0x7c | [<ffffffff8109aa16>] __might_sleep+0x116/0x190 | [<ffffffff815b8dd4>] rt_spin_lock+0x24/0x60 | [<ffffffff8108d2cd>] queue_work_on+0x6d/0x1d0 | [<ffffffff8110c881>] css_release+0x81/0x90 | [<ffffffff8132844e>] percpu_ref_call_confirm_rcu+0xbe/0xd0 | [<ffffffff813284e2>] percpu_ref_switch_to_atomic_rcu+0x82/0xc0 | [<ffffffff810e03e5>] rcu_cpu_kthread+0x445/0x940 | [<ffffffff81098a2d>] smpboot_thread_fn+0x18d/0x2d0 | [<ffffffff810948d8>] kthread+0xe8/0x100 | [<ffffffff815b9c3c>] ret_from_fork+0x7c/0xb0 Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
1 parent fa5af40 commit 74dc629

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

include/linux/cgroup-defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/percpu-refcount.h>
1717
#include <linux/percpu-rwsem.h>
1818
#include <linux/workqueue.h>
19+
#include <linux/swork.h>
1920

2021
#ifdef CONFIG_CGROUPS
2122

@@ -138,6 +139,7 @@ struct cgroup_subsys_state {
138139
/* percpu_ref killing and RCU release */
139140
struct rcu_head rcu_head;
140141
struct work_struct destroy_work;
142+
struct swork_event destroy_swork;
141143
};
142144

143145
/*

kernel/cgroup.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5041,10 +5041,10 @@ static void css_free_rcu_fn(struct rcu_head *rcu_head)
50415041
queue_work(cgroup_destroy_wq, &css->destroy_work);
50425042
}
50435043

5044-
static void css_release_work_fn(struct work_struct *work)
5044+
static void css_release_work_fn(struct swork_event *sev)
50455045
{
50465046
struct cgroup_subsys_state *css =
5047-
container_of(work, struct cgroup_subsys_state, destroy_work);
5047+
container_of(sev, struct cgroup_subsys_state, destroy_swork);
50485048
struct cgroup_subsys *ss = css->ss;
50495049
struct cgroup *cgrp = css->cgroup;
50505050

@@ -5087,8 +5087,8 @@ static void css_release(struct percpu_ref *ref)
50875087
struct cgroup_subsys_state *css =
50885088
container_of(ref, struct cgroup_subsys_state, refcnt);
50895089

5090-
INIT_WORK(&css->destroy_work, css_release_work_fn);
5091-
queue_work(cgroup_destroy_wq, &css->destroy_work);
5090+
INIT_SWORK(&css->destroy_swork, css_release_work_fn);
5091+
swork_queue(&css->destroy_swork);
50925092
}
50935093

50945094
static void init_and_link_css(struct cgroup_subsys_state *css,
@@ -5749,6 +5749,7 @@ static int __init cgroup_wq_init(void)
57495749
*/
57505750
cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1);
57515751
BUG_ON(!cgroup_destroy_wq);
5752+
BUG_ON(swork_get());
57525753

57535754
/*
57545755
* Used to destroy pidlists and separate to serve as flush domain.

0 commit comments

Comments
 (0)