[PATCH 09/19] tracehooks: kill tracehook_finish_jctl(), add tracehook_finish_stop()

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


tracehook_finish_jctl() is needed to avoid the races with SIGKILL
which wakes up UTRACED task, and thus it should be called every time
after the STOPPED/TRACED/UTRACED returns from schedule(), remember
that TASK_UTRACED can be added while the task is STOPPED/UTRACED.

- rename it to tracehook_finish_stop(),jctl no longer matches the
  reality.

- change do_signal_state() to call this helper right after schedule(),
  otherwise this logic is broken by the upstream changes

- now that utrace doesn't control TASK_TRACED bit, ptrace_stop() must
  call this helper too.

Signed-off-by: Oleg Nesterov <oleg at redhat.com>
---
 include/linux/tracehook.h |    6 +++---
 kernel/signal.c           |    5 +++--
 kernel/utrace.c           |    2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index 7d7bdde..3c7b6b3 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -528,11 +528,11 @@ static inline int tracehook_get_signal(struct task_struct *task,
 }
 
 /**
- * tracehook_finish_jctl - report about return from job control stop
+ * tracehook_finish_stop - report about return from STOPPED/TRACED
  *
- * This is called by do_signal_stop() after wakeup.
+ * This is called by do_signal_stop() and ptrace_stop after wakeup.
  */
-static inline void tracehook_finish_jctl(void)
+static inline void tracehook_finish_stop(void)
 {
 	if (task_utrace_flags(current))
 		utrace_finish_stop();
diff --git a/kernel/signal.c b/kernel/signal.c
index 4fcf1c7..a7979ad 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1816,6 +1816,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
 		read_unlock(&tasklist_lock);
 	}
 
+	tracehook_finish_stop();
 	/*
 	 * While in TASK_TRACED, we were considered "frozen enough".
 	 * Now that we woke up, it's crucial if we're supposed to be
@@ -1952,6 +1953,8 @@ retry:
 		/* Now we don't run again until woken by SIGCONT or SIGKILL */
 		schedule();
 
+		tracehook_finish_stop();
+
 		spin_lock_irq(&current->sighand->siglock);
 	} else {
 		ptrace_stop(current->group_stop & GROUP_STOP_SIGMASK,
@@ -1974,8 +1977,6 @@ retry:
 
 	spin_unlock_irq(&current->sighand->siglock);
 
-	tracehook_finish_jctl();
-
 	return 1;
 }
 
diff --git a/kernel/utrace.c b/kernel/utrace.c
index be98607..daa96b9 100644
--- a/kernel/utrace.c
+++ b/kernel/utrace.c
@@ -741,7 +741,7 @@ static bool utrace_reset(struct task_struct *task, struct utrace *utrace)
 void utrace_finish_stop(void)
 {
 	/*
-	 * If we were task_is_traced() and then SIGKILL'ed, make
+	 * If we were task_is_utraced() and then SIGKILL'ed, make
 	 * sure we do nothing until the tracer drops utrace->lock.
 	 */
 	if (unlikely(__fatal_signal_pending(current))) {
-- 
1.5.5.1




More information about the kernel mailing list