diff --git a/include/linux/sched.h b/include/linux/sched.h index a2cd1585..3bb78c8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -850,6 +850,7 @@ struct task_struct { #ifdef CONFIG_DETECT_HUNG_TASK unsigned long last_switch_count; unsigned long last_switch_time; + unsigned long last_sigkill_time; #endif /* Filesystem information: */ struct fs_struct *fs; diff --git a/kernel/hung_task.c b/kernel/hung_task.c index f108a95..0fe9228 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -192,6 +192,26 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) goto unlock; last_break = jiffies; } + if (unlikely(fatal_signal_pending(t))) { + unsigned long stamp = t->last_sigkill_time; + + if (!stamp) { + stamp = jiffies; + if (!stamp) + stamp++; + t->last_sigkill_time = stamp; + } else if (time_is_after_jiffies(stamp + timeout * HZ) + && !(t->flags & PF_EXITING)) { + if (sysctl_hung_task_panic) { + console_verbose(); + hung_task_show_lock = true; + hung_task_call_panic = true; + } + pr_err("INFO: task %s:%d can't die for more than %ld seconds.\n", + t->comm, t->pid, (jiffies - stamp) / HZ); + sched_show_task(t); + } + } /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) check_hung_task(t, timeout);