summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorjohansen <none@none>2007-01-16 14:09:46 -0800
committerjohansen <none@none>2007-01-16 14:09:46 -0800
commitf2bd46275366373a10ce31b170ae2bbc7b03cc0f (patch)
tree27f0aa8197331383b4035a7ebf4f4ff385c67211 /usr/src
parent516bda921188ac42ecd8efd54cda7645912f2e09 (diff)
downloadillumos-gate-f2bd46275366373a10ce31b170ae2bbc7b03cc0f.tar.gz
6498304 too much CPU time winding up in LMS_WAIT_CPU
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/disp/disp.c96
-rw-r--r--usr/src/uts/common/disp/shuttle.c8
-rw-r--r--usr/src/uts/common/os/msacct.c14
3 files changed, 77 insertions, 41 deletions
diff --git a/usr/src/uts/common/disp/disp.c b/usr/src/uts/common/disp/disp.c
index 489f0d46de..dc53b411e3 100644
--- a/usr/src/uts/common/disp/disp.c
+++ b/usr/src/uts/common/disp/disp.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -626,7 +626,6 @@ idle()
if (t == T_DONTSTEAL)
continue;
idle_exit();
- restore_mstate(t);
swtch_to(t);
}
idle_enter(); /* returned from swtch/swtch_to */
@@ -715,7 +714,6 @@ reschedule:
if (disp_ratify(tp, kpq) != NULL) {
TRACE_1(TR_FAC_DISP, TR_DISP_END,
"disp_end:tid %p", tp);
- restore_mstate(tp);
return (tp);
}
}
@@ -754,7 +752,6 @@ reschedule:
}
TRACE_1(TR_FAC_DISP, TR_DISP_END,
"disp_end:tid %p", tp);
- restore_mstate(tp);
return (tp);
}
@@ -820,7 +817,6 @@ reschedule:
if (disp_ratify(tp, kpq) == NULL)
goto reschedule;
- restore_mstate(tp);
return (tp);
}
@@ -883,6 +879,22 @@ swtch()
CHIP_NRUNNING(cp->cpu_chip, -1);
}
+ /*
+ * If t was previously in the TS_ONPROC state,
+ * setfrontdq and setbackdq won't have set its t_waitrq.
+ * Since we now finally know that we're switching away
+ * from this thread, set its t_waitrq if it is on a run
+ * queue.
+ */
+ if ((t->t_state == TS_RUN) && (t->t_waitrq == 0)) {
+ t->t_waitrq = gethrtime_unscaled();
+ }
+
+ /*
+ * restore mstate of thread that we are switching to
+ */
+ restore_mstate(next);
+
CPU_STATS_ADDQ(cp, sys, pswitch, 1);
cp->cpu_last_swtch = t->t_disp_time = lbolt;
TRACE_0(TR_FAC_DISP, TR_RESUME_START, "resume_start");
@@ -934,6 +946,8 @@ swtch_from_zombie()
if (next == cpu->cpu_idle_thread)
CHIP_NRUNNING(cpu->cpu_chip, -1);
+ restore_mstate(next);
+
if (dtrace_vtime_active)
dtrace_vtime_switch(next);
@@ -1018,6 +1032,19 @@ swtch_to(kthread_t *next)
/* record last execution time */
cp->cpu_last_swtch = curthread->t_disp_time = lbolt;
+ /*
+ * If t was previously in the TS_ONPROC state, setfrontdq and setbackdq
+ * won't have set its t_waitrq. Since we now finally know that we're
+ * switching away from this thread, set its t_waitrq if it is on a run
+ * queue.
+ */
+ if ((curthread->t_state == TS_RUN) && (curthread->t_waitrq == 0)) {
+ curthread->t_waitrq = gethrtime_unscaled();
+ }
+
+ /* restore next thread to previously running microstate */
+ restore_mstate(next);
+
if (dtrace_vtime_active)
dtrace_vtime_switch(next);
@@ -1161,17 +1188,6 @@ setbackdq(kthread_t *tp)
ASSERT(THREAD_LOCK_HELD(tp));
ASSERT((tp->t_schedflag & TS_ALLSTART) == 0);
-
- if (tp->t_waitrq == 0) {
- hrtime_t curtime;
-
- curtime = gethrtime_unscaled();
- (void) cpu_update_pct(tp, curtime);
- tp->t_waitrq = curtime;
- } else {
- (void) cpu_update_pct(tp, gethrtime_unscaled());
- }
-
ASSERT(!thread_on_queue(tp)); /* make sure tp isn't on a runq */
/*
@@ -1254,6 +1270,24 @@ setbackdq(kthread_t *tp)
tp->t_weakbound_cpu : tp->t_bound_cpu;
bound = 1;
}
+ /*
+ * A thread that is ONPROC may be temporarily placed on the run queue
+ * but then chosen to run again by disp. If the thread we're placing on
+ * the queue is in TS_ONPROC state, don't set its t_waitrq until a
+ * replacement process is actually scheduled in swtch(). In this
+ * situation, curthread is the only thread that could be in the ONPROC
+ * state.
+ */
+ if ((tp != curthread) && (tp->t_waitrq == 0)) {
+ hrtime_t curtime;
+
+ curtime = gethrtime_unscaled();
+ (void) cpu_update_pct(tp, curtime);
+ tp->t_waitrq = curtime;
+ } else {
+ (void) cpu_update_pct(tp, gethrtime_unscaled());
+ }
+
dp = cp->cpu_disp;
disp_lock_enter_high(&dp->disp_lock);
@@ -1332,17 +1366,6 @@ setfrontdq(kthread_t *tp)
ASSERT(THREAD_LOCK_HELD(tp));
ASSERT((tp->t_schedflag & TS_ALLSTART) == 0);
-
- if (tp->t_waitrq == 0) {
- hrtime_t curtime;
-
- curtime = gethrtime_unscaled();
- (void) cpu_update_pct(tp, curtime);
- tp->t_waitrq = curtime;
- } else {
- (void) cpu_update_pct(tp, gethrtime_unscaled());
- }
-
ASSERT(!thread_on_queue(tp)); /* make sure tp isn't on a runq */
/*
@@ -1396,6 +1419,25 @@ setfrontdq(kthread_t *tp)
tp->t_weakbound_cpu : tp->t_bound_cpu;
bound = 1;
}
+
+ /*
+ * A thread that is ONPROC may be temporarily placed on the run queue
+ * but then chosen to run again by disp. If the thread we're placing on
+ * the queue is in TS_ONPROC state, don't set its t_waitrq until a
+ * replacement process is actually scheduled in swtch(). In this
+ * situation, curthread is the only thread that could be in the ONPROC
+ * state.
+ */
+ if ((tp != curthread) && (tp->t_waitrq == 0)) {
+ hrtime_t curtime;
+
+ curtime = gethrtime_unscaled();
+ (void) cpu_update_pct(tp, curtime);
+ tp->t_waitrq = curtime;
+ } else {
+ (void) cpu_update_pct(tp, gethrtime_unscaled());
+ }
+
dp = cp->cpu_disp;
disp_lock_enter_high(&dp->disp_lock);
diff --git a/usr/src/uts/common/disp/shuttle.c b/usr/src/uts/common/disp/shuttle.c
index ab4ba99717..a84014772f 100644
--- a/usr/src/uts/common/disp/shuttle.c
+++ b/usr/src/uts/common/disp/shuttle.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -126,7 +125,6 @@ shuttle_resume(kthread_t *t, kmutex_t *l)
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;
diff --git a/usr/src/uts/common/os/msacct.c b/usr/src/uts/common/os/msacct.c
index 301d13a5b7..134de5a513 100644
--- a/usr/src/uts/common/os/msacct.c
+++ b/usr/src/uts/common/os/msacct.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -560,8 +559,6 @@ new_mstate(kthread_t *t, int new_state)
return (ms->ms_prev);
}
-static long waitrqis0 = 0;
-
/*
* Restore the LWP microstate to the previous runnable state.
* Called from disp() with the newly selected lwp.
@@ -625,11 +622,10 @@ restore_mstate(kthread_t *t)
break;
}
waitrq = t->t_waitrq; /* hopefully atomic */
- t->t_waitrq = 0;
- if (waitrq == 0) { /* should only happen during boot */
+ if (waitrq == 0) {
waitrq = curtime;
- waitrqis0++;
}
+ t->t_waitrq = 0;
newtime = waitrq - ms->ms_state_start;
if (newtime < 0) {
curtime = gethrtime_unscaled();