aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/mp_machdep.c2
-rw-r--r--sys/amd64/amd64/mp_machdep.c2
-rw-r--r--sys/i386/i386/mp_machdep.c2
-rw-r--r--sys/ia64/ia64/mp_machdep.c2
-rw-r--r--sys/kern/init_main.c5
-rw-r--r--sys/kern/kern_exit.c7
-rw-r--r--sys/kern/kern_proc.c4
-rw-r--r--sys/kern/kern_resource.c21
-rw-r--r--sys/kern/kern_synch.c9
-rw-r--r--sys/kern/kern_tc.c21
-rw-r--r--sys/kern/subr_trap.c2
-rw-r--r--sys/sparc64/sparc64/mp_machdep.c2
-rw-r--r--sys/sparc64/sparc64/tick.c17
-rw-r--r--sys/sys/pcpu.h2
-rw-r--r--sys/sys/proc.h2
-rw-r--r--sys/sys/systm.h3
16 files changed, 71 insertions, 32 deletions
diff --git a/sys/alpha/alpha/mp_machdep.c b/sys/alpha/alpha/mp_machdep.c
index e548d4f5d39b..9d6cdc5c6b86 100644
--- a/sys/alpha/alpha/mp_machdep.c
+++ b/sys/alpha/alpha/mp_machdep.c
@@ -225,7 +225,7 @@ smp_init_secondary(void)
spinlock_exit();
KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count"));
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
cpu_throw(NULL, choosethread()); /* doesn't return */
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index c05b05f789bf..a152bc120a23 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -582,7 +582,7 @@ init_secondary(void)
spinlock_exit();
KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count"));
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
cpu_throw(NULL, choosethread()); /* doesn't return */
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index 95928a1d6bfb..bd8dfdfd0662 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -631,7 +631,7 @@ init_secondary(void)
spinlock_exit();
KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count"));
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
cpu_throw(NULL, choosethread()); /* doesn't return */
diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c
index dedc395ec5aa..0b9e7ddadcd1 100644
--- a/sys/ia64/ia64/mp_machdep.c
+++ b/sys/ia64/ia64/mp_machdep.c
@@ -138,7 +138,7 @@ ia64_ap_startup(void)
spinlock_exit();
KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count"));
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
ia64_set_tpr(0);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index b63c4e8b3b11..e2ec53fb68c3 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -459,11 +459,10 @@ proc0_post(void *dummy __unused)
sx_slock(&allproc_lock);
LIST_FOREACH(p, &allproc, p_list) {
microuptime(&p->p_stats->p_start);
- p->p_rux.rux_runtime.sec = 0;
- p->p_rux.rux_runtime.frac = 0;
+ p->p_rux.rux_runtime = 0;
}
sx_sunlock(&allproc_lock);
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
/*
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index b907981ee97a..8803ac90a759 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -110,7 +110,7 @@ sys_exit(struct thread *td, struct sys_exit_args *uap)
void
exit1(struct thread *td, int rv)
{
- struct bintime new_switchtime;
+ uint64_t new_switchtime;
struct proc *p, *nq, *q;
struct tty *tp;
struct vnode *ttyvp;
@@ -543,9 +543,8 @@ retry:
ruadd(p->p_ru, &p->p_rux, &p->p_stats->p_cru, &p->p_crux);
/* Do the same timestamp bookkeeping that mi_switch() would do. */
- binuptime(&new_switchtime);
- bintime_add(&p->p_rux.rux_runtime, &new_switchtime);
- bintime_sub(&p->p_rux.rux_runtime, PCPU_PTR(switchtime));
+ new_switchtime = cpu_ticks();
+ p->p_rux.rux_runtime += (new_switchtime - PCPU_GET(switchtime));
PCPU_SET(switchtime, new_switchtime);
PCPU_SET(switchticks, ticks);
cnt.v_swtch++;
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 59d257b4f89f..e02b947b3596 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -624,7 +624,6 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp)
struct thread *td0;
struct tty *tp;
struct session *sp;
- struct timeval tv;
struct ucred *cred;
struct sigacts *ps;
@@ -695,8 +694,7 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp)
kp->ki_swtime = p->p_swtime;
kp->ki_pid = p->p_pid;
kp->ki_nice = p->p_nice;
- bintime2timeval(&p->p_rux.rux_runtime, &tv);
- kp->ki_runtime = tv.tv_sec * (u_int64_t)1000000 + tv.tv_usec;
+ kp->ki_runtime = p->p_rux.rux_runtime * 1000000 / cpu_tickrate();
mtx_unlock_spin(&sched_lock);
if ((p->p_sflag & PS_INMEM) && p->p_stats != NULL) {
kp->ki_start = p->p_stats->p_start;
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 397a7c507bce..8ecac2ea56af 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -704,7 +704,7 @@ calcru(p, up, sp)
struct timeval *up;
struct timeval *sp;
{
- struct bintime bt;
+ uint64_t bt;
struct rusage_ext rux;
struct thread *td;
int bt_valid;
@@ -712,6 +712,7 @@ calcru(p, up, sp)
PROC_LOCK_ASSERT(p, MA_OWNED);
mtx_assert(&sched_lock, MA_NOTOWNED);
bt_valid = 0;
+ bt = 0;
mtx_lock_spin(&sched_lock);
rux = p->p_rux;
FOREACH_THREAD_IN_PROC(p, td) {
@@ -725,12 +726,16 @@ calcru(p, up, sp)
KASSERT(td->td_oncpu != NOCPU,
("%s: running thread has no CPU", __func__));
if (!bt_valid) {
- binuptime(&bt);
+ bt = cpu_ticks();
bt_valid = 1;
}
- bintime_add(&rux.rux_runtime, &bt);
- bintime_sub(&rux.rux_runtime,
- &pcpu_find(td->td_oncpu)->pc_switchtime);
+ /*
+ * XXX: Doesn't this mean that this quantum will
+ * XXX: get counted twice if calcru() is called
+ * XXX: from SIGINFO ?
+ */
+ rux.rux_runtime +=
+ (bt - pcpu_find(td->td_oncpu)->pc_switchtime);
}
}
mtx_unlock_spin(&sched_lock);
@@ -758,7 +763,6 @@ calcru1(p, ruxp, up, sp)
struct timeval *up;
struct timeval *sp;
{
- struct timeval tv;
/* {user, system, interrupt, total} {ticks, usec}; previous tu: */
u_int64_t ut, uu, st, su, it, iu, tt, tu, ptu;
@@ -770,8 +774,7 @@ calcru1(p, ruxp, up, sp)
st = 1;
tt = 1;
}
- bintime2timeval(&ruxp->rux_runtime, &tv);
- tu = (u_int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+ tu = (ruxp->rux_runtime * 1000000LL) / cpu_tickrate();
ptu = ruxp->rux_uu + ruxp->rux_su + ruxp->rux_iu;
if (tu < ptu) {
printf(
@@ -884,7 +887,7 @@ ruadd(ru, rux, ru2, rux2)
register long *ip, *ip2;
register int i;
- bintime_add(&rux->rux_runtime, &rux2->rux_runtime);
+ rux->rux_runtime += rux2->rux_runtime;
rux->rux_uticks += rux2->rux_uticks;
rux->rux_sticks += rux2->rux_sticks;
rux->rux_iticks += rux2->rux_iticks;
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 6764e353f46d..3ccbc15155d6 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -355,7 +355,7 @@ wakeup_one(ident)
void
mi_switch(int flags, struct thread *newtd)
{
- struct bintime new_switchtime;
+ uint64_t new_switchtime;
struct thread *td;
struct proc *p;
@@ -384,9 +384,8 @@ mi_switch(int flags, struct thread *newtd)
* Compute the amount of time during which the current
* process was running, and add that to its total so far.
*/
- binuptime(&new_switchtime);
- bintime_add(&p->p_rux.rux_runtime, &new_switchtime);
- bintime_sub(&p->p_rux.rux_runtime, PCPU_PTR(switchtime));
+ new_switchtime = cpu_ticks();
+ p->p_rux.rux_runtime += (new_switchtime - PCPU_GET(switchtime));
td->td_generation++; /* bump preempt-detect counter */
@@ -405,7 +404,7 @@ mi_switch(int flags, struct thread *newtd)
* it reaches the max, arrange to kill the process in ast().
*/
if (p->p_cpulimit != RLIM_INFINITY &&
- p->p_rux.rux_runtime.sec >= p->p_cpulimit) {
+ p->p_rux.rux_runtime >= p->p_cpulimit * cpu_tickrate()) {
p->p_sflag |= PS_XCPU;
td->td_flags |= TDF_ASTPENDING;
}
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 929e5701745c..397fd2f165c2 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -131,6 +131,7 @@ sysctl_kern_boottime(SYSCTL_HANDLER_ARGS)
#endif
return SYSCTL_OUT(req, &boottime, sizeof(boottime));
}
+
/*
* Return the difference between the timehands' counter value now and what
* was when we copied it to the timehands' offset_count.
@@ -782,3 +783,23 @@ inittimecounter(void *dummy)
}
SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL)
+
+static
+uint64_t
+tc_cpu_ticks(void)
+{
+ static uint64_t base;
+ static unsigned last;
+ uint64_t u;
+ struct timecounter *tc;
+
+ tc = timehands->th_counter;
+ u = tc->tc_get_timecount(tc) & tc->tc_counter_mask;
+ if (u < last)
+ base += tc->tc_counter_mask + 1;
+ last = u;
+ return (u + base);
+}
+
+uint64_t (*cpu_ticks)(void) = tc_cpu_ticks;
+uint64_t (*cpu_tickrate)(void) = tc_getfrequency;
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 7b6c5b8df437..f4e0a530a5a1 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -238,7 +238,7 @@ ast(struct trapframe *framep)
PROC_LOCK(p);
lim_rlimit(p, RLIMIT_CPU, &rlim);
mtx_lock_spin(&sched_lock);
- if (p->p_rux.rux_runtime.sec >= rlim.rlim_max) {
+ if (p->p_rux.rux_runtime >= rlim.rlim_max * cpu_tickrate()) {
mtx_unlock_spin(&sched_lock);
killproc(p, "exceeded maximum CPU limit");
} else {
diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c
index ff2a0d4bd55d..e4e8280bfc44 100644
--- a/sys/sparc64/sparc64/mp_machdep.c
+++ b/sys/sparc64/sparc64/mp_machdep.c
@@ -361,7 +361,7 @@ cpu_mp_bootstrap(struct pcpu *pc)
/* ok, now grab sched_lock and enter the scheduler */
mtx_lock_spin(&sched_lock);
spinlock_exit();
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
cpu_throw(NULL, choosethread()); /* doesn't return */
}
diff --git a/sys/sparc64/sparc64/tick.c b/sys/sparc64/sparc64/tick.c
index 09ba1f124198..6f9f1a81601a 100644
--- a/sys/sparc64/sparc64/tick.c
+++ b/sys/sparc64/sparc64/tick.c
@@ -65,6 +65,20 @@ SYSCTL_INT(_machdep_tick, OID_AUTO, adjust_ticks, CTLFLAG_RD, &adjust_ticks,
static void tick_hardclock(struct trapframe *);
+static uint64_t
+tick_cputicks(void)
+{
+
+ return (rd(tick));
+}
+
+static uint64_t
+tick_cputickrate(void)
+{
+
+ return (tick_freq);
+}
+
void
cpu_initclocks(void)
{
@@ -156,6 +170,9 @@ tick_init(u_long clock)
* handled.
*/
tick_stop();
+
+ cpu_ticks = tick_cputicks;
+ cpu_tickrate = tick_cputickrate;
}
void
diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h
index c5c59447e7ba..00a3cac97c3e 100644
--- a/sys/sys/pcpu.h
+++ b/sys/sys/pcpu.h
@@ -60,7 +60,7 @@ struct pcpu {
struct thread *pc_fpcurthread; /* Fp state owner */
struct thread *pc_deadthread; /* Zombie thread or NULL */
struct pcb *pc_curpcb; /* Current pcb */
- struct bintime pc_switchtime;
+ uint64_t pc_switchtime;
int pc_switchticks;
u_int pc_cpuid; /* This cpu number */
cpumask_t pc_cpumask; /* This cpu mask */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 101c3953b651..d2a072737e8b 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -505,7 +505,7 @@ struct ksegrp {
* Locking: (cj) means (j) for p_rux and (c) for p_crux.
*/
struct rusage_ext {
- struct bintime rux_runtime; /* (cj) Real time. */
+ u_int64_t rux_runtime; /* (cj) Real time. */
u_int64_t rux_uticks; /* (cj) Statclock hits in user mode. */
u_int64_t rux_sticks; /* (cj) Statclock hits in sys mode. */
u_int64_t rux_iticks; /* (cj) Statclock hits in intr mode. */
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 235e8dd403cc..17967d21f229 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -238,6 +238,9 @@ int setenv(const char *name, const char *value);
int unsetenv(const char *name);
int testenv(const char *name);
+extern uint64_t (*cpu_ticks)(void);
+extern uint64_t (*cpu_tickrate)(void);
+
#ifdef APM_FIXUP_CALLTODO
struct timeval;
void adjust_timeout_calltodo(struct timeval *time_change);