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.

workqueue: Show in-flight work item duration in stall diagnostics

When diagnosing workqueue stalls, knowing how long each in-flight work
item has been executing is valuable. Add a current_start timestamp
(jiffies) to struct worker, set it when a work item begins execution in
process_one_work(), and print the elapsed wall-clock time in show_pwq().

Unlike current_at (which tracks CPU runtime and resets on wakeup for
CPU-intensive detection), current_start is never reset because the
diagnostic cares about total wall-clock time including sleeps.

Before: in-flight: 165:stall_work_fn [wq_stall]
After: in-flight: 165:stall_work_fn [wq_stall] for 100s

Signed-off-by: Breno Leitao <leitao@debian.org>
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Breno Leitao and committed by
Tejun Heo
e8e14ac7 6037160e

+4
+3
kernel/workqueue.c
··· 3204 3204 worker->current_pwq = pwq; 3205 3205 if (worker->task) 3206 3206 worker->current_at = worker->task->se.sum_exec_runtime; 3207 + worker->current_start = jiffies; 3207 3208 work_data = *work_data_bits(work); 3208 3209 worker->current_color = get_work_color(work_data); 3209 3210 ··· 6360 6359 pr_cont(" %s", comma ? "," : ""); 6361 6360 pr_cont_worker_id(worker); 6362 6361 pr_cont(":%ps", worker->current_func); 6362 + pr_cont(" for %us", 6363 + jiffies_to_msecs(jiffies - worker->current_start) / 1000); 6363 6364 list_for_each_entry(work, &worker->scheduled, entry) 6364 6365 pr_cont_work(false, work, &pcws); 6365 6366 pr_cont_work_flush(comma, (work_func_t)-1L, &pcws);
+1
kernel/workqueue_internal.h
··· 32 32 work_func_t current_func; /* K: function */ 33 33 struct pool_workqueue *current_pwq; /* K: pwq */ 34 34 u64 current_at; /* K: runtime at start or last wakeup */ 35 + unsigned long current_start; /* K: start time of current work item */ 35 36 unsigned int current_color; /* K: color */ 36 37 37 38 int sleeping; /* S: is worker sleeping? */