No functional changes, move reuse/attach code into the new helpers.

Microptimizations:

        - check ->utrace_flags before trying to re-use the self-detaching
          engine

        - if ptrace_reuse_engine() finds engine and ->resume != UTRACE_DETACH,
          we can just return EPERM without trying UTRACE_ATTACH_CREATE.

---

 kernel/ptrace.c |   96 +++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 61 insertions(+), 35 deletions(-)

--- PU/kernel/ptrace.c~86_CLEANUP_ATTACH_REUSE  2009-10-13 14:15:48.000000000 
+0200
+++ PU/kernel/ptrace.c  2009-10-13 17:36:05.000000000 +0200
@@ -421,6 +421,64 @@ static const struct utrace_engine_ops pt
        .release = ptrace_release,
 };
 
+static struct utrace_engine *
+ptrace_reuse_engine(struct task_struct *tracee)
+{
+       struct utrace_engine *engine;
+       struct ptrace_context *context;
+       int err = -EPERM;
+
+       engine = ptrace_lookup_engine(tracee);
+       if (IS_ERR(engine))
+               return engine;
+
+       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);
+               WARN_ON(!err != (engine->ops == &ptrace_utrace_ops));
+               if (!err)
+                       return engine;
+       }
+
+       utrace_engine_put(engine);
+       return ERR_PTR(err);
+}
+
+static struct utrace_engine *
+ptrace_attach_engine(struct task_struct *tracee)
+{
+       struct utrace_engine *engine;
+       struct ptrace_context *context;
+
+       if (unlikely(task_utrace_flags(tracee))) {
+               engine = ptrace_reuse_engine(tracee);
+               if (!IS_ERR(engine) || IS_ERR(engine) == -EPERM)
+                       return engine;
+       }
+
+       context = kzalloc(sizeof(*context), GFP_KERNEL);
+       if (unlikely(!context))
+               return ERR_PTR(-ENOMEM);
+
+       context->resume = UTRACE_RESUME;
+
+       engine = utrace_attach_task(tracee, UTRACE_ATTACH_CREATE |
+                                               UTRACE_ATTACH_EXCLUSIVE |
+                                               UTRACE_ATTACH_MATCH_OPS,
+                                               &ptrace_utrace_ops, context);
+       if (unlikely(IS_ERR(engine))) {
+               if (engine != ERR_PTR(-ESRCH) &&
+                   engine != ERR_PTR(-ERESTARTNOINTR))
+                       engine = ERR_PTR(-EPERM);
+               kfree(context);
+       }
+
+       return engine;
+}
+
 static inline int __ptrace_set_options(struct task_struct *target,
                                        struct utrace_engine *engine,
                                        unsigned long options)
@@ -446,44 +504,12 @@ static inline int __ptrace_set_options(s
  */
 static int ptrace_attach_task(struct task_struct *tracee, int options)
 {
-       struct ptrace_context *context;
        struct utrace_engine *engine;
        int err;
 
-       engine = ptrace_lookup_engine(tracee);
-       if (!IS_ERR(engine)) {
-               context = ptrace_context(engine);
-               if (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);
-                       if (!err)
-                               goto finish;
-               }
-               utrace_engine_put(engine);
-       }
-
-       context = kzalloc(sizeof(*context), GFP_KERNEL);
-       if (unlikely(!context))
-               return -ENOMEM;
-
-       context->resume = UTRACE_RESUME;
-
-       engine = utrace_attach_task(tracee, UTRACE_ATTACH_CREATE |
-                                               UTRACE_ATTACH_EXCLUSIVE |
-                                               UTRACE_ATTACH_MATCH_OPS,
-                                               &ptrace_utrace_ops, context);
-       if (unlikely(IS_ERR(engine))) {
-               err = PTR_ERR(engine);
-               if (err != -ESRCH && err != -ERESTARTNOINTR)
-                       err = -EPERM;
-               kfree(context);
-               return err;
-       }
-finish:
+       engine = ptrace_attach_engine(tracee);
+       if (IS_ERR(engine))
+               return PTR_ERR(engine);
        /*
         * It can fail only if the tracee is dead, the caller
         * must notice this before setting PT_PTRACED.

Reply via email to