diff options
author | Oleg Nesterov <oleg@redhat.com> | 2009-06-17 19:27:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 16:03:52 -0400 |
commit | e49612544c695117644af48bb4625264a3d2918f (patch) | |
tree | 7fe576d195533fb671c7a610cc35e9608e48c87e /kernel/ptrace.c | |
parent | d92656633b8352c6d4b14afcb7beb154d76e7aa6 (diff) |
ptrace: don't take tasklist to get/set ->last_siginfo
Change ptrace_getsiginfo/ptrace_setsiginfo to use lock_task_sighand()
without tasklist_lock. Perhaps it makes sense to make a single helper
with "bool rw" argument.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r-- | kernel/ptrace.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index a64fe75a48ba..61c78b2c07ba 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -424,37 +424,33 @@ static int ptrace_setoptions(struct task_struct *child, long data) | |||
424 | 424 | ||
425 | static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) | 425 | static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) |
426 | { | 426 | { |
427 | unsigned long flags; | ||
427 | int error = -ESRCH; | 428 | int error = -ESRCH; |
428 | 429 | ||
429 | read_lock(&tasklist_lock); | 430 | if (lock_task_sighand(child, &flags)) { |
430 | if (likely(child->sighand != NULL)) { | ||
431 | error = -EINVAL; | 431 | error = -EINVAL; |
432 | spin_lock_irq(&child->sighand->siglock); | ||
433 | if (likely(child->last_siginfo != NULL)) { | 432 | if (likely(child->last_siginfo != NULL)) { |
434 | *info = *child->last_siginfo; | 433 | *info = *child->last_siginfo; |
435 | error = 0; | 434 | error = 0; |
436 | } | 435 | } |
437 | spin_unlock_irq(&child->sighand->siglock); | 436 | unlock_task_sighand(child, &flags); |
438 | } | 437 | } |
439 | read_unlock(&tasklist_lock); | ||
440 | return error; | 438 | return error; |
441 | } | 439 | } |
442 | 440 | ||
443 | static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) | 441 | static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) |
444 | { | 442 | { |
443 | unsigned long flags; | ||
445 | int error = -ESRCH; | 444 | int error = -ESRCH; |
446 | 445 | ||
447 | read_lock(&tasklist_lock); | 446 | if (lock_task_sighand(child, &flags)) { |
448 | if (likely(child->sighand != NULL)) { | ||
449 | error = -EINVAL; | 447 | error = -EINVAL; |
450 | spin_lock_irq(&child->sighand->siglock); | ||
451 | if (likely(child->last_siginfo != NULL)) { | 448 | if (likely(child->last_siginfo != NULL)) { |
452 | *child->last_siginfo = *info; | 449 | *child->last_siginfo = *info; |
453 | error = 0; | 450 | error = 0; |
454 | } | 451 | } |
455 | spin_unlock_irq(&child->sighand->siglock); | 452 | unlock_task_sighand(child, &flags); |
456 | } | 453 | } |
457 | read_unlock(&tasklist_lock); | ||
458 | return error; | 454 | return error; |
459 | } | 455 | } |
460 | 456 | ||