* Paul E. McKenney <[EMAIL PROTECTED]> wrote:

> My tests are not finding even glaring races, so time to go and create 
> some torture tests before getting too much more elaborate.  10,000 
> eyes are nice (and Oleg's eyes do seem to be working especially well), 
> but a good software-test sledgehammer has its uses as well.

i've merged this to the -rt tree, and find below a delta patch relative 
to the previous patch.

        Ingo

Index: linux/kernel/exit.c
===================================================================
--- linux.orig/kernel/exit.c
+++ linux/kernel/exit.c
@@ -74,7 +74,6 @@ repeat: 
                __ptrace_unlink(p);
        BUG_ON(!list_empty(&p->ptrace_list) || 
!list_empty(&p->ptrace_children));
        __exit_signal(p);
-       __exit_sighand(p);
        /*
         * Note that the fastpath in sys_times depends on __exit_signal having
         * updated the counters before a task is removed from the tasklist of
Index: linux/kernel/signal.c
===================================================================
--- linux.orig/kernel/signal.c
+++ linux/kernel/signal.c
@@ -328,17 +328,19 @@ void __exit_sighand(struct task_struct *
        struct sighand_struct * sighand = tsk->sighand;
 
        /* Ok, we're done with the signal handlers */
-       spin_lock(&sighand->siglock);
        tsk->sighand = NULL;
        if (atomic_dec_and_test(&sighand->count))
                sighand_free(sighand);
-       spin_unlock(&sighand->siglock);
 }
 
 void exit_sighand(struct task_struct *tsk)
 {
        write_lock_irq(&tasklist_lock);
-       __exit_sighand(tsk);
+       spin_lock(&tsk->sighand->siglock);
+       if (tsk->sighand != NULL) {
+               __exit_sighand(tsk);
+       }
+       spin_unlock(&tsk->sighand->siglock);
        write_unlock_irq(&tasklist_lock);
 }
 
@@ -361,6 +363,7 @@ void __exit_signal(struct task_struct *t
                if (tsk == sig->curr_target)
                        sig->curr_target = next_thread(tsk);
                tsk->signal = NULL;
+               __exit_sighand(tsk);
                spin_unlock(&sighand->siglock);
                flush_sigqueue(&sig->shared_pending);
        } else {
@@ -392,6 +395,7 @@ void __exit_signal(struct task_struct *t
                sig->nvcsw += tsk->nvcsw;
                sig->nivcsw += tsk->nivcsw;
                sig->sched_time += tsk->sched_time;
+               __exit_sighand(tsk);
                spin_unlock(&sighand->siglock);
                sig = NULL;     /* Marker for below.  */
        }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to