[PATCH RFC 2/3] workqueue: trigger a single-CPU backtrace for stalled pools

From: Breno Leitao

Date: Tue Jun 16 2026 - 12:52:05 EST


When a CPU pool is stalled with no running worker, the task occupying the
CPU may not be a workqueue worker at all. Trigger a single-CPU backtrace
for the stalled CPU to capture what it is currently executing.

The CPU is snapshotted under pool->lock and the backtrace is triggered
after releasing the lock to avoid any potential issues with NMI delivery.

Suggested-by: Petr Mladek <pmladek@xxxxxxxx>
Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
kernel/workqueue.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index efbac160b7628..db6287cd39588 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -7720,10 +7720,13 @@ static void show_cpu_pool_busy_workers(struct worker_pool *pool)
bool found_running = false;
struct worker *worker;
unsigned long irq_flags;
- int bkt;
+ int cpu, bkt;

raw_spin_lock_irqsave(&pool->lock, irq_flags);

+ /* Snapshot cpu inside the lock to safely use it after unlock. */
+ cpu = pool->cpu;
+
hash_for_each(pool->busy_hash, bkt, worker, hentry) {
/* Skip workers that are not actively running on the CPU. */
if (!task_is_running(worker->task))
@@ -7751,6 +7754,14 @@ static void show_cpu_pool_busy_workers(struct worker_pool *pool)
show_pool_no_running_worker(pool);

raw_spin_unlock_irqrestore(&pool->lock, irq_flags);
+
+ /*
+ * Trigger a backtrace on the stalled CPU to capture what it is
+ * currently executing. Called after releasing the lock to avoid
+ * any potential issues with NMI delivery.
+ */
+ if (!found_running)
+ trigger_single_cpu_backtrace(cpu);
}

static void show_cpu_pools_busy_workers(void)

--
2.53.0-Meta