When we want to debug the workqueue stall, we can immediately make a panic to get the information we want. In some systems, it may be necessary to quickly reboot the system to escape from a workqueue lockup situation. In this case, we can control the number of stall detections to generate panic. workqueue.panic_on_stall sets the number times of the stall to trigger panic. 0 disables the panic on stall.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -7398,6 +7398,9 @@ static struct timer_list wq_watchdog_timer; · 7397 unmodified lines | ||
| 7398 | 7398 | static unsigned long wq_watchdog_touched = INITIAL_JIFFIES; |
| 7399 | 7399 | static DEFINE_PER_CPU(unsigned long, wq_watchdog_touched_cpu) = INITIAL_JIFFIES; |
| 7400 | 7400 | |
| 7401 | +static unsigned int wq_panic_on_stall; | |
| 7402 | +module_param_named(panic_on_stall, wq_panic_on_stall, uint, 0644); | |
| 7403 | + | |
| 7401 | 7404 | /* |
| 7402 | 7405 | * Show workers that might prevent the processing of pending work items. |
| 7403 | 7406 | * The only candidates are CPU-bound workers in the running state. |
| @@ -7449,6 +7452,16 @@ static void show_cpu_pools_hogs(void) · 45 unmodified lines | ||
| 7449 | 7452 | rcu_read_unlock(); |
| 7450 | 7453 | } |
| 7451 | 7454 | |
| 7455 | +static void panic_on_wq_watchdog(void) | |
| 7456 | +{ | |
| 7457 | + static unsigned int wq_stall; | |
| 7458 | + | |
| 7459 | + if (wq_panic_on_stall) { | |
| 7460 | + wq_stall++; | |
| 7461 | + BUG_ON(wq_stall >= wq_panic_on_stall); | |
| 7462 | + } | |
| 7463 | +} | |
| 7464 | + | |
| 7452 | 7465 | static void wq_watchdog_reset_touched(void) |
| 7453 | 7466 | { |
| 7454 | 7467 | int cpu; |
| @@ -7521,6 +7534,9 @@ static void wq_watchdog_timer_fn(struct timer_list *unused) · 66 unmodified lines | ||
| 7521 | 7534 | if (cpu_pool_stall) |
| 7522 | 7535 | show_cpu_pools_hogs(); |
| 7523 | 7536 | |
| 7537 | + if (lockup_detected) | |
| 7538 | + panic_on_wq_watchdog(); | |
| 7539 | + | |
| 7524 | 7540 | wq_watchdog_reset_touched(); |
| 7525 | 7541 | mod_timer(&wq_watchdog_timer, jiffies + thresh); |
| 7526 | 7542 | } |