[PATCH 1/4] utrace: kill mb() in tracehook_report_death()

2009-12-12 Thread Oleg Nesterov
As Peter pointed out, this barrier is not needed. utrace_set_events()
and tracehook_report_death() can rely on tasklist_lock.

utrace_set_events() checks -exit_state == 0 and adds DEATH_EVENTS
under tasklist_lock. After exit_notify() sets -exit_state under
write_lock(tasklist) we must see the change in flags.

utrace_set_events() does not set _UTRACE_DEATH_EVENTS if -exit_state
was already set by exit_notify(), and after we set -exit_state under
write_lock(tasklist) we must see the change in -utrace_flags.

Signed-off-by: Oleg Nesterov o...@redhat.com
---

 include/linux/tracehook.h |9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

--- UTRACE-PTRACE/include/linux/tracehook.h~1_REPORT_DEATH_KILL_MB  
2009-11-18 21:16:23.0 +0100
+++ UTRACE-PTRACE/include/linux/tracehook.h 2009-12-12 16:32:39.0 
+0100
@@ -626,17 +626,12 @@ static inline void tracehook_report_deat
  int group_dead)
 {
/*
-* This barrier ensures that our caller's setting of
-* @task-exit_state precedes checking @task-utrace_flags here.
 * 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()
-* uses tasklist_lock to synchronize enabling the bit with the
-* actual change to @task-exit_state, but we need this barrier
-* to be sure we see a flags change made just before our caller
-* took the tasklist_lock.
+* checks @task-exit_state under tasklist_lock to synchronize
+* with exit_notify(), the caller.
 */
-   smp_mb();
if (task_utrace_flags(task)  _UTRACE_DEATH_EVENTS)
utrace_report_death(task, death_cookie, group_dead, signal);
 }



[PATCH 2/4] utrace: fix the -cloning check in utrace_attach_delay()

2009-12-12 Thread Oleg Nesterov
Due to typo, utrace_attach_delay() always succeeds if the caller
is not traced. The creator must have the valid -utrace != NULL
and utrace-cloning should be target.

Signed-off-by: Oleg Nesterov o...@redhat.com
---

 kernel/utrace.c |   20 
 1 file changed, 12 insertions(+), 8 deletions(-)

--- UTRACE-PTRACE/kernel/utrace.c~2_ATTACH_DELAY_TYPO   2009-12-05 
16:02:50.0 +0100
+++ UTRACE-PTRACE/kernel/utrace.c   2009-12-12 16:49:26.0 +0100
@@ -184,14 +184,18 @@ static struct utrace_engine *matching_en
  */
 static inline int utrace_attach_delay(struct task_struct *target)
 {
-   if ((target-flags  PF_STARTING) 
-   task_utrace_struct(current) 
-   task_utrace_struct(current)-cloning != target)
-   do {
-   schedule_timeout_interruptible(1);
-   if (signal_pending(current))
-   return -ERESTARTNOINTR;
-   } while (target-flags  PF_STARTING);
+   if (!unlikely(target-flags  PF_STARTING))
+   return 0;
+
+   if (task_utrace_struct(current) 
+   task_utrace_struct(current)-cloning == target)
+   return 0;
+
+   do {
+   schedule_timeout_interruptible(1);
+   if (signal_pending(current))
+   return -ERESTARTNOINTR;
+   } while (target-flags  PF_STARTING);
 
return 0;
 }



[PATCH 3/4] utrace: improve the comment in tracehook_notify_resume()

2009-12-12 Thread Oleg Nesterov
My attempt to make the comment more explicit.

Signed-off-by: Oleg Nesterov o...@redhat.com
---

 include/linux/tracehook.h |7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

--- UTRACE-PTRACE/include/linux/tracehook.h~3_NOTIFY_RESUME_MB_COMMENT  
2009-12-12 16:32:39.0 +0100
+++ UTRACE-PTRACE/include/linux/tracehook.h 2009-12-12 17:28:03.0 
+0100
@@ -670,9 +670,10 @@ static inline void tracehook_notify_resu
 {
struct task_struct *task = current;
/*
-* This pairs with the barrier implicit in set_notify_resume().
-* It ensures that we read the nonzero utrace_flags set before
-* set_notify_resume() was called by utrace setup.
+* If we race with attach which sets nonzero -utrace_flags,
+* make sure we do not read -utrace_flags before the caller
+* clears TIF_NOTIFY_RESUME. This pairs with the implicit mb()
+* before setting TIF_NOTIFY_RESUME in set_notify_resume().
 */
smp_rmb();
if (task_utrace_flags(task))



[PATCH 4/4] utrace: fix the comments about rmb() in task_utrace_struct()

2009-12-12 Thread Oleg Nesterov
Move the comment from utrace_task_alloc() to utrace_add_engine()
and try to make it a bit more clear.

Signed-off-by: Oleg Nesterov o...@redhat.com
---

 include/linux/utrace.h |4 ++--
 kernel/utrace.c|   11 +--
 2 files changed, 7 insertions(+), 8 deletions(-)

--- UTRACE-PTRACE/include/linux/utrace.h~4_ADD_ENGINE_DOCUMENT_IMPLICIT_MB  
2009-11-21 15:12:27.0 +0100
+++ UTRACE-PTRACE/include/linux/utrace.h2009-12-12 17:42:16.0 
+0100
@@ -164,8 +164,8 @@ static inline struct utrace *task_utrace
 * is ordered before this load of task-utrace.  We use those
 * utrace_flags checks in the hot path to decide to call into
 * the utrace code.  The first attach installs task-utrace before
-* setting task-utrace_flags nonzero, with a barrier between.
-* See utrace_task_alloc().
+* setting task-utrace_flags nonzero with implicit barrier in
+* between, see utrace_add_engine().
 */
smp_rmb();
utrace = task-utrace;
--- UTRACE-PTRACE/kernel/utrace.c~4_ADD_ENGINE_DOCUMENT_IMPLICIT_MB 
2009-12-12 16:49:26.0 +0100
+++ UTRACE-PTRACE/kernel/utrace.c   2009-12-12 17:46:55.0 +0100
@@ -107,11 +107,7 @@ static bool utrace_task_alloc(struct tas
task-utrace = utrace;
}
task_unlock(task);
-   /*
-* That unlock after storing task-utrace acts as a memory barrier
-* ordering any subsequent task-utrace_flags store afterwards.
-* This pairs with smp_rmb() in task_utrace_struct().
-*/
+
if (unlikely(task-utrace != utrace))
kmem_cache_free(utrace_cachep, utrace);
return true;
@@ -221,7 +217,10 @@ static int utrace_add_engine(struct task
 
/*
 * In case we had no engines before, make sure that
-* utrace_flags is not zero.
+* utrace_flags is not zero. Since we did unlock+lock
+* at least once after utrace_task_alloc() installed
+* -utrace, we have the necessary barrier which pairs
+* with rmb() in task_utrace_struct().
 */
ret = -ESRCH;
if (!target-utrace_flags) {



(no subject)

2009-12-12 Thread Didomenico


inline: polygamize.jpg