Commit e8e14ac7 authored by Breno Leitao's avatar Breno Leitao Committed by Tejun Heo
Browse files

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: default avatarBreno Leitao <leitao@debian.org>
Acked-by: default avatarSong Liu <song@kernel.org>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent 6037160e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3204,6 +3204,7 @@ __acquires(&pool->lock)
	worker->current_pwq = pwq;
	if (worker->task)
		worker->current_at = worker->task->se.sum_exec_runtime;
	worker->current_start = jiffies;
	work_data = *work_data_bits(work);
	worker->current_color = get_work_color(work_data);

@@ -6359,6 +6360,8 @@ static void show_pwq(struct pool_workqueue *pwq)
			pr_cont(" %s", comma ? "," : "");
			pr_cont_worker_id(worker);
			pr_cont(":%ps", worker->current_func);
			pr_cont(" for %us",
				jiffies_to_msecs(jiffies - worker->current_start) / 1000);
			list_for_each_entry(work, &worker->scheduled, entry)
				pr_cont_work(false, work, &pcws);
			pr_cont_work_flush(comma, (work_func_t)-1L, &pcws);
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ struct worker {
	work_func_t		current_func;	/* K: function */
	struct pool_workqueue	*current_pwq;	/* K: pwq */
	u64			current_at;	/* K: runtime at start or last wakeup */
	unsigned long		current_start;	/* K: start time of current work item */
	unsigned int		current_color;	/* K: color */

	int			sleeping;	/* S: is worker sleeping? */