From: Tejun Heo <tj@kernel.org>
To: David Vernet <void@manifault.com>,
Andrea Righi <arighi@nvidia.com>,
Changwoo Min <changwoo@igalia.com>
Cc: sched-ext@lists.linux.dev, Emil Tsalapatis <emil@etsalapatis.com>,
Cheng-Yang Chou <yphbchou0911@gmail.com>,
linux-kernel@vger.kernel.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH 3/5] sched_ext: Always bounce scx_disable() through irq_work
Date: Mon, 9 Mar 2026 15:16:51 -1000 [thread overview]
Message-ID: <20260310011653.2993712-4-tj@kernel.org> (raw)
In-Reply-To: <20260310011653.2993712-1-tj@kernel.org>
scx_disable() directly called kthread_queue_work() which can acquire
worker->lock, pi_lock and rq->__lock. This made scx_disable() unsafe to
call while holding locks that conflict with this chain - in particular,
scx_claim_exit() calls scx_disable() for each descendant while holding
scx_sched_lock, which nests inside rq->__lock in scx_bypass().
The error path (scx_vexit()) was already bouncing through irq_work to
avoid this issue. Generalize the pattern to all scx_disable() calls by
always going through irq_work. irq_work_queue() is lockless and safe to
call from any context, and the actual kthread_queue_work() call happens
in the irq_work handler outside any locks.
Rename error_irq_work to disable_irq_work to reflect the broader usage.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
kernel/sched/ext.c | 12 ++++++------
kernel/sched/ext_internal.h | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index d76a47b782a7..cf28a8f62ad0 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -4498,7 +4498,7 @@ static void scx_sched_free_rcu_work(struct work_struct *work)
struct scx_dispatch_q *dsq;
int cpu, node;
- irq_work_sync(&sch->error_irq_work);
+ irq_work_sync(&sch->disable_irq_work);
kthread_destroy_worker(sch->helper);
timer_shutdown_sync(&sch->bypass_lb_timer);
@@ -5679,7 +5679,7 @@ static void scx_disable(struct scx_sched *sch, enum scx_exit_kind kind)
{
guard(preempt)();
if (scx_claim_exit(sch, kind))
- kthread_queue_work(sch->helper, &sch->disable_work);
+ irq_work_queue(&sch->disable_irq_work);
}
static void dump_newline(struct seq_buf *s)
@@ -6012,9 +6012,9 @@ static void scx_dump_state(struct scx_sched *sch, struct scx_exit_info *ei,
trunc_marker, sizeof(trunc_marker));
}
-static void scx_error_irq_workfn(struct irq_work *irq_work)
+static void scx_disable_irq_workfn(struct irq_work *irq_work)
{
- struct scx_sched *sch = container_of(irq_work, struct scx_sched, error_irq_work);
+ struct scx_sched *sch = container_of(irq_work, struct scx_sched, disable_irq_work);
struct scx_exit_info *ei = sch->exit_info;
if (ei->kind >= SCX_EXIT_ERROR)
@@ -6048,7 +6048,7 @@ static bool scx_vexit(struct scx_sched *sch,
ei->kind = kind;
ei->reason = scx_exit_reason(ei->kind);
- irq_work_queue(&sch->error_irq_work);
+ irq_work_queue(&sch->disable_irq_work);
return true;
}
@@ -6184,7 +6184,7 @@ static struct scx_sched *scx_alloc_and_add_sched(struct sched_ext_ops *ops,
sch->slice_dfl = SCX_SLICE_DFL;
atomic_set(&sch->exit_kind, SCX_EXIT_NONE);
- init_irq_work(&sch->error_irq_work, scx_error_irq_workfn);
+ init_irq_work(&sch->disable_irq_work, scx_disable_irq_workfn);
kthread_init_work(&sch->disable_work, scx_disable_workfn);
timer_setup(&sch->bypass_lb_timer, scx_bypass_lb_timerfn, 0);
sch->ops = *ops;
diff --git a/kernel/sched/ext_internal.h b/kernel/sched/ext_internal.h
index 3623de2c30a1..c78dadaadab8 100644
--- a/kernel/sched/ext_internal.h
+++ b/kernel/sched/ext_internal.h
@@ -1042,7 +1042,7 @@ struct scx_sched {
struct kobject kobj;
struct kthread_worker *helper;
- struct irq_work error_irq_work;
+ struct irq_work disable_irq_work;
struct kthread_work disable_work;
struct timer_list bypass_lb_timer;
struct rcu_work rcu_work;
--
2.53.0
next prev parent reply other threads:[~2026-03-10 1:16 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-10 1:16 [PATCHSET sched_ext/for-7.1] Fix sub-sched locking issues Tejun Heo
2026-03-10 1:16 ` [PATCH 1/5] sched_ext: Fix sub_detach op check to test the parent's ops Tejun Heo
2026-03-10 1:16 ` [PATCH 2/5] sched_ext: Add scx_dump_lock and dump_disabled Tejun Heo
2026-03-10 1:16 ` Tejun Heo [this message]
2026-03-10 1:16 ` [PATCH 4/5] sched_ext: Fix scx_sched_lock / rq lock ordering Tejun Heo
2026-03-10 5:18 ` Cheng-Yang Chou
2026-03-10 6:39 ` Andrea Righi
2026-03-10 6:47 ` Andrea Righi
2026-03-10 1:16 ` [PATCH 5/5] sched_ext: Reject sub-sched attachment to a disabled parent Tejun Heo
2026-03-10 6:50 ` [PATCHSET sched_ext/for-7.1] Fix sub-sched locking issues Andrea Righi
2026-03-10 17:17 ` Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260310011653.2993712-4-tj@kernel.org \
--to=tj@kernel.org \
--cc=arighi@nvidia.com \
--cc=changwoo@igalia.com \
--cc=emil@etsalapatis.com \
--cc=linux-kernel@vger.kernel.org \
--cc=sched-ext@lists.linux.dev \
--cc=void@manifault.com \
--cc=yphbchou0911@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.