summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_thread.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2002-08-29 19:49:53 +0000
committerjulian <julian@FreeBSD.org>2002-08-29 19:49:53 +0000
commita9901abd65684d503ef81966ede6f2b7bb982af3 (patch)
treeda5eca802efcec024b6c7bd781571db5a107cb8b /sys/kern/kern_thread.c
parent1986a94b82132d3e7898ec24ee7e632c5e884ad7 (diff)
downloadFreeBSD-src-a9901abd65684d503ef81966ede6f2b7bb982af3.zip
FreeBSD-src-a9901abd65684d503ef81966ede6f2b7bb982af3.tar.gz
Fix crack-smoking code that was panicing on the quad xeon:
- If either of proc or kse are NULL during thread_exit(), then the kernel is going to fault because parts of the function assume they aren't NULL. Instead, just assert they aren't NULL (as well as the kse group) and assume they are in all of the code. It doesn't make sense for them to be NULL here anyways. - Move the PROC_UNLOCK(p) up above clearing td_proc, etc. since otherwise we will panic if the proc's lock is contested. Submitted by: jhb@freebsd.org
Diffstat (limited to 'sys/kern/kern_thread.c')
-rw-r--r--sys/kern/kern_thread.c49
1 files changed, 23 insertions, 26 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 0214237..fd4f0b3 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -320,6 +320,9 @@ thread_exit(void)
ke = td->td_kse;
mtx_assert(&sched_lock, MA_OWNED);
+ KASSERT(p != NULL, ("thread exiting without a process"));
+ KASSERT(ke != NULL, ("thread exiting without a kse"));
+ KASSERT(kg != NULL, ("thread exiting without a kse group"));
PROC_LOCK_ASSERT(p, MA_OWNED);
CTR1(KTR_PROC, "thread_exit: thread %p", td);
KASSERT(!mtx_owned(&Giant), ("dying thread owns giant"));
@@ -331,41 +334,35 @@ thread_exit(void)
cpu_thread_exit(td); /* XXXSMP */
/* Reassign this thread's KSE. */
- if (ke != NULL) {
- ke->ke_thread = NULL;
- td->td_kse = NULL;
- ke->ke_state = KES_UNQUEUED;
- kse_reassign(ke);
- }
+ ke->ke_thread = NULL;
+ td->td_kse = NULL;
+ ke->ke_state = KES_UNQUEUED;
+ kse_reassign(ke);
/* Unlink this thread from its proc. and the kseg */
- if (p != NULL) {
- TAILQ_REMOVE(&p->p_threads, td, td_plist);
- p->p_numthreads--;
- if (kg != NULL) {
- TAILQ_REMOVE(&kg->kg_threads, td, td_kglist);
- kg->kg_numthreads--;
- }
- /*
- * The test below is NOT true if we are the
- * sole exiting thread. P_STOPPED_SNGL is unset
- * in exit1() after it is the only survivor.
- */
- if (P_SHOULDSTOP(p) == P_STOPPED_SNGL) {
- if (p->p_numthreads == p->p_suspcount) {
- TAILQ_REMOVE(&p->p_suspended,
- p->p_singlethread, td_runq);
- setrunqueue(p->p_singlethread);
- p->p_suspcount--;
- }
+ TAILQ_REMOVE(&p->p_threads, td, td_plist);
+ p->p_numthreads--;
+ TAILQ_REMOVE(&kg->kg_threads, td, td_kglist);
+ kg->kg_numthreads--;
+ /*
+ * The test below is NOT true if we are the
+ * sole exiting thread. P_STOPPED_SNGL is unset
+ * in exit1() after it is the only survivor.
+ */
+ if (P_SHOULDSTOP(p) == P_STOPPED_SNGL) {
+ if (p->p_numthreads == p->p_suspcount) {
+ TAILQ_REMOVE(&p->p_suspended,
+ p->p_singlethread, td_runq);
+ setrunqueue(p->p_singlethread);
+ p->p_suspcount--;
}
}
+ PROC_UNLOCK(p);
td->td_state = TDS_SURPLUS;
td->td_proc = NULL;
td->td_ksegrp = NULL;
td->td_last_kse = NULL;
ke->ke_tdspare = td;
- PROC_UNLOCK(p);
cpu_throw();
/* NOTREACHED */
}
OpenPOWER on IntegriCloud