summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormishra <none@none>2005-09-01 21:03:25 -0700
committermishra <none@none>2005-09-01 21:03:25 -0700
commitb33833433bc450712bdb03145caaaa0cfd358f92 (patch)
treedd387f0687e53d6a98d2b88e631933ed7a944d91
parent0541156464ba74bca005fda4b225d3bbe53f7a0c (diff)
downloadillumos-joyent-b33833433bc450712bdb03145caaaa0cfd358f92.tar.gz
6217375 CPU unconfigure, t_disp_queue, and restore_mstate() duke it out
6294464 machine hung with threads spining in thread_lock()on a cpu dispatch lock that never gets released.
-rw-r--r--usr/src/uts/common/disp/disp.c2
-rw-r--r--usr/src/uts/common/disp/fss.c3
-rw-r--r--usr/src/uts/common/disp/fx.c3
-rw-r--r--usr/src/uts/common/disp/rt.c2
-rw-r--r--usr/src/uts/common/disp/shuttle.c39
-rw-r--r--usr/src/uts/common/disp/ts.c5
-rw-r--r--usr/src/uts/common/os/msacct.c6
7 files changed, 34 insertions, 26 deletions
diff --git a/usr/src/uts/common/disp/disp.c b/usr/src/uts/common/disp/disp.c
index 6bb9debbe2..aee7512c08 100644
--- a/usr/src/uts/common/disp/disp.c
+++ b/usr/src/uts/common/disp/disp.c
@@ -132,7 +132,6 @@ id_t defaultcid; /* system "default" class; see dispadmin(1M) */
disp_lock_t transition_lock; /* lock on transitioning threads */
disp_lock_t stop_lock; /* lock on stopped threads */
-disp_lock_t shuttle_lock; /* lock on shuttle objects */
static void cpu_dispqalloc(int numpris);
@@ -202,7 +201,6 @@ dispinit(void)
DISP_LOCK_INIT(&transition_lock);
disp_lock_enter_high(&transition_lock);
DISP_LOCK_INIT(&stop_lock);
- DISP_LOCK_INIT(&shuttle_lock);
mutex_enter(&cpu_lock);
CPU->cpu_disp->disp_maxrunpri = -1;
diff --git a/usr/src/uts/common/disp/fss.c b/usr/src/uts/common/disp/fss.c
index 2fc5fe6e2f..f2b77f7ea7 100644
--- a/usr/src/uts/common/disp/fss.c
+++ b/usr/src/uts/common/disp/fss.c
@@ -2167,7 +2167,8 @@ fss_tick(kthread_t *t)
fssproc->fss_flags |= FSSBACKQ;
cpu_surrender(t);
}
- } else if (t->t_pri < t->t_disp_queue->disp_maxrunpri) {
+ } else if (t->t_state == TS_ONPROC &&
+ t->t_pri < t->t_disp_queue->disp_maxrunpri) {
/*
* If there is a higher-priority thread which is
* waiting for a processor, then thread surrenders
diff --git a/usr/src/uts/common/disp/fx.c b/usr/src/uts/common/disp/fx.c
index 2e7f27c399..62b5eb1da2 100644
--- a/usr/src/uts/common/disp/fx.c
+++ b/usr/src/uts/common/disp/fx.c
@@ -1382,7 +1382,8 @@ fx_tick(kthread_t *t)
fxpp->fx_flags |= FXBACKQ;
cpu_surrender(t);
}
- } else if (t->t_pri < t->t_disp_queue->disp_maxrunpri) {
+ } else if (t->t_state == TS_ONPROC &&
+ t->t_pri < t->t_disp_queue->disp_maxrunpri) {
fxpp->fx_flags |= FXBACKQ;
cpu_surrender(t);
}
diff --git a/usr/src/uts/common/disp/rt.c b/usr/src/uts/common/disp/rt.c
index 128cdeef1b..2b60fbe24e 100644
--- a/usr/src/uts/common/disp/rt.c
+++ b/usr/src/uts/common/disp/rt.c
@@ -994,7 +994,7 @@ rt_tick(kthread_t *t)
thread_lock(t);
if ((rtpp->rt_pquantum != RT_TQINF && --rtpp->rt_timeleft == 0) ||
- (DISP_MUST_SURRENDER(t))) {
+ (t->t_state == TS_ONPROC && DISP_MUST_SURRENDER(t))) {
if (rtpp->rt_timeleft == 0 && rtpp->rt_tqsignal) {
thread_unlock(t);
sigtoproc(ttoproc(t), t, rtpp->rt_tqsignal);
diff --git a/usr/src/uts/common/disp/shuttle.c b/usr/src/uts/common/disp/shuttle.c
index 1c0dd9e65e..47b6e17e66 100644
--- a/usr/src/uts/common/disp/shuttle.c
+++ b/usr/src/uts/common/disp/shuttle.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,6 +39,7 @@
#include <sys/cpuvar.h>
#include <sys/sdt.h>
+static disp_lock_t shuttle_lock; /* lock on shuttle objects */
/*
* Place the thread in question on the run q.
@@ -86,7 +87,7 @@ shuttle_resume(kthread_t *t, kmutex_t *l)
{
klwp_t *lwp = ttolwp(curthread);
cpu_t *cp;
- extern disp_lock_t shuttle_lock;
+ disp_lock_t *oldtlp;
thread_lock(curthread);
disp_lock_enter_high(&shuttle_lock);
@@ -115,16 +116,31 @@ shuttle_resume(kthread_t *t, kmutex_t *l)
DTRACE_SCHED1(wakeup, kthread_t *, t);
DTRACE_SCHED(sleep);
THREAD_SLEEP(curthread, &shuttle_lock);
+ disp_lock_exit_high(&shuttle_lock);
- /* Update ustate records (there is no waitrq obviously) */
-
+ /*
+ * Update ustate records (there is no waitrq obviously)
+ */
(void) new_mstate(curthread, LMS_SLEEP);
+
+ thread_lock_high(t);
+ oldtlp = t->t_lockp;
+
restore_mstate(t);
t->t_flag &= ~T_WAKEABLE;
t->t_wchan0 = NULL;
t->t_sobj_ops = NULL;
/*
+ * Make sure we end up on the right CPU if we are dealing with bound
+ * CPU's or processor partitions.
+ */
+ if (t->t_bound_cpu != NULL || t->t_cpupart != cp->cpu_part) {
+ aston(t);
+ cp->cpu_runrun = 1;
+ }
+
+ /*
* We re-assign t_disp_queue and t_lockp of 't' here because
* 't' could have been preempted.
*/
@@ -134,15 +150,12 @@ shuttle_resume(kthread_t *t, kmutex_t *l)
}
/*
- * Make sure we end up on the right CPU if we are dealing with bound
- * CPU's or processor partitions.
+ * We can't call thread_unlock_high() here because t's thread lock
+ * could have changed by thread_onproc() call above to point to
+ * CPU->cpu_thread_lock.
*/
- if (t->t_bound_cpu != NULL || t->t_cpupart != cp->cpu_part) {
- aston(t);
- cp->cpu_runrun = 1;
- }
+ disp_lock_exit_high(oldtlp);
- disp_lock_exit_high(&shuttle_lock);
mutex_exit(l);
/*
* Make sure we didn't receive any important events while
@@ -151,6 +164,7 @@ shuttle_resume(kthread_t *t, kmutex_t *l)
if (lwp &&
(ISSIG(curthread, JUSTLOOKING) || MUSTRETURN(curproc, curthread)))
setrun(curthread);
+
swtch_to(t);
/*
* Caller must check for ISSIG/lwp_sysabort conditions
@@ -167,7 +181,6 @@ void
shuttle_swtch(kmutex_t *l)
{
klwp_t *lwp = ttolwp(curthread);
- extern disp_lock_t shuttle_lock;
thread_lock(curthread);
disp_lock_enter_high(&shuttle_lock);
@@ -205,8 +218,6 @@ shuttle_sleep(kthread_t *t)
klwp_t *lwp = ttolwp(t);
proc_t *p = ttoproc(t);
- extern disp_lock_t shuttle_lock;
-
thread_lock(t);
disp_lock_enter_high(&shuttle_lock);
if (lwp != NULL) {
diff --git a/usr/src/uts/common/disp/ts.c b/usr/src/uts/common/disp/ts.c
index d0f09f5817..9a10dac7ad 100644
--- a/usr/src/uts/common/disp/ts.c
+++ b/usr/src/uts/common/disp/ts.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1701,7 +1701,8 @@ ts_tick(kthread_t *t)
}
TRACE_2(TR_FAC_DISP, TR_TICK,
"tick:tid %p old pri %d", t, oldpri);
- } else if (t->t_pri < t->t_disp_queue->disp_maxrunpri) {
+ } else if (t->t_state == TS_ONPROC &&
+ t->t_pri < t->t_disp_queue->disp_maxrunpri) {
tspp->ts_flags |= TSBACKQ;
cpu_surrender(t);
}
diff --git a/usr/src/uts/common/os/msacct.c b/usr/src/uts/common/os/msacct.c
index 1ca2347c15..475913ac76 100644
--- a/usr/src/uts/common/os/msacct.c
+++ b/usr/src/uts/common/os/msacct.c
@@ -534,7 +534,6 @@ restore_mstate(kthread_t *t)
hrtime_t waitrq;
hrtime_t newtime;
hrtime_t oldtime;
- struct cpu *cpup;
if ((lwp = ttolwp(t)) == NULL)
return;
@@ -601,11 +600,8 @@ restore_mstate(kthread_t *t)
/*
* Update the WAIT_CPU timer and per-cpu waitrq total.
*/
- cpup = t->t_disp_queue->disp_cpu;
- if (cpup == NULL)
- cpup = t->t_cpu;
ms->ms_acct[LMS_WAIT_CPU] += (curtime - waitrq);
- cpup->cpu_waitrq += (curtime - waitrq);
+ CPU->cpu_waitrq += (curtime - waitrq);
ms->ms_state_start = curtime;
}