summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-06-27 06:15:44 +0000
committerjhb <jhb@FreeBSD.org>2001-06-27 06:15:44 +0000
commitf4029cf62b7527d3d28d121fa81da9c63fbce9af (patch)
tree328ceb66f0239d2e5bd750e910fea544fefd0235 /sys/kern/kern_exit.c
parentb2bba7ca2ac8a4de0678d1fe23ee5189bc40c8e4 (diff)
downloadFreeBSD-src-f4029cf62b7527d3d28d121fa81da9c63fbce9af.zip
FreeBSD-src-f4029cf62b7527d3d28d121fa81da9c63fbce9af.tar.gz
- Always use the proc lock of the task leader to protect the peers list of
processes. - Don't construct fake call args and then call kill(). psignal is not anymore complicated and is quicker and not prone to locking problems. Calling psignal() avoids having to do a pfind() since we already have a proc pointer and also allows us to keep the task leader locked while we kill all the peer processes so the list is kept coherent. - When a kthread exits, do a wakeup() on its proc pointers. This can be used by kernel modules that have kthreads and want to ensure they have safely exited before completely the MOD_UNLOAD event. Connectivity provided by: Usenix wireless
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 6454d11..b1a2ee5 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -131,20 +131,11 @@ exit1(p, rv)
/* are we a task leader? */
PROC_LOCK(p);
if(p == p->p_leader) {
- struct kill_args killArgs;
-
- killArgs.signum = SIGKILL;
q = p->p_peers;
- while(q) {
- killArgs.pid = q->p_pid;
- /*
- * The interface for kill is better
- * than the internal signal
- */
- PROC_UNLOCK(p);
- kill(p, &killArgs);
- PROC_LOCK(p);
- nq = q;
+ while (q != NULL) {
+ PROC_LOCK(q);
+ psignal(q, SIGKILL);
+ PROC_UNLOCK(q);
q = q->p_peers;
}
while (p->p_peers)
@@ -197,7 +188,7 @@ exit1(p, rv)
/*
* Remove ourself from our leader's peer list and wake our leader.
*/
- PROC_LOCK(p);
+ PROC_LOCK(p->p_leader);
if(p->p_leader->p_peers) {
q = p->p_leader;
while(q->p_peers != p)
@@ -205,7 +196,7 @@ exit1(p, rv)
q->p_peers = p->p_peers;
wakeup((caddr_t)p->p_leader);
}
- PROC_UNLOCK(p);
+ PROC_UNLOCK(p->p_leader);
/*
* XXX Shutdown SYSV semaphores
@@ -359,6 +350,12 @@ exit1(p, rv)
else
psignal(p->p_pptr, SIGCHLD);
PROC_UNLOCK(p->p_pptr);
+
+ /*
+ * If this is a kthread, then wakeup anyone waiting for it to exit.
+ */
+ if (p->p_flag & P_KTHREAD)
+ wakeup((caddr_t)p);
PROC_UNLOCK(p);
sx_xunlock(&proctree_lock);
OpenPOWER on IntegriCloud