diff options
author | Tejun Heo <tj@kernel.org> | 2011-03-23 05:37:01 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-03-23 05:37:01 -0400 |
commit | 75b95953a56969a990e6ce154b260be83818fe71 (patch) | |
tree | a6a78c433a1ace907511f71be289cdd16ec1137f /kernel | |
parent | 45cb24a1da53beb70f09efccc0373f6a47a9efe0 (diff) |
job control: Add @for_ptrace to do_notify_parent_cldstop()
Currently, do_notify_parent_cldstop() determines whether the
notification is for the real parent or ptracer. Move the decision to
the caller by adding @for_ptrace parameter to
do_notify_parent_cldstop(). All the callers are updated to pass
task_ptrace(target_task), so this patch doesn't cause any behavior
difference.
While at it, add function comment to do_notify_parent_cldstop().
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/signal.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 2f2c8f6ee01f..69d60540a680 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1595,16 +1595,30 @@ int do_notify_parent(struct task_struct *tsk, int sig) | |||
1595 | return ret; | 1595 | return ret; |
1596 | } | 1596 | } |
1597 | 1597 | ||
1598 | static void do_notify_parent_cldstop(struct task_struct *tsk, int why) | 1598 | /** |
1599 | * do_notify_parent_cldstop - notify parent of stopped/continued state change | ||
1600 | * @tsk: task reporting the state change | ||
1601 | * @for_ptracer: the notification is for ptracer | ||
1602 | * @why: CLD_{CONTINUED|STOPPED|TRAPPED} to report | ||
1603 | * | ||
1604 | * Notify @tsk's parent that the stopped/continued state has changed. If | ||
1605 | * @for_ptracer is %false, @tsk's group leader notifies to its real parent. | ||
1606 | * If %true, @tsk reports to @tsk->parent which should be the ptracer. | ||
1607 | * | ||
1608 | * CONTEXT: | ||
1609 | * Must be called with tasklist_lock at least read locked. | ||
1610 | */ | ||
1611 | static void do_notify_parent_cldstop(struct task_struct *tsk, | ||
1612 | bool for_ptracer, int why) | ||
1599 | { | 1613 | { |
1600 | struct siginfo info; | 1614 | struct siginfo info; |
1601 | unsigned long flags; | 1615 | unsigned long flags; |
1602 | struct task_struct *parent; | 1616 | struct task_struct *parent; |
1603 | struct sighand_struct *sighand; | 1617 | struct sighand_struct *sighand; |
1604 | 1618 | ||
1605 | if (task_ptrace(tsk)) | 1619 | if (for_ptracer) { |
1606 | parent = tsk->parent; | 1620 | parent = tsk->parent; |
1607 | else { | 1621 | } else { |
1608 | tsk = tsk->group_leader; | 1622 | tsk = tsk->group_leader; |
1609 | parent = tsk->real_parent; | 1623 | parent = tsk->real_parent; |
1610 | } | 1624 | } |
@@ -1743,7 +1757,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) | |||
1743 | spin_unlock_irq(¤t->sighand->siglock); | 1757 | spin_unlock_irq(¤t->sighand->siglock); |
1744 | read_lock(&tasklist_lock); | 1758 | read_lock(&tasklist_lock); |
1745 | if (may_ptrace_stop()) { | 1759 | if (may_ptrace_stop()) { |
1746 | do_notify_parent_cldstop(current, why); | 1760 | do_notify_parent_cldstop(current, task_ptrace(current), why); |
1747 | /* | 1761 | /* |
1748 | * Don't want to allow preemption here, because | 1762 | * Don't want to allow preemption here, because |
1749 | * sys_ptrace() needs this task to be inactive. | 1763 | * sys_ptrace() needs this task to be inactive. |
@@ -1886,7 +1900,8 @@ retry: | |||
1886 | 1900 | ||
1887 | if (notify) { | 1901 | if (notify) { |
1888 | read_lock(&tasklist_lock); | 1902 | read_lock(&tasklist_lock); |
1889 | do_notify_parent_cldstop(current, notify); | 1903 | do_notify_parent_cldstop(current, task_ptrace(current), |
1904 | notify); | ||
1890 | read_unlock(&tasklist_lock); | 1905 | read_unlock(&tasklist_lock); |
1891 | } | 1906 | } |
1892 | 1907 | ||
@@ -1982,6 +1997,7 @@ relock: | |||
1982 | * the CLD_ si_code into SIGNAL_CLD_MASK bits. | 1997 | * the CLD_ si_code into SIGNAL_CLD_MASK bits. |
1983 | */ | 1998 | */ |
1984 | if (unlikely(signal->flags & SIGNAL_CLD_MASK)) { | 1999 | if (unlikely(signal->flags & SIGNAL_CLD_MASK)) { |
2000 | struct task_struct *leader; | ||
1985 | int why; | 2001 | int why; |
1986 | 2002 | ||
1987 | if (signal->flags & SIGNAL_CLD_CONTINUED) | 2003 | if (signal->flags & SIGNAL_CLD_CONTINUED) |
@@ -1994,7 +2010,8 @@ relock: | |||
1994 | spin_unlock_irq(&sighand->siglock); | 2010 | spin_unlock_irq(&sighand->siglock); |
1995 | 2011 | ||
1996 | read_lock(&tasklist_lock); | 2012 | read_lock(&tasklist_lock); |
1997 | do_notify_parent_cldstop(current->group_leader, why); | 2013 | leader = current->group_leader; |
2014 | do_notify_parent_cldstop(leader, task_ptrace(leader), why); | ||
1998 | read_unlock(&tasklist_lock); | 2015 | read_unlock(&tasklist_lock); |
1999 | goto relock; | 2016 | goto relock; |
2000 | } | 2017 | } |
@@ -2167,7 +2184,7 @@ out: | |||
2167 | 2184 | ||
2168 | if (unlikely(group_stop)) { | 2185 | if (unlikely(group_stop)) { |
2169 | read_lock(&tasklist_lock); | 2186 | read_lock(&tasklist_lock); |
2170 | do_notify_parent_cldstop(tsk, group_stop); | 2187 | do_notify_parent_cldstop(tsk, task_ptrace(tsk), group_stop); |
2171 | read_unlock(&tasklist_lock); | 2188 | read_unlock(&tasklist_lock); |
2172 | } | 2189 | } |
2173 | } | 2190 | } |