]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/signal.c
timerfd: wire the new timerfd API to the x86 family
[linux-2.6-omap-h63xx.git] / kernel / signal.c
index 909a0cc6bc70a3078f3e41a1e42b94a28cd9ae6e..6a5f97cd337a3bc980428ea1c186efedbe991a25 100644 (file)
@@ -55,7 +55,7 @@ static int sig_ignored(struct task_struct *t, int sig)
         * signal handler may change by the time it is
         * unblocked.
         */
-       if (sigismember(&t->blocked, sig))
+       if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
                return 0;
 
        /* Is it explicitly or implicitly ignored? */
@@ -456,15 +456,15 @@ void signal_wake_up(struct task_struct *t, int resume)
        set_tsk_thread_flag(t, TIF_SIGPENDING);
 
        /*
-        * For SIGKILL, we want to wake it up in the stopped/traced case.
-        * We don't check t->state here because there is a race with it
+        * For SIGKILL, we want to wake it up in the stopped/traced/killable
+        * case. We don't check t->state here because there is a race with it
         * executing another processor and just now entering stopped state.
         * By using wake_up_state, we ensure the process will wake up and
         * handle its death signal.
         */
        mask = TASK_INTERRUPTIBLE;
        if (resume)
-               mask |= TASK_STOPPED | TASK_TRACED;
+               mask |= TASK_WAKEKILL;
        if (!wake_up_state(t, mask))
                kick_process(t);
 }
@@ -620,7 +620,7 @@ static void handle_stop_signal(int sig, struct task_struct *p)
                         * Wake up the stopped thread _after_ setting
                         * TIF_SIGPENDING
                         */
-                       state = TASK_STOPPED;
+                       state = __TASK_STOPPED;
                        if (sig_user_defined(t, SIGCONT) && !sigismember(&t->blocked, SIGCONT)) {
                                set_tsk_thread_flag(t, TIF_SIGPENDING);
                                state |= TASK_INTERRUPTIBLE;
@@ -733,13 +733,13 @@ static void print_fatal_signal(struct pt_regs *regs, int signr)
                current->comm, task_pid_nr(current), signr);
 
 #if defined(__i386__) && !defined(__arch_um__)
-       printk("code at %08lx: ", regs->eip);
+       printk("code at %08lx: ", regs->ip);
        {
                int i;
                for (i = 0; i < 16; i++) {
                        unsigned char insn;
 
-                       __get_user(insn, (unsigned char *)(regs->eip + i));
+                       __get_user(insn, (unsigned char *)(regs->ip + i));
                        printk("%02x ", insn);
                }
        }
@@ -838,7 +838,7 @@ static inline int wants_signal(int sig, struct task_struct *p)
                return 0;
        if (sig == SIGKILL)
                return 1;
-       if (p->state & (TASK_STOPPED | TASK_TRACED))
+       if (task_is_stopped_or_traced(p))
                return 0;
        return task_curr(p) || !signal_pending(p);
 }
@@ -911,27 +911,6 @@ __group_complete_signal(int sig, struct task_struct *p)
                        } while_each_thread(p, t);
                        return;
                }
-
-               /*
-                * There will be a core dump.  We make all threads other
-                * than the chosen one go into a group stop so that nothing
-                * happens until it gets scheduled, takes the signal off
-                * the shared queue, and does the core dump.  This is a
-                * little more complicated than strictly necessary, but it
-                * keeps the signal state that winds up in the core dump
-                * unchanged from the death state, e.g. which thread had
-                * the core-dump signal unblocked.
-                */
-               rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
-               rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending);
-               p->signal->group_stop_count = 0;
-               p->signal->group_exit_task = t;
-               p = t;
-               do {
-                       p->signal->group_stop_count++;
-                       signal_wake_up(t, t == p);
-               } while_each_thread(p, t);
-               return;
        }
 
        /*
@@ -978,7 +957,6 @@ void zap_other_threads(struct task_struct *p)
 {
        struct task_struct *t;
 
-       p->signal->flags = SIGNAL_GROUP_EXIT;
        p->signal->group_stop_count = 0;
 
        for (t = next_thread(p); t != p; t = next_thread(t)) {
@@ -994,6 +972,12 @@ void zap_other_threads(struct task_struct *p)
        }
 }
 
+int fastcall __fatal_signal_pending(struct task_struct *tsk)
+{
+       return sigismember(&tsk->pending.signal, SIGKILL);
+}
+EXPORT_SYMBOL(__fatal_signal_pending);
+
 /*
  * Must be called under rcu_read_lock() or with tasklist_lock read-held.
  */
