From 6603859ca0be85441af86d350d68bc6144d5da9c Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: May 10 2023 14:34:44 +0000 Subject: workqueue: Fix hung time report of worker pools (bsc#1211044). --- diff --git a/patches.suse/workqueue-Fix-hung-time-report-of-worker-pools.patch b/patches.suse/workqueue-Fix-hung-time-report-of-worker-pools.patch new file mode 100644 index 0000000..af14bb1 --- /dev/null +++ b/patches.suse/workqueue-Fix-hung-time-report-of-worker-pools.patch @@ -0,0 +1,60 @@ +From 335a42ebb0ca8ee9997a1731aaaae6dcd704c113 Mon Sep 17 00:00:00 2001 +From: Petr Mladek +Date: Tue, 7 Mar 2023 13:53:31 +0100 +Subject: [PATCH] workqueue: Fix hung time report of worker pools +Git-commit: 335a42ebb0ca8ee9997a1731aaaae6dcd704c113 +Patch-mainline: v6.4-rc1 +References: bsc#1211044 + +The workqueue watchdog prints a warning when there is no progress in +a worker pool. Where the progress means that the pool started processing +a pending work item. + +Note that it is perfectly fine to process work items much longer. +The progress should be guaranteed by waking up or creating idle +workers. + +show_one_worker_pool() prints state of non-idle worker pool. It shows +a delay since the last pool->watchdog_ts. + +The timestamp is updated when a first pending work is queued in +__queue_work(). Also it is updated when a work is dequeued for +processing in worker_thread() and rescuer_thread(). + +The delay is misleading when there is no pending work item. In this +case it shows how long the last work item is being proceed. Show +zero instead. There is no stall if there is no pending work. + +Fixes: 82607adcf9cdf40fb7b ("workqueue: implement lockup detector") +Signed-off-by: Petr Mladek +Signed-off-by: Tejun Heo + +--- + kernel/workqueue.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -4879,16 +4879,19 @@ void show_workqueue_state(void) + for_each_pool(pool, pi) { + struct worker *worker; + bool first = true; ++ unsigned long hung = 0; + + spin_lock_irqsave(&pool->lock, flags); + if (pool->nr_workers == pool->nr_idle) + goto next_pool; + ++ /* How long the first pending work is waiting for a worker. */ ++ if (!list_empty(&pool->worklist)) ++ hung = jiffies_to_msecs(jiffies - pool->watchdog_ts) / 1000; ++ + pr_info("pool %d:", pool->id); + pr_cont_pool_info(pool); +- pr_cont(" hung=%us workers=%d", +- jiffies_to_msecs(jiffies - pool->watchdog_ts) / 1000, +- pool->nr_workers); ++ pr_cont(" hung=%lus workers=%d", hung, pool->nr_workers); + if (pool->manager) + pr_cont(" manager: %d", + task_pid_nr(pool->manager->task)); diff --git a/series.conf b/series.conf index 6d6503d..1e30df2 100644 --- a/series.conf +++ b/series.conf @@ -63305,6 +63305,7 @@ patches.suse/USB-dwc3-fix-runtime-pm-imbalance-on-probe-errors.patch patches.suse/USB-dwc3-fix-runtime-pm-imbalance-on-unbind.patch patches.suse/usb-chipidea-fix-missing-goto-in-ci_hdrc_probe.patch + patches.suse/workqueue-Fix-hung-time-report-of-worker-pools.patch patches.suse/xfs-verify-buffer-contents-when-we-skip-log-replay.patch # dhowells/linux-fs keys-uefi