forked from mirrors/linux
		
	cgroup: Fixes for v6.12-rc5
- 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. -----BEGIN PGP SIGNATURE----- iIQEABYKACwWIQTfIjM1kS57o3GsC/uxYfJx3gVYGQUCZyGCPA4cdGpAa2VybmVs Lm9yZwAKCRCxYfJx3gVYGS2MAQDmtRNBlDYl36fiLAsylU4Coz5P0Y4ISmtSWT+c zrEUZAD/WKSlCfy4RFngmnfkYbrJ+tWOVTMtsDqby8IzYLDGBw8= =glRQ -----END PGP SIGNATURE----- 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
This commit is contained in:
		
						commit
						c1e939a21e
					
				
					 2 changed files with 20 additions and 3 deletions
				
			
		|  | @ -24,6 +24,23 @@ | |||
| DEFINE_STATIC_KEY_ARRAY_FALSE(cgroup_bpf_enabled_key, MAX_CGROUP_BPF_ATTACH_TYPE); | ||||
| EXPORT_SYMBOL(cgroup_bpf_enabled_key); | ||||
| 
 | ||||
| /*
 | ||||
|  * cgroup bpf destruction makes heavy use of work items and there can be a lot | ||||
|  * of concurrent destructions.  Use a separate workqueue so that cgroup bpf | ||||
|  * destruction work items don't end up filling up max_active of system_wq | ||||
|  * which may lead to deadlock. | ||||
|  */ | ||||
| static struct workqueue_struct *cgroup_bpf_destroy_wq; | ||||
| 
 | ||||
| static int __init cgroup_bpf_wq_init(void) | ||||
| { | ||||
| 	cgroup_bpf_destroy_wq = alloc_workqueue("cgroup_bpf_destroy", 0, 1); | ||||
| 	if (!cgroup_bpf_destroy_wq) | ||||
| 		panic("Failed to alloc workqueue for cgroup bpf destroy.\n"); | ||||
| 	return 0; | ||||
| } | ||||
| core_initcall(cgroup_bpf_wq_init); | ||||
| 
 | ||||
| /* __always_inline is necessary to prevent indirect call through run_prog
 | ||||
|  * function pointer. | ||||
|  */ | ||||
|  | @ -334,7 +351,7 @@ static void cgroup_bpf_release_fn(struct percpu_ref *ref) | |||
| 	struct cgroup *cgrp = container_of(ref, struct cgroup, bpf.refcnt); | ||||
| 
 | ||||
| 	INIT_WORK(&cgrp->bpf.release_work, cgroup_bpf_release); | ||||
| 	queue_work(system_wq, &cgrp->bpf.release_work); | ||||
| 	queue_work(cgroup_bpf_destroy_wq, &cgrp->bpf.release_work); | ||||
| } | ||||
| 
 | ||||
| /* Get underlying bpf_prog of bpf_prog_list entry, regardless if it's through
 | ||||
|  |  | |||
|  | @ -5789,7 +5789,7 @@ static bool cgroup_check_hierarchy_limits(struct cgroup *parent) | |||
| { | ||||
| 	struct cgroup *cgroup; | ||||
| 	int ret = false; | ||||
| 	int level = 1; | ||||
| 	int level = 0; | ||||
| 
 | ||||
| 	lockdep_assert_held(&cgroup_mutex); | ||||
| 
 | ||||
|  | @ -5797,7 +5797,7 @@ static bool cgroup_check_hierarchy_limits(struct cgroup *parent) | |||
| 		if (cgroup->nr_descendants >= cgroup->max_descendants) | ||||
| 			goto fail; | ||||
| 
 | ||||
| 		if (level > cgroup->max_depth) | ||||
| 		if (level >= cgroup->max_depth) | ||||
| 			goto fail; | ||||
| 
 | ||||
| 		level++; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Linus Torvalds
						Linus Torvalds