mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
sched_ext: Defer sub_kset base put to scx_sched_free_rcu_work
scx_sub_enable_workfn() pins parent->kobj before dropping scx_sched_lock,
but that does not pin parent->sub_kset. Concurrent disable can
kset_unregister and free sub_kset before scx_alloc_and_add_sched()
dereferences it.
Split sub_kset teardown: kobject_del() at disable keeps sysfs removal; defer
kobject_put() to scx_sched_free_rcu_work so the memory survives. A racing
child sees state_in_sysfs=0 with valid memory, sysfs_create_dir() fails, and
the existing exit_kind gate in scx_link_sched() turns it away with -ENOENT.
Fixes: 411d3ef1a7 ("sched_ext: Unregister sub_kset on scheduler disable")
Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
b273b75b8d
commit
cceb874eee
|
|
@ -4821,6 +4821,8 @@ static void scx_sched_free_rcu_work(struct work_struct *work)
|
|||
kfree(sch->cgrp_path);
|
||||
if (sch_cgroup(sch))
|
||||
cgroup_put(sch_cgroup(sch));
|
||||
if (sch->sub_kset)
|
||||
kobject_put(&sch->sub_kset->kobj);
|
||||
#endif /* CONFIG_EXT_SUB_SCHED */
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
|
|
@ -5861,7 +5863,7 @@ static void scx_sub_disable(struct scx_sched *sch)
|
|||
if (sch->ops.exit)
|
||||
SCX_CALL_OP(sch, exit, NULL, sch->exit_info);
|
||||
if (sch->sub_kset)
|
||||
kset_unregister(sch->sub_kset);
|
||||
kobject_del(&sch->sub_kset->kobj);
|
||||
kobject_del(&sch->kobj);
|
||||
}
|
||||
#else /* CONFIG_EXT_SUB_SCHED */
|
||||
|
|
@ -5995,7 +5997,7 @@ static void scx_root_disable(struct scx_sched *sch)
|
|||
*/
|
||||
#ifdef CONFIG_EXT_SUB_SCHED
|
||||
if (sch->sub_kset)
|
||||
kset_unregister(sch->sub_kset);
|
||||
kobject_del(&sch->sub_kset->kobj);
|
||||
#endif
|
||||
kobject_del(&sch->kobj);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user