linux-next: manual merge of the sched-ext tree with the origin tree
From: Mark Brown
Date: Mon Oct 19 2026 - 13:48:40 EST
Hi all,
Today's linux-next merge of the sched-ext tree got a conflict in:
kernel/sched/ext/sub.c
between commit:
18f5c699d1d0a ("sched_ext: Rename scx_reenq_wait_dispatching() to scx_wait_dispatching()")
from the origin tree and commit:
cea8b60e4aee0 ("sched_ext: Move reject DSQ draining into core")
from the sched-ext tree.
I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.
diff --cc kernel/sched/ext/ext.c
index 2b6239763b230,9491e4332115f..0000000000000
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@@ -2421,11 -2597,8 +2601,11 @@@ void scx_move_local_task_to_local_dsq(s
lockdep_assert_rq_held(dst_rq);
WARN_ON_ONCE(p->scx.holding_cpu >= 0);
+ scx_wait_dispatching(p);
+
+ dst_dsq = scx_resolve_local_dsq(sch, dst_rq, p, &enq_flags);
- if (enq_flags & (SCX_ENQ_HEAD | SCX_ENQ_PREEMPT))
+ if (enq_flags & (SCX_ENQ_HEAD | SCX_ENQ_PREEMPT | SCX_ENQ_PREEMPT_LAZY))
dsq_insert_head(dst_dsq, p);
else
list_add_tail(&p->scx.dsq_list.node, &dst_dsq->list);
@@@ -2604,7 -2847,13 +2854,14 @@@ static bool unlink_dsq_and_switch_rq_lo
/* task_rq couldn't have changed if we're still the holding cpu */
if (likely(p->scx.holding_cpu == cpu) && !WARN_ON_ONCE(src_rq != task_rq(p))) {
+ scx_wait_dispatching(p);
+ /*
+ * Keep ->dsq set until we own @src_rq so that a racing dequeue
+ * can find @dsq and clear holding_cpu. Once ownership is
+ * confirmed, clear it under @src_rq so that deactivate_task()
+ * takes the !dsq path instead of retaking @dsq->lock.
+ */
+ p->scx.dsq = NULL;
return true;
}
@@@ -2651,10 -2913,21 +2921,23 @@@ static struct rq *move_task_between_dsq
lockdep_assert_held(&src_dsq->lock);
lockdep_assert_rq_held(src_rq);
+ scx_wait_dispatching(p);
+
if (dst_dsq->id == SCX_DSQ_LOCAL) {
dst_rq = container_of(dst_dsq, struct rq, scx.local_dsq);
+ /*
+ * Unlike the rq-lock handoff paths, @src_rq has been locked
+ * throughout this operation. Only active proxy state can race the
+ * move here; let the enforcing check below diagnose an ordinary
+ * migration-disabled task.
+ */
+ if (src_rq != dst_rq &&
+ unlikely(task_proxy_running_or_donating(p))) {
+ dispatch_dequeue_locked(p, src_dsq);
+ raw_spin_unlock(&src_dsq->lock);
+ scx_proxy_reject_task(sch, src_rq, p, enq_flags);
+ return src_rq;
+ }
if (src_rq != dst_rq &&
unlikely(!task_can_run_on_remote_rq(sch, p, dst_rq, true))) {
dst_dsq = find_global_dsq(sch, task_cpu(p));
@@@ -4562,11 -4922,10 +4942,10 @@@ static u32 reenq_local(struct scx_sche
if (!local_task_should_reenq(rq, p, &reenq_flags, &reason))
continue;
- scx_reenq_wait_dispatching(p);
+ scx_wait_dispatching(p);
scx_dispatch_dequeue(rq, p);
- if (WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK))
- p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK;
+ WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK);
p->scx.flags |= reason;
list_add_tail(&p->scx.dsq_list.node, &tasks);
Attachment:
signature.asc
Description: PGP signature