diff options
Diffstat (limited to 'arch/ia64/kernel/ptrace.c')
| -rw-r--r-- | arch/ia64/kernel/ptrace.c | 28 |
1 files changed, 11 insertions, 17 deletions
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index bbb8bc7c0552..4b19d0410632 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
| @@ -587,8 +587,9 @@ thread_matches (struct task_struct *thread, unsigned long addr) | |||
| 587 | static struct task_struct * | 587 | static struct task_struct * |
| 588 | find_thread_for_addr (struct task_struct *child, unsigned long addr) | 588 | find_thread_for_addr (struct task_struct *child, unsigned long addr) |
| 589 | { | 589 | { |
| 590 | struct task_struct *g, *p; | 590 | struct task_struct *p; |
| 591 | struct mm_struct *mm; | 591 | struct mm_struct *mm; |
| 592 | struct list_head *this, *next; | ||
| 592 | int mm_users; | 593 | int mm_users; |
| 593 | 594 | ||
| 594 | if (!(mm = get_task_mm(child))) | 595 | if (!(mm = get_task_mm(child))) |
| @@ -600,28 +601,21 @@ find_thread_for_addr (struct task_struct *child, unsigned long addr) | |||
| 600 | goto out; /* not multi-threaded */ | 601 | goto out; /* not multi-threaded */ |
| 601 | 602 | ||
| 602 | /* | 603 | /* |
| 603 | * First, traverse the child's thread-list. Good for scalability with | 604 | * Traverse the current process' children list. Every task that |
| 604 | * NPTL-threads. | 605 | * one attaches to becomes a child. And it is only attached children |
| 606 | * of the debugger that are of interest (ptrace_check_attach checks | ||
| 607 | * for this). | ||
| 605 | */ | 608 | */ |
| 606 | p = child; | 609 | list_for_each_safe(this, next, ¤t->children) { |
| 607 | do { | 610 | p = list_entry(this, struct task_struct, sibling); |
| 608 | if (thread_matches(p, addr)) { | 611 | if (p->mm != mm) |
| 609 | child = p; | ||
| 610 | goto out; | ||
| 611 | } | ||
| 612 | if (mm_users-- <= 1) | ||
| 613 | goto out; | ||
| 614 | } while ((p = next_thread(p)) != child); | ||
| 615 | |||
| 616 | do_each_thread(g, p) { | ||
| 617 | if (child->mm != mm) | ||
| 618 | continue; | 612 | continue; |
| 619 | |||
| 620 | if (thread_matches(p, addr)) { | 613 | if (thread_matches(p, addr)) { |
| 621 | child = p; | 614 | child = p; |
| 622 | goto out; | 615 | goto out; |
| 623 | } | 616 | } |
| 624 | } while_each_thread(g, p); | 617 | } |
| 618 | |||
| 625 | out: | 619 | out: |
| 626 | mmput(mm); | 620 | mmput(mm); |
| 627 | return child; | 621 | return child; |
