[PATCH] workqueue: Better describe stall check

From: Petr Mladek

Date: Wed Mar 25 2026 - 08:34:18 EST


Try to be more explicit why the workqueue watchdog does not take
pool->lock by default. Spin locks are full memory barriers which
delay anything. Obviously, they would primary delay operations
on the related worker pools.

Explain why it is enough to prevent the false positive by re-checking
the timestamp under the pool->lock.

Finally, make it clear what would be the alternative solution in
__queue_work() which is a hotter path.

Signed-off-by: Petr Mladek <pmladek@xxxxxxxx>
---
kernel/workqueue.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index ff97b705f25e..e3e97d59d2f4 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -7702,13 +7702,13 @@ static void wq_watchdog_timer_fn(struct timer_list *unused)
/*
* Did we stall?
*
- * Do a lockless check first. On weakly ordered
- * architectures, the lockless check can observe a
- * reordering between worklist insert_work() and
- * last_progress_ts update from __queue_work(). Since
- * __queue_work() is a much hotter path than the timer
- * function, we handle false positive here by reading
- * last_progress_ts again with pool->lock held.
+ * Try to block or slow down queue_work() as less as possible
+ * because it might be used in hot paths. Just prevent false
+ * positives.
+ *
+ * Do a lockless check first. The spin_lock() makes sure
+ * that the re-check reads an updated pool->last_progress_ts
+ * when this CPU saw an already updated pool->worklist.
*/
if (time_after(now, ts + thresh)) {
scoped_guard(raw_spinlock_irqsave, &pool->lock) {
--
2.53.0