drm/radeon/kms: make initial state of load detect property correct.
[safe/jmp/linux-2.6] / kernel / signal.c
index 5d3b3f8..6705320 100644 (file)
@@ -971,6 +971,20 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
        return send_signal(sig, info, t, 0);
 }
 
+int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p,
+                       bool group)
+{
+       unsigned long flags;
+       int ret = -ESRCH;
+
+       if (lock_task_sighand(p, &flags)) {
+               ret = send_signal(sig, info, p, group);
+               unlock_task_sighand(p, &flags);
+       }
+
+       return ret;
+}
+
 /*
  * Force a signal that the process can't ignore: if necessary
  * we unblock the signal and change any SIG_IGN to SIG_DFL.
@@ -1036,12 +1050,6 @@ void zap_other_threads(struct task_struct *p)
        }
 }
 
-int __fatal_signal_pending(struct task_struct *tsk)
-{
-       return sigismember(&tsk->pending.signal, SIGKILL);
-}
-EXPORT_SYMBOL(__fatal_signal_pending);
-
 struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags)
 {
        struct sighand_struct *sighand;
@@ -1068,18 +1076,10 @@ struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long
  */
 int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
-       unsigned long flags;
-       int ret;
+       int ret = check_kill_permission(sig, info, p);
 
-       ret = check_kill_permission(sig, info, p);
-
-       if (!ret && sig) {
-               ret = -ESRCH;
-               if (lock_task_sighand(p, &flags)) {
-                       ret = __group_send_sig_info(sig, info, p);
-                       unlock_task_sighand(p, &flags);
-               }
-       }
+       if (!ret && sig)
+               ret = do_send_sig_info(sig, info, p, true);
 
        return ret;
 }
@@ -1224,15 +1224,9 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid)
  * These are for backward compatibility with the rest of the kernel source.
  */
 
-/*
- * The caller must ensure the task can't exit.
- */
 int
 send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
-       int ret;
-       unsigned long flags;
-
        /*
         * Make sure legacy kernel users don't send in bad values
         * (normal paths check this in check_kill_permission).
@@ -1240,10 +1234,7 @@ send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
        if (!valid_signal(sig))
                return -EINVAL;
 
-       spin_lock_irqsave(&p->sighand->siglock, flags);
-       ret = specific_send_sig_info(sig, info, p);
-       spin_unlock_irqrestore(&p->sighand->siglock, flags);
-       return ret;
+       return do_send_sig_info(sig, info, p, false);
 }
 
 #define __si_special(priv) \
@@ -2278,7 +2269,6 @@ static int
 do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
 {
        struct task_struct *p;
-       unsigned long flags;
        int error = -ESRCH;
 
        rcu_read_lock();
@@ -2288,14 +2278,16 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
                /*
                 * The null signal is a permissions and process existence
                 * probe.  No signal is actually delivered.
-                *
-                * If lock_task_sighand() fails we pretend the task dies
-                * after receiving the signal. The window is tiny, and the
-                * signal is private anyway.
                 */
-               if (!error && sig && lock_task_sighand(p, &flags)) {
-                       error = specific_send_sig_info(sig, info, p);
-                       unlock_task_sighand(p, &flags);
+               if (!error && sig) {
+                       error = do_send_sig_info(sig, info, p, false);
+                       /*
+                        * If lock_task_sighand() failed we pretend the task
+                        * dies after receiving the signal. The window is tiny,
+                        * and the signal is private anyway.
+                        */
+                       if (unlikely(error == -ESRCH))
+                               error = 0;
                }
        }
        rcu_read_unlock();