Mercurial > illumos > illumos-gate
changeset 3426:e69c0764a03e
6498304 too much CPU time winding up in LMS_WAIT_CPU
author | johansen |
---|---|
date | Tue, 16 Jan 2007 14:09:46 -0800 |
parents | 69e10a2dd6f0 |
children | fa42dcd66837 |
files | usr/src/uts/common/disp/disp.c usr/src/uts/common/disp/shuttle.c usr/src/uts/common/os/msacct.c |
diffstat | 3 files changed, 77 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/disp/disp.c Tue Jan 16 07:17:31 2007 -0800 +++ b/usr/src/uts/common/disp/disp.c Tue Jan 16 14:09:46 2007 -0800 @@ -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 @@ if (t == T_DONTSTEAL) continue; idle_exit(); - restore_mstate(t); swtch_to(t); } idle_enter(); /* returned from swtch/swtch_to */ @@ -715,7 +714,6 @@ 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 @@ } TRACE_1(TR_FAC_DISP, TR_DISP_END, "disp_end:tid %p", tp); - restore_mstate(tp); return (tp); } @@ -820,7 +817,6 @@ if (disp_ratify(tp, kpq) == NULL) goto reschedule; - restore_mstate(tp); return (tp); } @@ -883,6 +879,22 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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);
--- a/usr/src/uts/common/disp/shuttle.c Tue Jan 16 07:17:31 2007 -0800 +++ b/usr/src/uts/common/disp/shuttle.c Tue Jan 16 14:09:46 2007 -0800 @@ -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 @@ 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;
--- a/usr/src/uts/common/os/msacct.c Tue Jan 16 07:17:31 2007 -0800 +++ b/usr/src/uts/common/os/msacct.c Tue Jan 16 14:09:46 2007 -0800 @@ -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 @@ 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 @@ 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();