[PATCH 08/31] restore the DEATH/REAP utrace hooks

Oleg Nesterov oleg at redhat.com
Wed Aug 3 19:09:45 UTC 2011


Restore the necessary hooks in release_task() and exit_notify(),
add the corresponding helpers into utrace.h.

Note: the @signal argument passed to ->report_death() does not
match the previous behaviour. I think this shouldn't affect the
current users, and I bet nobody can really understand what this
magic argument should actually mean anyway.

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

diff --git a/include/linux/utrace.h b/include/linux/utrace.h
index 9a2e2f4..cf13839 100644
--- a/include/linux/utrace.h
+++ b/include/linux/utrace.h
@@ -697,4 +697,26 @@ static inline __must_check int utrace_barrier_pid(struct pid *pid,
 
 #endif	/* CONFIG_UTRACE */
 
+static inline void utrace_release_task(struct task_struct *task)
+{
+	/* see utrace_add_engine() about this barrier */
+	smp_mb();
+	if (task_utrace_flags(task))
+		utrace_maybe_reap(task, task_utrace_struct(task), true);
+}
+
+static inline void utrace_exit_notify(struct task_struct *task,
+					  int signal, int group_dead)
+{
+	/*
+	 * If utrace_set_events() was just called to enable
+	 * UTRACE_EVENT(DEATH), then we are obliged to call
+	 * utrace_report_death() and not miss it.  utrace_set_events()
+	 * checks @task->exit_state under tasklist_lock to synchronize
+	 * with exit_notify(), the caller.
+	 */
+	if (task_utrace_flags(task) & _UTRACE_DEATH_EVENTS)
+		utrace_report_death(task, group_dead, signal);
+}
+
 #endif	/* linux/utrace.h */
diff --git a/kernel/exit.c b/kernel/exit.c
index c1b0ab6..ba5ba22 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -168,6 +168,8 @@ void release_task(struct task_struct * p)
 	struct task_struct *leader;
 	int zap_leader;
 repeat:
+	utrace_release_task(p);
+
 	/* don't need to get the RCU readlock here - the process is dead and
 	 * can't be modifying its own credentials. But shut RCU-lockdep up */
 	rcu_read_lock();
@@ -860,6 +862,8 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
 		wake_up_process(tsk->signal->group_exit_task);
 	write_unlock_irq(&tasklist_lock);
 
+	utrace_exit_notify(tsk, autoreap ? -1 : SIGCHLD, group_dead);
+
 	/* If the process is dead, release it - nobody will wait for it */
 	if (autoreap)
 		release_task(tsk);
-- 
1.5.5.1




More information about the kernel mailing list