From 4ad085b81b02aeae490f479dc7932d3de9003a2c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 11 May 2006 11:08:49 -0700 Subject: [PATCH] --- yaml --- r: 26604 b: refs/heads/master c: f358166a9405e4f1d8e50d8f415c26d95505b6de h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/kernel/ptrace.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index ac0cb62686da..02c8fb3f16bd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0e44dc383787b472a7f13564c6bd8a44cc07d408 +refs/heads/master: f358166a9405e4f1d8e50d8f415c26d95505b6de diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index b0f8da80d7d4..921c22ad16e4 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -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)