Skip to content

Commit 86ecb1c

Browse files
arighihtejun
authored andcommitted
sched_ext: Clear ops->priv on scx_alloc_and_add_sched() error paths
scx_alloc_and_add_sched() can fail after @sch has been assigned to ops->priv. In those cases @sch is torn down (either via kfree() through the err_free_* chain or via kobject_put() -> scx_kobj_release() -> RCU work), but @ops->priv is left pointing at the about-to-be-freed pointer. With the recent -EBUSY gate in scx_root_enable_workfn() and scx_sub_enable_workfn() that rejects an attach when @ops->priv is still non-NULL, see commit bbf30b3 ("sched_ext: Fix ops->priv clobber on concurrent attach/detach"), a dangling @ops->priv permanently locks the kdata out: every future attach attempt sees a stale binding and returns -EBUSY even though no scheduler is actually attached. Clear @ops->priv on the post-assign failure paths so that the kdata returns to its pre-attach state when the function returns ERR_PTR(). Fixes: bbf30b3 ("sched_ext: Fix ops->priv clobber on concurrent attach/detach") Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent bbf30b3 commit 86ecb1c

1 file changed

Lines changed: 4 additions & 0 deletions

File tree

kernel/sched/ext.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6670,20 +6670,23 @@ static struct scx_sched *scx_alloc_and_add_sched(struct sched_ext_ops *ops,
66706670
ret = kobject_init_and_add(&sch->kobj, &scx_ktype, NULL, "root");
66716671

66726672
if (ret < 0) {
6673+
RCU_INIT_POINTER(ops->priv, NULL);
66736674
kobject_put(&sch->kobj);
66746675
return ERR_PTR(ret);
66756676
}
66766677

66776678
if (ops->sub_attach) {
66786679
sch->sub_kset = kset_create_and_add("sub", NULL, &sch->kobj);
66796680
if (!sch->sub_kset) {
6681+
RCU_INIT_POINTER(ops->priv, NULL);
66806682
kobject_put(&sch->kobj);
66816683
return ERR_PTR(-ENOMEM);
66826684
}
66836685
}
66846686
#else /* CONFIG_EXT_SUB_SCHED */
66856687
ret = kobject_init_and_add(&sch->kobj, &scx_ktype, NULL, "root");
66866688
if (ret < 0) {
6689+
RCU_INIT_POINTER(ops->priv, NULL);
66876690
kobject_put(&sch->kobj);
66886691
return ERR_PTR(ret);
66896692
}
@@ -6692,6 +6695,7 @@ static struct scx_sched *scx_alloc_and_add_sched(struct sched_ext_ops *ops,
66926695

66936696
#ifdef CONFIG_EXT_SUB_SCHED
66946697
err_free_lb_resched:
6698+
RCU_INIT_POINTER(ops->priv, NULL);
66956699
free_cpumask_var(sch->bypass_lb_resched_cpumask);
66966700
#endif
66976701
err_free_lb_cpumask:

0 commit comments

Comments
 (0)