diff options
author | mishra <none@none> | 2005-09-01 21:03:25 -0700 |
---|---|---|
committer | mishra <none@none> | 2005-09-01 21:03:25 -0700 |
commit | b33833433bc450712bdb03145caaaa0cfd358f92 (patch) | |
tree | dd387f0687e53d6a98d2b88e631933ed7a944d91 | |
parent | 0541156464ba74bca005fda4b225d3bbe53f7a0c (diff) | |
download | illumos-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.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/disp/fss.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/disp/fx.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/disp/rt.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/disp/shuttle.c | 39 | ||||
-rw-r--r-- | usr/src/uts/common/disp/ts.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/os/msacct.c | 6 |
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; } |