[PATCH 04/19] introduce wake_up_quiescent()

Oleg Nesterov oleg at redhat.com
Fri Jul 1 00:21:07 UTC 2011


No functional changes. Add the new helper, wake_up_quiescent(task, state),
which simply returns wake_up_state(task, state). Change all callers which
do wake_up_state(STOPPED/TRACED) to use the new helper. ptrace_stop() is
a bit special, it does __set_current_state(RUNNING) in the very unlikely
case, change it as well.

Signed-off-by: Oleg Nesterov <oleg at redhat.com>
---
 include/linux/signal.h |    2 ++
 kernel/ptrace.c        |    2 +-
 kernel/signal.c        |   12 ++++++++++--
 kernel/utrace.c        |    2 +-
 4 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/include/linux/signal.h b/include/linux/signal.h
index a822300..2be3712 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -239,6 +239,8 @@ static inline int valid_signal(unsigned long sig)
 struct timespec;
 struct pt_regs;
 
+extern int wake_up_quiescent(struct task_struct *p, unsigned int state);
+
 extern int next_signal(struct sigpending *pending, sigset_t *mask);
 extern int do_send_sig_info(int sig, struct siginfo *info,
 				struct task_struct *p, bool group);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 9988b13..26ae214 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -566,7 +566,7 @@ static int ptrace_resume(struct task_struct *child, long request,
 	child->exit_code = data;
 
 	if (lock_task_sighand(child, &flags)) {
-		wake_up_state(child, __TASK_TRACED);
+		wake_up_quiescent(child, __TASK_TRACED);
 		unlock_task_sighand(child, &flags);
 	}
 
diff --git a/kernel/signal.c b/kernel/signal.c
index 2138cee..4fcf1c7 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -652,6 +652,14 @@ void signal_wake_up(struct task_struct *t, int resume)
 }
 
 /*
+ * wakes up the STOPPED/TRACED task, must be called with ->siglock held.
+ */
+int wake_up_quiescent(struct task_struct *p, unsigned int state)
+{
+	return wake_up_state(p, state);
+}
+
+/*
  * Remove signals in mask from the pending set and queue.
  * Returns 1 if any signals were found.
  *
@@ -811,7 +819,7 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns)
 		do {
 			task_clear_group_stop_pending(t);
 			rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
-			wake_up_state(t, __TASK_STOPPED);
+			wake_up_quiescent(t, __TASK_STOPPED);
 		} while_each_thread(p, t);
 
 		/*
@@ -1800,7 +1808,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
 			do_notify_parent_cldstop(current, false, why);
 
 		spin_lock_irq(&current->sighand->siglock);
-		__set_current_state(TASK_RUNNING);
+		wake_up_quiescent(current, __TASK_TRACED);
 		spin_unlock_irq(&current->sighand->siglock);
 
 		if (clear_code)
diff --git a/kernel/utrace.c b/kernel/utrace.c
index 6e7fafb..d7c547c 100644
--- a/kernel/utrace.c
+++ b/kernel/utrace.c
@@ -648,7 +648,7 @@ static void utrace_wakeup(struct task_struct *target, struct utrace *utrace)
 {
 	lockdep_assert_held(&utrace->lock);
 	spin_lock_irq(&target->sighand->siglock);
-	wake_up_state(target, __TASK_TRACED);
+	wake_up_quiescent(target, __TASK_TRACED);
 	spin_unlock_irq(&target->sighand->siglock);
 }
 
-- 
1.5.5.1




More information about the kernel mailing list