uprobes: Change the callsite of uprobe_copy_process()
authorOleg Nesterov <oleg@redhat.com>
Sun, 13 Oct 2013 19:18:31 +0000 (21:18 +0200)
committerOleg Nesterov <oleg@redhat.com>
Tue, 29 Oct 2013 17:02:48 +0000 (18:02 +0100)
Preparation for the next patches.

Move the callsite of uprobe_copy_process() in copy_process() down
to the succesfull return. We do not care if copy_process() fails,
uprobe_free_utask() won't be called in this case so the wrong
->utask != NULL doesn't matter.

OTOH, with this change we know that copy_process() can't fail when
uprobe_copy_process() is called, the new task should either return
to user-mode or call do_exit(). This way uprobe_copy_process() can:

1. setup p->utask != NULL if necessary

2. setup uprobes_state.xol_area

3. use task_work_add(p)

Also, move the definition of uprobe_copy_process() down so that it
can see get_utask().

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
kernel/events/uprobes.c
kernel/fork.c

index ad8e1bdca70e4c702ff5c6e86255dc74a8b98259..db7a1dcb3dd68a43d58dc1faf27015015dc9990f 100644 (file)
@@ -1344,14 +1344,6 @@ void uprobe_free_utask(struct task_struct *t)
        t->utask = NULL;
 }
 
-/*
- * Called in context of a new clone/fork from copy_process.
- */
-void uprobe_copy_process(struct task_struct *t)
-{
-       t->utask = NULL;
-}
-
 /*
  * Allocate a uprobe_task object for the task if if necessary.
  * Called when the thread hits a breakpoint.
@@ -1367,6 +1359,14 @@ static struct uprobe_task *get_utask(void)
        return current->utask;
 }
 
+/*
+ * Called in context of a new clone/fork from copy_process.
+ */
+void uprobe_copy_process(struct task_struct *t)
+{
+       t->utask = NULL;
+}
+
 /*
  * Current area->vaddr notion assume the trampoline address is always
  * equal area->vaddr.
index 086fe73ad6bde5b1ac1703f29f3d9f154878968b..d3603b81246b5e4b8e3c683ad81123059dbfec67 100644 (file)
@@ -1373,7 +1373,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        INIT_LIST_HEAD(&p->pi_state_list);
        p->pi_state_cache = NULL;
 #endif
-       uprobe_copy_process(p);
        /*
         * sigaltstack should be cleared when sharing the same VM
         */
@@ -1490,6 +1489,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        perf_event_fork(p);
 
        trace_task_newtask(p, clone_flags);
+       uprobe_copy_process(p);
 
        return p;