Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'wq-for-7.0-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq

Pull workqueue fix from Tejun Heo:

- Fix false positive stall reports on weakly ordered architectures
where the lockless worklist/timestamp check in the watchdog can
observe stale values due to memory reordering.

Recheck under pool->lock to confirm.

* tag 'wq-for-7.0-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
workqueue: Better describe stall check
workqueue: Fix false positive stall reports

+22 -3
+22 -3
kernel/workqueue.c
··· 7699 7699 else 7700 7700 ts = touched; 7701 7701 7702 - /* did we stall? */ 7702 + /* 7703 + * Did we stall? 7704 + * 7705 + * Do a lockless check first to do not disturb the system. 7706 + * 7707 + * Prevent false positives by double checking the timestamp 7708 + * under pool->lock. The lock makes sure that the check reads 7709 + * an updated pool->last_progress_ts when this CPU saw 7710 + * an already updated pool->worklist above. It seems better 7711 + * than adding another barrier into __queue_work() which 7712 + * is a hotter path. 7713 + */ 7703 7714 if (time_after(now, ts + thresh)) { 7715 + scoped_guard(raw_spinlock_irqsave, &pool->lock) { 7716 + pool_ts = pool->last_progress_ts; 7717 + if (time_after(pool_ts, touched)) 7718 + ts = pool_ts; 7719 + else 7720 + ts = touched; 7721 + } 7722 + if (!time_after(now, ts + thresh)) 7723 + continue; 7724 + 7704 7725 lockup_detected = true; 7705 7726 stall_time = jiffies_to_msecs(now - pool_ts) / 1000; 7706 7727 max_stall_time = max(max_stall_time, stall_time); ··· 7733 7712 pr_cont_pool_info(pool); 7734 7713 pr_cont(" stuck for %us!\n", stall_time); 7735 7714 } 7736 - 7737 - 7738 7715 } 7739 7716 7740 7717 if (lockup_detected)