Re: [RFC,PATCH] Use RCU to protect tasklist for unicast signals
From: Ingo Molnar
Date: Wed Aug 17 2005 - 01:36:08 EST
* Paul E. McKenney <paulmck@xxxxxxxxxx> 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/