1) Remove the misleading comment in __sigqueue_alloc() which claims that holding a spinlock is equivalent to rcu_read_lock(). 2) Wrap the __send_signal() call in send_signal() into a rcu read side critical section to guarantee that the __sigqueue_alloc() requirement is met in any case. This needs to be revisited to remove the remaining users of read_lock(&tasklist_lock) but that's outside the scope of this patch. Signed-off-by: Thomas Gleixner Cc: Oleg Nesterov --- kernel/signal.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) Index: linux-2.6-tip/kernel/signal.c =================================================================== --- linux-2.6-tip.orig/kernel/signal.c +++ linux-2.6-tip/kernel/signal.c @@ -220,8 +220,7 @@ __sigqueue_alloc(int sig, struct task_st /* * We won't get problems with the target's UID changing under us * because changing it requires RCU be used, and if t != current, the - * caller must be holding the RCU readlock (by way of a spinlock) and - * we use RCU protection here + * caller must be holding the RCU readlock. */ user = get_uid(__task_cred(t)->user); atomic_inc(&user->sigpending); @@ -946,7 +945,7 @@ out_set: static int send_signal(int sig, struct siginfo *info, struct task_struct *t, int group) { - int from_ancestor_ns = 0; + int ret, from_ancestor_ns = 0; #ifdef CONFIG_PID_NS if (!is_si_special(info) && SI_FROMUSER(info) && @@ -954,7 +953,11 @@ static int send_signal(int sig, struct s from_ancestor_ns = 1; #endif - return __send_signal(sig, info, t, group, from_ancestor_ns); + rcu_read_lock(); + ret = __send_signal(sig, info, t, group, from_ancestor_ns); + rcu_read_unlock(); + + return ret; } static void print_fatal_signal(struct pt_regs *regs, int signr) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/