[PATCH 78] attach: try to re-use the self-detaching engine

Oleg Nesterov oleg at redhat.com
Fri Oct 9 17:09:17 UTC 2009


Change ptrace_attach_task() to re-use the self-detaching engine first,
then do utrace_attach_task(UTRACE_ATTACH_CREATE).

Todo:

	- re-check this all (and test)

	- rename check()

	- cleanups the mess in ptrace_attach_task()

	- ptrace_detach_task() should clear options/flags, if we re-use
	  this engine then ptrace_attach_task()->utrace_set_events()
	  happens a bit late.

---

 kernel/ptrace.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

--- PU/kernel/ptrace.c~78_REUSE_PARTING_ENGINE	2009-10-09 18:51:56.000000000 +0200
+++ PU/kernel/ptrace.c	2009-10-09 19:04:34.000000000 +0200
@@ -431,6 +431,15 @@ static inline int __ptrace_set_options(s
 	return utrace_set_events(target, engine, events);
 }
 
+static bool check(void *data)
+{
+	struct ptrace_context *context = data;
+	if (context->resume != UTRACE_DETACH)
+		return false;
+	context->resume = UTRACE_RESUME;
+	return true;
+}
+
 /*
  * Attach a utrace engine for ptrace and set up its event mask.
  * Returns error code or 0 on success.
@@ -441,6 +450,20 @@ static int ptrace_attach_task(struct tas
 	struct utrace_engine *engine;
 	int err;
 
+	engine = utrace_attach_task(tracee, UTRACE_ATTACH_MATCH_OPS |
+						UTRACE_ATTACH_MATCH_CHECK,
+						&ptrace_utrace_ops, check);
+	if (!IS_ERR(engine)) {
+		/*
+		 * Make sure we don't race with ptrace_report_signal()
+		 */
+		utrace_barrier(tracee, engine);
+		if (engine->ops != &ptrace_utrace_ops)
+			utrace_engine_put(engine);
+		else
+			goto finish;
+	}
+
 	context = kzalloc(sizeof(*context), GFP_KERNEL);
 	if (unlikely(!context))
 		return -ENOMEM;
@@ -458,6 +481,7 @@ static int ptrace_attach_task(struct tas
 		kfree(context);
 		return err;
 	}
+finish:
 	/*
 	 * It can fail only if the tracee is dead, the caller
 	 * must notice this before setting PT_PTRACED.




More information about the utrace-devel mailing list