[PATCH 87] shift context re-initialization from detach to reuse

Oleg Nesterov oleg at redhat.com
Tue Oct 13 16:27:46 UTC 2009


It doesn't make sense to reset engine->context unless we know we
are going to re-use it, move this code to ptrace_reuse_engine().

Except: ptrace_detach_task() has to clear context->stop_code
(it is checked by ptrace_report_signal()) and tracee->exit_code.
This will be removed later, when we change detach to use
ptrace_wake_up(action) instead of utrace_control().

Also, improve the comments.

---

 kernel/ptrace.c |   31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)

--- PU/kernel/ptrace.c~87_SHIFT_REINIT_TO_REUSE	2009-10-13 17:36:05.000000000 +0200
+++ PU/kernel/ptrace.c	2009-10-13 18:14:55.000000000 +0200
@@ -107,18 +107,11 @@ static void ptrace_detach_task(struct ta
 			break;
 
 		case PTRACE_EVENT_SIGNAL:
+			/* make sure do_wait() can't succeed */
+			tracee->exit_code = 0;
 			if (valid_signal(sig))
 				context->signr = sig;
-			context->options = 0;
-			context->eventmsg = 0;
 			context->stop_code = 0;
-			/* make sure do_wait() can't succeed */
-			tracee->exit_code = 0;
-			utrace_set_events(tracee, engine, UTRACE_EVENT(QUIESCE));
-			/*
-			 * once we set UTRACE_DETACH we don't own this engine,
-			 * utrace_set_events() also acts as a memory barrier.
-			 */
 			context->resume = UTRACE_DETACH;
 			action = UTRACE_RESUME;
 			break;
@@ -434,11 +427,23 @@ ptrace_reuse_engine(struct task_struct *
 
 	context = ptrace_context(engine);
 	if (unlikely(context->resume == UTRACE_DETACH)) {
-		/* we rely on ->cred_guard_mutex */
-		context->resume = UTRACE_RESUME;
-		/* make sure we don't race with ptrace_report_signal() */
-		err = utrace_barrier(tracee, engine);
+		/*
+		 * Try to reuse this self-detaching engine.
+		 * The only caller which can hit this case is ptrace_attach(),
+		 * it holds ->cred_guard_mutex.
+		 */
+		context->options = 0;
+		context->eventmsg = 0;
+
+		/* make sure we don't get unwanted reports */
+		err = utrace_set_events(tracee, engine, UTRACE_EVENT(QUIESCE));
+		if (!err || err == -EINPROGRESS) {
+			context->resume = UTRACE_RESUME;
+			/* synchronize with ptrace_report_signal() */
+			err = utrace_barrier(tracee, engine);
+		}
 		WARN_ON(!err != (engine->ops == &ptrace_utrace_ops));
+
 		if (!err)
 			return engine;
 	}




More information about the utrace-devel mailing list