From: Matt Fleming <matt@readmodwrite.com>
To: Tejun Heo <tj@kernel.org>
Cc: David Vernet <void@manifault.com>,
Andrea Righi <arighi@nvidia.com>,
Changwoo Min <changwoo@igalia.com>,
Johannes Weiner <hannes@cmpxchg.org>,
Suren Baghdasaryan <surenb@google.com>,
Peter Zijlstra <peterz@infradead.org>,
Edward Adam Davis <eadavis@qq.com>,
Chen Ridong <chenridong@huaweicloud.com>,
sched-ext@lists.linux.dev, cgroups@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
kernel-team@cloudflare.com,
Matt Fleming <mfleming@cloudflare.com>
Subject: [PATCH] sched_ext: Fix deadlock with PSI trigger creation
Date: Fri, 10 Jul 2026 11:04:41 +0100 [thread overview]
Message-ID: <20260710100441.2653477-1-matt@readmodwrite.com> (raw)
From: Matt Fleming <mfleming@cloudflare.com>
scx_root_enable_workfn() currently takes scx_fork_rwsem for writing
before acquiring cgroup_mutex. Since commit a5b98009f16d ("sched/psi:
fix race between file release and pressure write"), pressure_write()
holds cgroup_mutex across psi_trigger_create(), which may call
kthread_create() for the psimon kthread. kthreadd's fork then enters
scx_pre_fork() and waits for the read side of scx_fork_rwsem.
This results in a deadlock. The enable worker holds scx_fork_rwsem and
waits for cgroup_mutex, while the PSI writer holds cgroup_mutex and
waits for psimon creation to complete. Any concurrent fork blocks on
scx_pre_fork() behind the enable worker.
The hung-task detector captured all three sides of the deadlock:
scx_enable_help:
__mutex_lock
scx_enable_workfn
kthread_worker_fn
systemd:
wait_for_completion_killable
__kthread_create_on_node
kthread_create_on_node
psi_trigger_create
pressure_write
kernfs_fop_write_iter
python3:
percpu_rwsem_wait
__percpu_down_read
scx_pre_fork
sched_fork
copy_process
kernel_clone
It also identified systemd as the likely owner of the mutex on which
scx_enable_help was blocked.
We reproduced this on a 128-CPU AMD EPYC 7713 by enabling scx_lavd
concurrently with writes to cgroup PSI trigger files. Unrelated tasks
piled up in scx_pre_fork() and process creation on the box stopped.
Fix the inversion by acquiring cgroup_mutex before scx_fork_rwsem in
scx_root_enable_workfn() and releasing them in reverse order, while
preserving the existing exclusion around cgroup and task initialisation.
Fixes: a5b98009f16d ("sched/psi: fix race between file release and pressure write")
Cc: stable@vger.kernel.org
Signed-off-by: Matt Fleming <mfleming@cloudflare.com>
---
kernel/sched/ext/ext.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 691d53fe0f64..ba89eafe7964 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -7193,7 +7193,10 @@ static void scx_root_enable_workfn(struct kthread_work *work)
/*
* Lock out forks, cgroup on/offlining and moves before opening the
* floodgate so that they don't wander into the operations prematurely.
+ * cgroup_mutex must nest outside scx_fork_rwsem because cgroup file
+ * operations may create kthreads while holding cgroup_mutex.
*/
+ scx_cgroup_lock();
percpu_down_write(&scx_fork_rwsem);
WARN_ON_ONCE(scx_init_task_enabled);
@@ -7216,7 +7219,6 @@ static void scx_root_enable_workfn(struct kthread_work *work)
* while tasks are being initialized so that scx_cgroup_can_attach()
* never sees uninitialized tasks.
*/
- scx_cgroup_lock();
set_cgroup_sched(sch_cgroup(sch), sch);
ret = scx_cgroup_init(sch);
if (ret)
@@ -7283,8 +7285,8 @@ static void scx_root_enable_workfn(struct kthread_work *work)
put_task_struct(p);
}
scx_task_iter_stop(&sti);
- scx_cgroup_unlock();
percpu_up_write(&scx_fork_rwsem);
+ scx_cgroup_unlock();
/*
* All tasks are READY. It's safe to turn on scx_enabled() and switch
@@ -7369,8 +7371,8 @@ static void scx_root_enable_workfn(struct kthread_work *work)
return;
err_disable_unlock_all:
- scx_cgroup_unlock();
percpu_up_write(&scx_fork_rwsem);
+ scx_cgroup_unlock();
/* we'll soon enter disable path, keep bypass on */
err_disable:
mutex_unlock(&scx_enable_mutex);
--
2.43.0
next reply other threads:[~2026-07-10 10:04 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 10:04 Matt Fleming [this message]
2026-07-10 17:46 ` [PATCH] sched_ext: Fix deadlock with PSI trigger creation Andrea Righi
2026-07-10 18:24 ` Andrea Righi
2026-07-10 23:49 ` [PATCH cgroup/for-7.2-fixes] cgroup: Create the psimon kthread outside of cgroup_mutex Tejun Heo
2026-07-11 5:54 ` Matt Fleming
2026-07-12 17:49 ` 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=20260710100441.2653477-1-matt@readmodwrite.com \
--to=matt@readmodwrite.com \
--cc=arighi@nvidia.com \
--cc=cgroups@vger.kernel.org \
--cc=changwoo@igalia.com \
--cc=chenridong@huaweicloud.com \
--cc=eadavis@qq.com \
--cc=hannes@cmpxchg.org \
--cc=kernel-team@cloudflare.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mfleming@cloudflare.com \
--cc=peterz@infradead.org \
--cc=sched-ext@lists.linux.dev \
--cc=stable@vger.kernel.org \
--cc=surenb@google.com \
--cc=tj@kernel.org \
--cc=void@manifault.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox