To identify the task most likely responsible for a stall, add last_woken_worker (L: pool->lock) to worker_pool and record it in kick_pool() just before wake_up_process(). This captures the idle worker that was kicked to take over when the last running worker went to sleep; if the pool is now stuck with no running worker, that task is the prime suspect and its backtrace is dumped by show_pool_no_running_worker(). Using struct worker * rather than struct task_struct * avoids any lifetime concern: workers are only destroyed via set_worker_dying() which requires pool->lock, and set_worker_dying() clears last_woken_worker when the dying worker matches. show_cpu_pool_busy_workers() holds pool->lock while calling sched_show_task(), so last_woken_worker is either NULL or points to a live worker with a valid task. More precisely, set_worker_dying() clears last_woken_worker before setting WORKER_DIE, so a non-NULL last_woken_worker means the kthread has not yet exited and worker->task is still alive.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -226,6 +226,8 @@ struct worker_pool { · 225 unmodified lines | |||
| 226 | /* L: hash of busy workers */ | 226 | /* L: hash of busy workers */ |
| 227 | 227 | ||
| 228 | struct worker *manager; /* L: purely informational */ | 228 | struct worker *manager; /* L: purely informational */ |
| 229 | /* L: last worker woken by kick_pool() */ | ||
| 230 | struct worker *last_woken_worker; | ||
| 229 | struct list_head workers; /* A: attached workers */ | 231 | struct list_head workers; /* A: attached workers */ |
| 230 | 232 | ||
| 231 | struct ida worker_ida; /* worker IDs for task name */ | 233 | struct ida worker_ida; /* worker IDs for task name */ |
| @@ -1318,6 +1320,9 @@ static bool kick_pool_pick(struct worker_pool *pool, struct task_struct **wakep) · 1086 unmodified lines | |||
| 1318 | } | 1320 | } |
| 1319 | } | 1321 | } |
| 1320 | #endif | 1322 | #endif |
| 1323 | /* Track the last idle worker woken, used for stall diagnostics. */ | ||
| 1324 | pool->last_woken_worker = worker; | ||
| 1325 | |||
| 1321 | *wakep = p; | 1326 | *wakep = p; |
| 1322 | return true; | 1327 | return true; |
| 1323 | } | 1328 | } |
| @@ -2976,6 +2981,13 @@ static void set_worker_dying(struct worker *worker, struct list_head *list) · 1652 unmodified lines | |||
| 2976 | pool->nr_workers--; | 2981 | pool->nr_workers--; |
| 2977 | pool->nr_idle--; | 2982 | pool->nr_idle--; |
| 2978 | 2983 | ||
| 2984 | /* | ||
| 2985 | * Clear last_woken_worker if it points to this worker, so that | ||
| 2986 | * show_cpu_pool_busy_workers() cannot dereference a freed worker. | ||
| 2987 | */ | ||
| 2988 | if (pool->last_woken_worker == worker) | ||
| 2989 | pool->last_woken_worker = NULL; | ||
| 2990 | |||
| 2979 | worker->flags |= WORKER_DIE; | 2991 | worker->flags |= WORKER_DIE; |
| 2980 | 2992 | ||
| 2981 | list_move(&worker->entry, list); | 2993 | list_move(&worker->entry, list); |
| @@ -7740,13 +7752,25 @@ static void show_pool_no_running_worker(struct worker_pool *pool) · 4758 unmodified lines | |||
| 7740 | idle_cpu(pool->cpu) ? "idle" : "busy", | 7752 | idle_cpu(pool->cpu) ? "idle" : "busy", |
| 7741 | pool->nr_workers, pool->nr_idle); | 7753 | pool->nr_workers, pool->nr_idle); |
| 7742 | pr_info("The pool might have trouble waking an idle worker.\n"); | 7754 | pr_info("The pool might have trouble waking an idle worker.\n"); |
| 7755 | /* | ||
| 7756 | * last_woken_worker and its task are valid here: set_worker_dying() | ||
| 7757 | * clears it under pool->lock before setting WORKER_DIE, so if | ||
| 7758 | * last_woken_worker is non-NULL the kthread has not yet exited and | ||
| 7759 | * worker->task is still alive. | ||
| 7760 | */ | ||
| 7761 | if (pool->last_woken_worker) { | ||
| 7762 | pr_info("Backtrace of last woken worker:\n"); | ||
| 7763 | sched_show_task(pool->last_woken_worker->task); | ||
| 7764 | } else { | ||
| 7765 | pr_info("Last woken worker empty\n"); | ||
| 7766 | } | ||
| 7743 | printk_deferred_exit(); | 7767 | printk_deferred_exit(); |
| 7744 | } | 7768 | } |
| 7745 | 7769 | ||
| 7746 | /* | 7770 | /* |
| 7747 | * Show running workers that might prevent the processing of pending work items. | 7771 | * Show running workers that might prevent the processing of pending work items. |
| 7748 | * If no running worker is found, the pool may be stuck waiting for an idle | 7772 | * If no running worker is found, the pool may be stuck waiting for an idle |
| 7749 | * worker to be woken, so report the pool state. | 7773 | * worker to be woken, so report the pool state and the last woken worker. |
| 7750 | */ | 7774 | */ |
| 7751 | static void show_cpu_pool_busy_workers(struct worker_pool *pool) | 7775 | static void show_cpu_pool_busy_workers(struct worker_pool *pool) |
| 7752 | { | 7776 | { |
| @@ -7781,7 +7805,8 @@ static void show_cpu_pool_busy_workers(struct worker_pool *pool) · 28 unmodified lines | |||
| 7781 | 7805 | ||
| 7782 | /* | 7806 | /* |
| 7783 | * If no running worker was found, the pool is likely stuck. Print pool | 7807 | * If no running worker was found, the pool is likely stuck. Print pool |
| 7784 | * state. | 7808 | * state and the backtrace of the last woken worker, which is the prime |
| 7809 | * suspect for the stall. | ||
| 7785 | */ | 7810 | */ |
| 7786 | if (!found_running) | 7811 | if (!found_running) |
| 7787 | show_pool_no_running_worker(pool); | 7812 | show_pool_no_running_worker(pool); |