Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[pandora-kernel.git] / kernel / ptrace.c
index b0f8da8..921c22a 100644 (file)
@@ -155,8 +155,26 @@ int ptrace_attach(struct task_struct *task)
        if (task->tgid == current->tgid)
                goto out;
 
-       write_lock_irq(&tasklist_lock);
+repeat:
+       /*
+        * Nasty, nasty.
+        *
+        * We want to hold both the task-lock and the
+        * tasklist_lock for writing at the same time.
+        * But that's against the rules (tasklist_lock
+        * is taken for reading by interrupts on other
+        * cpu's that may have task_lock).
+        */
        task_lock(task);
+       local_irq_disable();
+       if (!write_trylock(&tasklist_lock)) {
+               local_irq_enable();
+               task_unlock(task);
+               do {
+                       cpu_relax();
+               } while (!write_can_lock(&tasklist_lock));
+               goto repeat;
+       }
 
        /* the same process cannot be attached many times */
        if (task->ptrace & PT_PTRACED)