cgroup_attach_lock(9)
π cgroup_attach_lock(9) β a Kernel API Manual moment
okay so bestie, you're in the Kernel API Manual, and today's main character is cgroup_attach_lock. yes, the lock for ->attach(). let's get into it π
β¨ NAME β¨
cgroup_attach_lock β the lock for ->attach() π
β¨ SYNOPSIS β¨
void cgroup_attach_lock (enum cgroup_attach_lock_mode lock_mode , struct
task_struct *tsk );
β¨ ARGUMENTS β¨
lock_modeβ tells us whether to acquire a rwsem, and which rwsem to acquire. yes it's doing both jobs, she's multitasking πtskβ the thread group to lock π«Ά
β¨ DESCRIPTION β¨
so, cgroup migration sometimes needs to stabilize threadgroups against forks and exits by write-locking cgroup_threadgroup_rwsem. makes sense, right? you're moving stuff around, you don't want the threadgroup wiggling out from under you.
but here's the plot twist π β some ->attach implementations (looking at you, cpuset) also need to disable CPU hotplug. and unfortunately, letting ->attach operations acquire cpus_read_lock can lead to deadlocks. not cute. not slay. genuinely bad vibes.
here's why, bestie, because the nesting goes the wrong way π:
bringing up a CPU may involve creating and destroying tasks, and that requires read-locking threadgroup_rwsem. so threadgroup_rwsem nests inside cpus_read_lock. if we call an ->attach which acquires the cpus lock while write-locking threadgroup_rwsem, the locking order is reversed and we end up waiting for an on-going CPU hotplug operation β which in turn is waiting for the threadgroup_rwsem to be released so it can create new tasks. deadlock city, population: us π
for more details:
http://lkml.kernel.org/r/20220711174629.uehfmqegcwn2lqzuwubuntu
so how do we resolve the situation? π‘ by always acquiring cpus_read_lock before optionally write-locking cgroup_threadgroup_rwsem. that's it, that's the fix. this allows ->attach to assume that CPU hotplug is disabled on entry. iconic behavior, honestly π
also! when favordynmods is enabled, take per threadgroup rwsem to reduce overhead on dynamic cgroup modifications. see the comment above the CGRP_ROOT_FAVOR_DYNMODS definition πΈ
and one last little note: tsk is not NULL only when writing to cgroup.procs. no cap. π
β¨ SEE ALSO β¨
kernel file ./kernel/cgroup/cgroup.c π β and here's the whole friend group, everybody say hi:
cgroup_ssid_enabled(9), cgroup_on_dfl(9), cgroup_e_css_by_mask(9), cgroup_e_css(9), cgroup_get_e_css(9), __cgroup_task_count(9), cgroup_task_count(9), for_each_css(9), do_each_subsys_mask(9), css_set_populated(9), css_update_populated(9), css_set_update_populated(9), css_set_move_task(9), compare_css_sets(9), find_existing_css_set(9), allocate_cgrp_cset_links(9), link_css_set(9), find_css_set(9), cgroup_file_mode(9), cgroup_calc_subtree_ss_mask(9), cgroup_kn_unlock(9), cgroup_kn_lock_live(9), css_clear_dir(9), css_populate_dir(9), cgroup_attach_unlock(9), cgroup_migrate_add_task(9), cgroup_taskset_first(9), cgroup_taskset_next(9), cgroup_migrate_execute(9), cgroup_migrate_vet_dst(9), cgroup_migrate_finish(9), cgroup_migrate_add_src(9), cgroup_migrate_prepare_dst(9), cgroup_migrate(9), cgroup_attach_task(9), cgroup_update_dfl_csses(9), cgroup_lock_and_drain_offline(9), cgroup_save_control(9), cgroup_propagate_control(9), cgroup_restore_control(9), cgroup_apply_control_enable(9), cgroup_apply_control_disable(9), cgroup_apply_control(9), cgroup_finalize_control(9), cgroup_enable_threaded(9), cgroup_tryget_css(9), cgroup_addrm_files(9), cgroup_rm_cftypes(9), cgroup_add_cftypes(9), cgroup_add_dfl_cftypes(9), cgroup_add_legacy_cftypes(9), cgroup_file_notify(9), cgroup_file_show(9), css_next_child(9), css_next_descendant_pre(9), css_rightmost_descendant(9), css_next_descendant_post(9), css_has_online_children(9), css_task_iter_advance_css_set(9), css_task_iter_start(9), css_task_iter_next(9), css_task_iter_end(9), css_create(9), kill_css_sync(9), kill_css_finish(9), cgroup_destroy_locked(9), cgroup_init_early(9), cgroup_init(9), cgroup_fork(9), cgroup_v1v2_get_from_file(9), cgroup_get_from_file(9), cgroup_css_set_fork(9), cgroup_css_set_put_fork(9), cgroup_can_fork(9), cgroup_cancel_fork(9), cgroup_post_fork(9), cgroup_task_exit(9), css_tryget_online_from_dir(9), css_from_id(9), cgroup_get_from_path(9), cgroup_v1v2_get_from_fd(9), cgroup_get_from_fd(9), cgroup_parse_float(9)
bestie please remember: release the rwsem, respect the locking order, and never let ->attach grab the cpus lock while you're holding the write lock. that's the whole personality of this function π
and that's a wrap, babe π¦ this page came from the source ./kernel/cgroup, dated October 2026, and it's filed under cgroup_attach_lock(9). mwah π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms