Merge branch 'for-7.1-fixes' into for-7.2

Pull to receive:

 39e25a2100 ("sched_ext: Drop NONE early return in scx_disable_and_exit_task()")
 b273b75b8d ("sched_ext: INIT_LIST_HEAD() &sch->all in scx_alloc_and_add_sched()")
 cceb874eee ("sched_ext: Defer sub_kset base put to scx_sched_free_rcu_work")
 6ae315d379 ("sched_ext: Use HK_TYPE_DOMAIN_BOOT to detect isolcpus= domain isolation")
 515e3996a4 ("sched_ext: Fix deadlock between scx_root_disable() and concurrent forks")

to prepare for-7.2 for further sub-sched changes.

Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Tejun Heo 2026-05-17 10:31:10 -10:00
commit 1136fb1213

View File

@ -3816,22 +3816,14 @@ static void scx_sub_init_cancel_task(struct scx_sched *sch, struct task_struct *
static void scx_disable_and_exit_task(struct scx_sched *sch,
struct task_struct *p)
{
/*
* %NONE means @p is already detached at the SCX level (e.g. handed
* back to the parent by scx_fail_parent() with no init to undo).
* Skip to avoid clobbering scx_task_sched() and writing %NONE again
* on a state that's already %NONE.
*/
if (scx_get_task_state(p) == SCX_TASK_NONE)
return;
__scx_disable_and_exit_task(sch, p);
/*
* If set, @p exited between __scx_init_task() and scx_enable_task() in
* scx_sub_enable() and is initialized for both the associated sched and
* its parent. Exit for the child too - scx_enable_task() never ran for
* it, so undo only init_task.
* it, so undo only init_task. The flag is only set on the sub-enable
* path, so it's always clear when @p arrives here in %SCX_TASK_NONE.
*/
if (p->scx.flags & SCX_TASK_SUB_INIT) {
if (!WARN_ON_ONCE(!scx_enabling_sub_sched))
@ -4975,6 +4967,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) {
@ -5098,10 +5092,30 @@ static const struct kset_uevent_ops scx_uevent_ops = {
*/
bool task_should_scx(int policy)
{
if (!scx_enabled() || unlikely(scx_enable_state() == SCX_DISABLING))
/* if disabled, nothing should be on it */
if (!scx_enabled())
return false;
/* scx is taking over all SCHED_OTHER and SCHED_EXT tasks */
if (READ_ONCE(scx_switching_all))
return true;
/*
* scx is tearing down - keep new SCHED_EXT tasks out.
*
* Must come after scx_switching_all test, which serves as a proxy
* for __scx_switched_all. While __scx_switched_all is set, we must
* return true via the branch above: a fork routed to fair would
* stall because next_active_class() skips fair.
*
* This can develop into a deadlock - scx holds scx_enable_mutex across
* kthread_create() in scx_alloc_and_add_sched(); if the new kthread is
* the stalled task, the disable path can never grab the mutex to clear
* scx_switching_all.
*/
if (unlikely(scx_enable_state() == SCX_DISABLING))
return false;
return policy == SCHED_EXT;
}
@ -6035,7 +6049,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 */
@ -6161,7 +6175,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);
@ -6850,6 +6864,7 @@ static struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd,
rcu_assign_pointer(ops->priv, sch);
sch->kobj.kset = scx_kset;
INIT_LIST_HEAD(&sch->all);
#ifdef CONFIG_EXT_SUB_SCHED
char *buf = kzalloc(PATH_MAX, GFP_KERNEL);
@ -7677,8 +7692,7 @@ static s32 scx_enable(struct scx_enable_cmd *cmd, struct bpf_link *link)
static struct kthread_worker *helper;
static DEFINE_MUTEX(helper_mutex);
if (!cpumask_equal(housekeeping_cpumask(HK_TYPE_DOMAIN),
cpu_possible_mask)) {
if (housekeeping_enabled(HK_TYPE_DOMAIN_BOOT)) {
pr_err("sched_ext: Not compatible with \"isolcpus=\" domain isolation\n");
return -EINVAL;
}