Skip to content

Commit cceb874

Browse files
committed
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: 411d3ef ("sched_ext: Unregister sub_kset on scheduler disable") Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent b273b75 commit cceb874

1 file changed

Lines changed: 4 additions & 2 deletions

File tree

kernel/sched/ext.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4821,6 +4821,8 @@ static void scx_sched_free_rcu_work(struct work_struct *work)
48214821
kfree(sch->cgrp_path);
48224822
if (sch_cgroup(sch))
48234823
cgroup_put(sch_cgroup(sch));
4824+
if (sch->sub_kset)
4825+
kobject_put(&sch->sub_kset->kobj);
48244826
#endif /* CONFIG_EXT_SUB_SCHED */
48254827

48264828
for_each_possible_cpu(cpu) {
@@ -5861,7 +5863,7 @@ static void scx_sub_disable(struct scx_sched *sch)
58615863
if (sch->ops.exit)
58625864
SCX_CALL_OP(sch, exit, NULL, sch->exit_info);
58635865
if (sch->sub_kset)
5864-
kset_unregister(sch->sub_kset);
5866+
kobject_del(&sch->sub_kset->kobj);
58655867
kobject_del(&sch->kobj);
58665868
}
58675869
#else /* CONFIG_EXT_SUB_SCHED */
@@ -5995,7 +5997,7 @@ static void scx_root_disable(struct scx_sched *sch)
59955997
*/
59965998
#ifdef CONFIG_EXT_SUB_SCHED
59975999
if (sch->sub_kset)
5998-
kset_unregister(sch->sub_kset);
6000+
kobject_del(&sch->sub_kset->kobj);
59996001
#endif
60006002
kobject_del(&sch->kobj);
60016003

0 commit comments

Comments
 (0)