]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/signal.c
korina: misc cleanup
[linux-2.6-omap-h63xx.git] / kernel / signal.c
index cc45a6b6913409367dc35cb0a2ab2c75f737de76..cc8303cd093dd5f05e7218b7f35d77d340bddc09 100644 (file)
@@ -972,7 +972,7 @@ void zap_other_threads(struct task_struct *p)
        }
 }
 
-int fastcall __fatal_signal_pending(struct task_struct *tsk)
+int __fatal_signal_pending(struct task_struct *tsk)
 {
        return sigismember(&tsk->pending.signal, SIGKILL);
 }
@@ -1018,7 +1018,7 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 }
 
 /*
- * kill_pgrp_info() sends a signal to a process group: this is what the tty
+ * __kill_pgrp_info() sends a signal to a process group: this is what the tty
  * control characters do (^C, ^Z etc)
  */
 
@@ -1037,17 +1037,6 @@ int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
        return success ? 0 : retval;
 }
 
-int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
-{
-       int retval;
-
-       read_lock(&tasklist_lock);
-       retval = __kill_pgrp_info(sig, info, pgrp);
-       read_unlock(&tasklist_lock);
-
-       return retval;
-}
-
 int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
 {
        int error = -ESRCH;
@@ -1134,14 +1123,22 @@ EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);
 static int kill_something_info(int sig, struct siginfo *info, int pid)
 {
        int ret;
-       rcu_read_lock();
-       if (!pid) {
-               ret = kill_pgrp_info(sig, info, task_pgrp(current));
-       } else if (pid == -1) {
+
+       if (pid > 0) {
+               rcu_read_lock();
+               ret = kill_pid_info(sig, info, find_vpid(pid));
+               rcu_read_unlock();
+               return ret;
+       }
+
+       read_lock(&tasklist_lock);
+       if (pid != -1) {
+               ret = __kill_pgrp_info(sig, info,
+                               pid ? find_vpid(-pid) : task_pgrp(current));
+       } else {
                int retval = 0, count = 0;
                struct task_struct * p;
 
-               read_lock(&tasklist_lock);
                for_each_process(p) {
                        if (p->pid > 1 && !same_thread_group(p, current)) {
                                int err = group_send_sig_info(sig, info, p);
@@ -1150,14 +1147,10 @@ static int kill_something_info(int sig, struct siginfo *info, int pid)
                                        retval = err;
                        }
                }
-               read_unlock(&tasklist_lock);
                ret = count ? retval : -ESRCH;
-       } else if (pid < 0) {
-               ret = kill_pgrp_info(sig, info, find_vpid(-pid));
-       } else {
-               ret = kill_pid_info(sig, info, find_vpid(pid));
        }
-       rcu_read_unlock();
+       read_unlock(&tasklist_lock);
+
        return ret;
 }
 
@@ -1232,7 +1225,13 @@ force_sigsegv(int sig, struct task_struct *p)
 
 int kill_pgrp(struct pid *pid, int sig, int priv)
 {
-       return kill_pgrp_info(sig, __si_special(priv), pid);
+       int ret;
+
+       read_lock(&tasklist_lock);
+       ret = __kill_pgrp_info(sig, __si_special(priv), pid);
+       read_unlock(&tasklist_lock);
+
+       return ret;
 }
 EXPORT_SYMBOL(kill_pgrp);
 
@@ -1624,7 +1623,6 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info)
        /* Let the debugger run.  */
        __set_current_state(TASK_TRACED);
        spin_unlock_irq(&current->sighand->siglock);
-       try_to_freeze();
        read_lock(&tasklist_lock);
        if (!unlikely(killed) && may_ptrace_stop()) {
                do_notify_parent_cldstop(current, CLD_TRAPPED);
@@ -1641,6 +1639,13 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info)
                read_unlock(&tasklist_lock);
        }
 
+       /*
+        * While in TASK_TRACED, we were considered "frozen enough".
+        * Now that we woke up, it's crucial if we're supposed to be
+        * frozen that we freeze now before running anything substantial.
+        */
+       try_to_freeze();
+
        /*
         * We are back.  Now reacquire the siglock before touching
         * last_siginfo, so that we are sure to have synchronized with
@@ -1752,15 +1757,60 @@ static int do_signal_stop(int signr)
        return 1;
 }
 
+static int ptrace_signal(int signr, siginfo_t *info,
+                        struct pt_regs *regs, void *cookie)
+{
+       if (!(current->ptrace & PT_PTRACED))
+               return signr;
+
+       ptrace_signal_deliver(regs, cookie);
+
+       /* Let the debugger run.  */
+       ptrace_stop(signr, 0, info);
+
+       /* We're back.  Did the debugger cancel the sig?  */
+       signr = current->exit_code;
+       if (signr == 0)
+               return signr;
+
+       current->exit_code = 0;
+
+       /* Update the siginfo structure if the signal has
+          changed.  If the debugger wanted something
+          specific in the siginfo structure then it should
+          have updated *info via PTRACE_SETSIGINFO.  */
+       if (signr != info->si_signo) {
+               info->si_signo = signr;
+               info->si_errno = 0;
+               info->si_code = SI_USER;
+               info->si_pid = task_pid_vnr(current->parent);
+               info->si_uid = current->parent->uid;
+       }
+
+       /* If the (new) signal is now blocked, requeue it.  */
+       if (sigismember(&current->blocked, signr)) {
+               specific_send_sig_info(signr, info, current);
+               signr = 0;
+       }
+
+       return signr;
+}
+
 int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
                          struct pt_regs *regs, void *cookie)
 {
        sigset_t *mask = &current->blocked;
        int signr = 0;
 
+relock:
+       /*
+        * We'll jump back here after any time we were stopped in TASK_STOPPED.
+        * While in TASK_STOPPED, we were considered "frozen enough".
+        * Now that we woke up, it's crucial if we're supposed to be
+        * frozen that we freeze now before running anything substantial.
+        */
        try_to_freeze();
 
-relock:
        spin_lock_irq(&current->sighand->siglock);
        for (;;) {
                struct k_sigaction *ka;
@@ -1774,36 +1824,10 @@ relock:
                if (!signr)
                        break; /* will return 0 */
 
-               if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
-                       ptrace_signal_deliver(regs, cookie);
-
-                       /* Let the debugger run.  */
-                       ptrace_stop(signr, 0, info);
-
-                       /* We're back.  Did the debugger cancel the sig?  */
-                       signr = current->exit_code;
-                       if (signr == 0)
+               if (signr != SIGKILL) {
+                       signr = ptrace_signal(signr, info, regs, cookie);
+                       if (!signr)
                                continue;
-
-                       current->exit_code = 0;
-
-                       /* Update the siginfo structure if the signal has
-                          changed.  If the debugger wanted something
-                          specific in the siginfo structure then it should
-                          have updated *info via PTRACE_SETSIGINFO.  */
-                       if (signr != info->si_signo) {
-                               info->si_signo = signr;
-                               info->si_errno = 0;
-                               info->si_code = SI_USER;
-                               info->si_pid = task_pid_vnr(current->parent);
-                               info->si_uid = current->parent->uid;
-                       }
-
-                       /* If the (new) signal is now blocked, requeue it.  */
-                       if (sigismember(&current->blocked, signr)) {
-                               specific_send_sig_info(signr, info, current);
-                               continue;
-                       }
                }
 
                ka = &current->sighand->action[signr-1];