aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul E. McKenney <[email protected]>2024-07-24 16:51:52 -0700
committerPaul E. McKenney <[email protected]>2024-08-02 10:55:04 -0700
commitb8e753128ed074fcb48e9ceded940752f6b1c19f (patch)
tree765af0cb8e48088f8ea1ed2c0d8a5137dd34741d
parent8400291e289ee6b2bf9779ff1c83a291501f017b (diff)
exit: Sleep at TASK_IDLE when waiting for application core dump
Currently, the coredump_task_exit() function sets the task state to TASK_UNINTERRUPTIBLE|TASK_FREEZABLE, which usually works well. But a combination of large memory and slow (and/or highly contended) mass storage can cause application core dumps to take more than two minutes, which can cause check_hung_task(), which is invoked by check_hung_uninterruptible_tasks(), to produce task-blocked splats. There does not seem to be any reasonable benefit to getting these splats. Furthermore, as Oleg Nesterov points out, TASK_UNINTERRUPTIBLE could be misleading because the task sleeping in coredump_task_exit() really is killable, albeit indirectly. See the check of signal->core_state in prepare_signal() and the check of fatal_signal_pending() in dump_interrupted(), which bypass the normal unkillability of TASK_UNINTERRUPTIBLE, resulting in coredump_finish() invoking wake_up_process() on any threads sleeping in coredump_task_exit(). Therefore, change that TASK_UNINTERRUPTIBLE to TASK_IDLE. Reported-by: Anhad Jai Singh <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]> Acked-by: Oleg Nesterov <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Christian Brauner <[email protected]> Cc: Andrew Morton <[email protected]> Cc: "Matthew Wilcox (Oracle)" <[email protected]> Cc: Chris Mason <[email protected]> Cc: Rik van Riel <[email protected]>
-rw-r--r--kernel/exit.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 7430852a8571..0d62a53605df 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -428,7 +428,7 @@ static void coredump_task_exit(struct task_struct *tsk)
complete(&core_state->startup);
for (;;) {
- set_current_state(TASK_UNINTERRUPTIBLE|TASK_FREEZABLE);
+ set_current_state(TASK_IDLE|TASK_FREEZABLE);
if (!self.task) /* see coredump_finish() */
break;
schedule();