sched_ext/lavd hard lockup in old call_rcu_tasks_generic needadjust path

From: Matt Fleming

Date: Tue Jun 09 2026 - 06:48:57 EST


Hi there,

We're investigating a hard lockup on a 6.18.33-based kernel with scx_lavd
running.

The vmcore shows CPU#67 stuck in:

native_queued_spin_lock_slowpath
_raw_spin_lock
task_rq_lock
sched_ext_free
__put_task_struct
rcu_core
handle_softirqs
irq_exit_rcu
sysvec_apic_timer_interrupt

The rq lock being waited on is for CPU#66.

Another CPU in the same dump is in:

sched_ext_free
scx_exit_task
bpf_task_storage_delete
call_rcu_tasks_generic+547
_printk
console_unlock
wake_up_q
try_to_wake_up
__task_rq_lock

The `call_rcu_tasks_generic+547` site is the old needadjust path that
prints:

Switching RCU Tasks Trace to per-CPU callback queuing.

So the current theory is that a task teardown under rq lock enters
bpf_task_storage_delete(), hits the callback-queue adjustment printk,
then console wakeup tries to acquire the same rq lock again.

We found related upstream changes:

3063b33a347c ("rcu-tasks: Avoid raw-spinlocked wakeups from call_rcu_tasks_generic()")
d245698d727a ("cgroup: Defer task cgroup unlink until after the task is done switching out")
7900aa699c34 ("sched_ext: Fix cgroup exit ordering by moving sched_ext_free() to finish_task_switch()")
7c405fb3279b ("rcu: Use an intermediate irq_work to start process_srcu()")

But none appears to directly fix the old 6.18 needadjust printk path.

Would backporting d245698d727a and 7900aa699c34 be useful, or should
the needadjust printk path itself be deferred away from rq-locked
callers?

Thanks,
Matt