aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/ptrace.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2009-06-17 19:27:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-18 16:03:52 -0400
commite49612544c695117644af48bb4625264a3d2918f (patch)
tree7fe576d195533fb671c7a610cc35e9608e48c87e /kernel/ptrace.c
parentd92656633b8352c6d4b14afcb7beb154d76e7aa6 (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.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index a64fe75a48b..61c78b2c07b 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
425static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) 425static 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
443static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) 441static 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