diff options
Diffstat (limited to 'usr/src/uts/common/os/msacct.c')
-rw-r--r-- | usr/src/uts/common/os/msacct.c | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/usr/src/uts/common/os/msacct.c b/usr/src/uts/common/os/msacct.c index df975eb7ee..30e50cce72 100644 --- a/usr/src/uts/common/os/msacct.c +++ b/usr/src/uts/common/os/msacct.c @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -33,6 +34,7 @@ #include <sys/debug.h> #include <sys/msacct.h> #include <sys/time.h> +#include <sys/zone.h> /* * Mega-theory block comment: @@ -390,6 +392,7 @@ void syscall_mstate(int fromms, int toms) { kthread_t *t = curthread; + zone_t *z = ttozone(t); struct mstate *ms; hrtime_t *mstimep; hrtime_t curtime; @@ -413,6 +416,10 @@ syscall_mstate(int fromms, int toms) newtime = curtime - ms->ms_state_start; } *mstimep += newtime; + if (fromms == LMS_USER) + atomic_add_64(&z->zone_utime, newtime); + else if (fromms == LMS_SYSTEM) + atomic_add_64(&z->zone_stime, newtime); t->t_mstate = toms; ms->ms_state_start = curtime; ms->ms_prev = fromms; @@ -560,27 +567,18 @@ cpu_update_pct(kthread_t *t, hrtime_t newtime) */ do { - if (T_ONPROC(t) && t->t_waitrq == 0) { - hrlb = t->t_hrtime; + pctcpu = t->t_pctcpu; + hrlb = t->t_hrtime; + delta = newtime - hrlb; + if (delta < 0) { + newtime = gethrtime_unscaled(); delta = newtime - hrlb; - if (delta < 0) { - newtime = gethrtime_unscaled(); - delta = newtime - hrlb; - } - t->t_hrtime = newtime; - scalehrtime(&delta); - pctcpu = t->t_pctcpu; + } + t->t_hrtime = newtime; + scalehrtime(&delta); + if (T_ONPROC(t) && t->t_waitrq == 0) { npctcpu = cpu_grow(pctcpu, delta); } else { - hrlb = t->t_hrtime; - delta = newtime - hrlb; - if (delta < 0) { - newtime = gethrtime_unscaled(); - delta = newtime - hrlb; - } - t->t_hrtime = newtime; - scalehrtime(&delta); - pctcpu = t->t_pctcpu; npctcpu = cpu_decay(pctcpu, delta); } } while (cas32(&t->t_pctcpu, pctcpu, npctcpu) != pctcpu); @@ -602,7 +600,10 @@ new_mstate(kthread_t *t, int new_state) hrtime_t curtime; hrtime_t newtime; hrtime_t oldtime; + hrtime_t ztime; + hrtime_t origstart; klwp_t *lwp; + zone_t *z; ASSERT(new_state != LMS_WAIT_CPU); ASSERT((unsigned)new_state < NMSTATES); @@ -625,6 +626,7 @@ new_mstate(kthread_t *t, int new_state) ms = &lwp->lwp_mstate; state = t->t_mstate; + origstart = ms->ms_state_start; do { switch (state) { case LMS_TFAULT: @@ -637,7 +639,7 @@ new_mstate(kthread_t *t, int new_state) mstimep = &ms->ms_acct[state]; break; } - newtime = curtime - ms->ms_state_start; + ztime = newtime = curtime - ms->ms_state_start; if (newtime < 0) { curtime = gethrtime_unscaled(); oldtime = *mstimep - 1; /* force CAS to fail */ @@ -648,6 +650,20 @@ new_mstate(kthread_t *t, int new_state) t->t_mstate = new_state; ms->ms_state_start = curtime; } while (cas64((uint64_t *)mstimep, oldtime, newtime) != oldtime); + + /* + * When the system boots the initial startup thread will have a + * ms_state_start of 0 which would add a huge system time to the global + * zone. We want to skip aggregating that initial bit of work. + */ + if (origstart != 0) { + z = ttozone(t); + if (state == LMS_USER) + atomic_add_64(&z->zone_utime, ztime); + else if (state == LMS_SYSTEM) + atomic_add_64(&z->zone_stime, ztime); + } + /* * Remember the previous running microstate. */ @@ -686,6 +702,8 @@ restore_mstate(kthread_t *t) hrtime_t waitrq; hrtime_t newtime; hrtime_t oldtime; + hrtime_t waittime; + zone_t *z; /* * Don't call restore mstate of threads without lwps. (Kernel threads) @@ -756,11 +774,15 @@ restore_mstate(kthread_t *t) oldtime = *mstimep; newtime += oldtime; } while (cas64((uint64_t *)mstimep, oldtime, newtime) != oldtime); + /* * Update the WAIT_CPU timer and per-cpu waitrq total. */ - ms->ms_acct[LMS_WAIT_CPU] += (curtime - waitrq); - CPU->cpu_waitrq += (curtime - waitrq); + z = ttozone(t); + waittime = curtime - waitrq; + ms->ms_acct[LMS_WAIT_CPU] += waittime; + atomic_add_64(&z->zone_wtime, waittime); + CPU->cpu_waitrq += waittime; ms->ms_state_start = curtime; } |