@@ -1441,7 +1425,7 @@ void do_notify_parent(struct task_struct *tsk, int sig)
        BUG_ON(sig == -1);
 
        /* do_notify_parent_cldstop should have been called instead.  */
-       BUG_ON(tsk->state & (TASK_STOPPED|TASK_TRACED));
+       BUG_ON(task_is_stopped_or_traced(tsk));
 
        BUG_ON(!tsk->ptrace &&
               (tsk->group_leader != tsk || !thread_group_empty(tsk)));
@@ -1703,9 +1687,6 @@ static int do_signal_stop(int signr)
        struct signal_struct *sig = current->signal;
        int stop_count;
 
-       if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED))
-               return 0;
-
        if (sig->group_stop_count > 0) {
                /*
                 * There is a group stop in progress.  We don't need to
@@ -1713,12 +1694,15 @@ static int do_signal_stop(int signr)
                 */
                stop_count = --sig->group_stop_count;
        } else {
+               struct task_struct *t;
+
+               if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) ||
+                   unlikely(sig->group_exit_task))
+                       return 0;
                /*
                 * There is no group stop already in progress.
                 * We must initiate one now.
                 */
-               struct task_struct *t;
-
                sig->group_exit_code = signr;
 
                stop_count = 0;
@@ -1729,7 +1713,7 @@ static int do_signal_stop(int signr)
                         * so this check has no races.
                         */
                        if (!t->exit_state &&
-                           !(t->state & (TASK_STOPPED|TASK_TRACED))) {
+                           !task_is_stopped_or_traced(t)) {
                                stop_count++;
                                signal_wake_up(t, 0);
                        }
@@ -1746,47 +1730,6 @@ static int do_signal_stop(int signr)
        return 1;
 }
 
-/*
- * Do appropriate magic when group_stop_count > 0.
- * We return nonzero if we stopped, after releasing the siglock.
- * We return zero if we still hold the siglock and should look
- * for another signal without checking group_stop_count again.
- */
-static int handle_group_stop(void)
-{
-       int stop_count;
-
-       if (current->signal->group_exit_task == current) {
-               /*
-                * Group stop is so we can do a core dump,
-                * We are the initiating thread, so get on with it.
-                */
-               current->signal->group_exit_task = NULL;
-               return 0;
-       }
-
-       if (current->signal->flags & SIGNAL_GROUP_EXIT)
-               /*
-                * Group stop is so another thread can do a core dump,
-                * or else we are racing against a death signal.
-                * Just punt the stop so we can get the next signal.
-                */
-               return 0;
-
-       /*
-        * There is a group stop in progress.  We stop
-        * without any associated signal being in our queue.
-        */
-       stop_count = --current->signal->group_stop_count;
-       if (stop_count == 0)
-               current->signal->flags = SIGNAL_STOP_STOPPED;
-       current->exit_code = current->signal->group_exit_code;
-       set_current_state(TASK_STOPPED);
-       spin_unlock_irq(&current->sighand->siglock);
-       finish_stop(stop_count);
-       return 1;
-}
-
 int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
                          struct pt_regs *regs, void *cookie)
 {
@@ -1801,7 +1744,7 @@ relock:
                struct k_sigaction *ka;
 
                if (unlikely(current->signal->group_stop_count > 0) &&
-                   handle_group_stop())
+                   do_signal_stop(0))
                        goto relock;
 
                signr = dequeue_signal(current, mask, info);