Skip to content

Commit c1e939a

Browse files
committed
Merge tag 'cgroup-for-6.12-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup fixes from Tejun Heo: - cgroup_bpf_release_fn() could saturate system_wq with cgrp->bpf.release_work which can then form a circular dependency leading to deadlocks. Fix by using a dedicated workqueue. The system_wq's max concurrency limit is being increased separately. - Fix theoretical off-by-one bug when enforcing max cgroup hierarchy depth * tag 'cgroup-for-6.12-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup: Fix potential overflow issue when checking max_depth cgroup/bpf: use a dedicated workqueue for cgroup bpf destruction
2 parents daa9f66 + 3cc4e13 commit c1e939a

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

kernel/bpf/cgroup.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,23 @@
2424
DEFINE_STATIC_KEY_ARRAY_FALSE(cgroup_bpf_enabled_key, MAX_CGROUP_BPF_ATTACH_TYPE);
2525
EXPORT_SYMBOL(cgroup_bpf_enabled_key);
2626

27+
/*
28+
* cgroup bpf destruction makes heavy use of work items and there can be a lot
29+
* of concurrent destructions. Use a separate workqueue so that cgroup bpf
30+
* destruction work items don't end up filling up max_active of system_wq
31+
* which may lead to deadlock.
32+
*/
33+
static struct workqueue_struct *cgroup_bpf_destroy_wq;
34+
35+
static int __init cgroup_bpf_wq_init(void)
36+
{
37+
cgroup_bpf_destroy_wq = alloc_workqueue("cgroup_bpf_destroy", 0, 1);
38+
if (!cgroup_bpf_destroy_wq)
39+
panic("Failed to alloc workqueue for cgroup bpf destroy.\n");
40+
return 0;
41+
}
42+
core_initcall(cgroup_bpf_wq_init);
43+
2744
/* __always_inline is necessary to prevent indirect call through run_prog
2845
* function pointer.
2946
*/
@@ -334,7 +351,7 @@ static void cgroup_bpf_release_fn(struct percpu_ref *ref)
334351
struct cgroup *cgrp = container_of(ref, struct cgroup, bpf.refcnt);
335352

336353
INIT_WORK(&cgrp->bpf.release_work, cgroup_bpf_release);
337-
queue_work(system_wq, &cgrp->bpf.release_work);
354+
queue_work(cgroup_bpf_destroy_wq, &cgrp->bpf.release_work);
338355
}
339356

340357
/* Get underlying bpf_prog of bpf_prog_list entry, regardless if it's through

kernel/cgroup/cgroup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5789,15 +5789,15 @@ static bool cgroup_check_hierarchy_limits(struct cgroup *parent)
57895789
{
57905790
struct cgroup *cgroup;
57915791
int ret = false;
5792-
int level = 1;
5792+
int level = 0;
57935793

57945794
lockdep_assert_held(&cgroup_mutex);
57955795

57965796
for (cgroup = parent; cgroup; cgroup = cgroup_parent(cgroup)) {
57975797
if (cgroup->nr_descendants >= cgroup->max_descendants)
57985798
goto fail;
57995799

5800-
if (level > cgroup->max_depth)
5800+
if (level >= cgroup->max_depth)
58015801
goto fail;
58025802

58035803
level++;

0 commit comments

Comments
 (0)