summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/coredump.c9
-rw-r--r--include/linux/sched/signal.h4
-rw-r--r--kernel/exit.c6
3 files changed, 10 insertions, 9 deletions
diff --git a/fs/coredump.c b/fs/coredump.c
index b75b79c8245b..5c293e890ae6 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -39,6 +39,7 @@
#include <linux/oom.h>
#include <linux/compat.h>
#include <linux/fs.h>
+#include <linux/wait_bit.h>
#include <linux/path.h>
#include <linux/timekeeping.h>
#include <linux/sysctl.h>
@@ -512,7 +513,7 @@ static int zap_threads(struct task_struct *tsk,
nr = zap_process(signal, exit_code);
clear_tsk_thread_flag(tsk, TIF_SIGPENDING);
tsk->flags |= PF_DUMPCORE;
- atomic_set(&core_state->nr_threads, nr);
+ atomic_set(&core_state->threads_remaining, nr);
}
spin_unlock_irq(&tsk->sighand->siglock);
return nr;
@@ -523,15 +524,15 @@ static int coredump_wait(int exit_code, struct core_state *core_state)
struct task_struct *tsk = current;
int core_waiters = -EBUSY;
- init_completion(&core_state->startup);
core_state->tasks = NULL;
core_waiters = zap_threads(tsk, core_state, exit_code);
if (core_waiters > 0) {
struct core_thread *ptr;
- wait_for_completion_state(&core_state->startup,
- TASK_UNINTERRUPTIBLE|TASK_FREEZABLE);
+ wait_var_event_state(&core_state->threads_remaining,
+ !atomic_read_acquire(&core_state->threads_remaining),
+ TASK_UNINTERRUPTIBLE|TASK_FREEZABLE);
/*
* Wait for all the threads to become inactive, so that
* all the thread context (extended register state, like
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index 14b55d00d605..e039e29cd8c5 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -79,9 +79,9 @@ struct core_thread {
};
struct core_state {
- atomic_t nr_threads;
+ /* Threads the dumper still waits for. */
+ atomic_t threads_remaining;
struct core_thread *tasks;
- struct completion startup;
};
/*
diff --git a/kernel/exit.c b/kernel/exit.c
index 3df1fffc6674..55dbea3b242e 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/capability.h>
#include <linux/completion.h>
+#include <linux/wait_bit.h>
#include <linux/personality.h>
#include <linux/tty.h>
#include <linux/iocontext.h>
@@ -442,8 +443,7 @@ static void coredump_task_exit(struct task_struct *tsk,
* Implies mb(), the result of xchg() must be visible
* to the dumper.
*/
- if (atomic_dec_and_test(&core_state->nr_threads))
- complete(&core_state->startup);
+ atomic_dec_and_wake_up(&core_state->threads_remaining);
for (;;) {
set_current_state(TASK_IDLE|TASK_FREEZABLE);
@@ -917,7 +917,7 @@ static void synchronize_group_exit(struct task_struct *tsk, long code)
* Serialize with any possible pending coredump.
* We must hold siglock around checking core_state
* and setting PF_POSTCOREDUMP. The core-inducing thread
- * will increment ->nr_threads for each thread in the
+ * will increment ->threads_remaining for each thread in the
* group without PF_POSTCOREDUMP set.
*/
tsk->flags |= PF_POSTCOREDUMP;