kern_clock.c revision 174898
11541Srgrimes/*-
21541Srgrimes * Copyright (c) 1982, 1986, 1991, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes * (c) UNIX System Laboratories, Inc.
51541Srgrimes * All or some portions of this file are derived from material licensed
61541Srgrimes * to the University of California by American Telephone and Telegraph
71541Srgrimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with
81541Srgrimes * the permission of UNIX System Laboratories, Inc.
91541Srgrimes *
101541Srgrimes * Redistribution and use in source and binary forms, with or without
111541Srgrimes * modification, are permitted provided that the following conditions
121541Srgrimes * are met:
131541Srgrimes * 1. Redistributions of source code must retain the above copyright
141541Srgrimes *    notice, this list of conditions and the following disclaimer.
151541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
161541Srgrimes *    notice, this list of conditions and the following disclaimer in the
171541Srgrimes *    documentation and/or other materials provided with the distribution.
181541Srgrimes * 4. Neither the name of the University nor the names of its contributors
191541Srgrimes *    may be used to endorse or promote products derived from this software
201541Srgrimes *    without specific prior written permission.
211541Srgrimes *
221541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
231541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
241541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
251541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
261541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
271541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
281541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
291541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
301541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
311541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
321541Srgrimes * SUCH DAMAGE.
331541Srgrimes *
341541Srgrimes *	@(#)kern_clock.c	8.5 (Berkeley) 1/21/94
351541Srgrimes */
361541Srgrimes
37116182Sobrien#include <sys/cdefs.h>
38116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_clock.c 174898 2007-12-25 17:52:02Z rwatson $");
39116182Sobrien
40170075Semaste#include "opt_kdb.h"
41150968Sglebius#include "opt_device_polling.h"
42147565Speter#include "opt_hwpmc_hooks.h"
4344666Sphk#include "opt_ntp.h"
44116874Ssmkelly#include "opt_watchdog.h"
4544666Sphk
461541Srgrimes#include <sys/param.h>
471541Srgrimes#include <sys/systm.h>
481541Srgrimes#include <sys/callout.h>
49131927Smarcel#include <sys/kdb.h>
501541Srgrimes#include <sys/kernel.h>
5174914Sjhb#include <sys/lock.h>
5284812Sjhb#include <sys/ktr.h>
5367365Sjhb#include <sys/mutex.h>
541541Srgrimes#include <sys/proc.h>
55111024Sjeff#include <sys/resource.h>
561541Srgrimes#include <sys/resourcevar.h>
57104964Sjeff#include <sys/sched.h>
583308Sphk#include <sys/signalvar.h>
5976078Sjhb#include <sys/smp.h>
602320Sdg#include <vm/vm.h>
6112662Sdg#include <vm/pmap.h>
6212662Sdg#include <vm/vm_map.h>
633308Sphk#include <sys/sysctl.h>
6467551Sjhb#include <sys/bus.h>
6567551Sjhb#include <sys/interrupt.h>
66114216Skan#include <sys/limits.h>
67102926Sphk#include <sys/timetc.h>
681541Srgrimes
691541Srgrimes#ifdef GPROF
701541Srgrimes#include <sys/gmon.h>
711541Srgrimes#endif
721541Srgrimes
73146799Sjkoshy#ifdef HWPMC_HOOKS
74146799Sjkoshy#include <sys/pmckern.h>
75146799Sjkoshy#endif
76146799Sjkoshy
7787902Sluigi#ifdef DEVICE_POLLING
7887902Sluigiextern void hardclock_device_poll(void);
7987902Sluigi#endif /* DEVICE_POLLING */
8031639Sfsmp
8192723Salfredstatic void initclocks(void *dummy);
8210358SjulianSYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL)
8310358Sjulian
84169803Sjeff/* Spin-lock protecting profiling statistics. */
85170468Sattiliostatic struct mtx time_lock;
86169803Sjeff
87147692Speterstatic int
88147692Spetersysctl_kern_cp_time(SYSCTL_HANDLER_ARGS)
89147692Speter{
90147692Speter	int error;
91174070Speter	long cp_time[CPUSTATES];
92147703Sps#ifdef SCTL_MASK32
93147692Speter	int i;
94147692Speter	unsigned int cp_time32[CPUSTATES];
95174070Speter#endif
96157822Sjhb
97174070Speter	read_cpu_time(cp_time);
98174070Speter#ifdef SCTL_MASK32
99147703Sps	if (req->flags & SCTL_MASK32) {
100147692Speter		if (!req->oldptr)
101147692Speter			return SYSCTL_OUT(req, 0, sizeof(cp_time32));
102147692Speter		for (i = 0; i < CPUSTATES; i++)
103147692Speter			cp_time32[i] = (unsigned int)cp_time[i];
104147692Speter		error = SYSCTL_OUT(req, cp_time32, sizeof(cp_time32));
105147692Speter	} else
106147692Speter#endif
107147692Speter	{
108147692Speter		if (!req->oldptr)
109147692Speter			return SYSCTL_OUT(req, 0, sizeof(cp_time));
110147692Speter		error = SYSCTL_OUT(req, cp_time, sizeof(cp_time));
111147692Speter	}
112147692Speter	return error;
113147692Speter}
114147692Speter
115157822SjhbSYSCTL_PROC(_kern, OID_AUTO, cp_time, CTLTYPE_LONG|CTLFLAG_RD,
116147692Speter    0,0, sysctl_kern_cp_time, "LU", "CPU time statistics");
117147692Speter
118174070Speterstatic long empty[CPUSTATES];
119174070Speter
120174070Speterstatic int
121174070Spetersysctl_kern_cp_times(SYSCTL_HANDLER_ARGS)
122174070Speter{
123174070Speter	struct pcpu *pcpu;
124174070Speter	int error;
125174072Srwatson	int c;
126174070Speter	long *cp_time;
127174070Speter#ifdef SCTL_MASK32
128174070Speter	unsigned int cp_time32[CPUSTATES];
129174072Srwatson	int i;
130174070Speter#endif
131174070Speter
132174070Speter	if (!req->oldptr) {
133174070Speter#ifdef SCTL_MASK32
134174070Speter		if (req->flags & SCTL_MASK32)
135174070Speter			return SYSCTL_OUT(req, 0, sizeof(cp_time32) * (mp_maxid + 1));
136174070Speter		else
137174070Speter#endif
138174070Speter			return SYSCTL_OUT(req, 0, sizeof(long) * CPUSTATES * (mp_maxid + 1));
139174070Speter	}
140174070Speter	for (error = 0, c = 0; error == 0 && c <= mp_maxid; c++) {
141174070Speter		if (!CPU_ABSENT(c)) {
142174070Speter			pcpu = pcpu_find(c);
143174070Speter			cp_time = pcpu->pc_cp_time;
144174070Speter		} else {
145174070Speter			cp_time = empty;
146174070Speter		}
147174070Speter#ifdef SCTL_MASK32
148174070Speter		if (req->flags & SCTL_MASK32) {
149174070Speter			for (i = 0; i < CPUSTATES; i++)
150174070Speter				cp_time32[i] = (unsigned int)cp_time[i];
151174070Speter			error = SYSCTL_OUT(req, cp_time32, sizeof(cp_time32));
152174070Speter		} else
153174070Speter#endif
154174070Speter			error = SYSCTL_OUT(req, cp_time, sizeof(long) * CPUSTATES);
155174070Speter	}
156174070Speter	return error;
157174070Speter}
158174070Speter
159174070SpeterSYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD,
160174070Speter    0,0, sysctl_kern_cp_times, "LU", "per-CPU time statistics");
161174070Speter
162174070Spetervoid
163174070Speterread_cpu_time(long *cp_time)
164174070Speter{
165174070Speter	struct pcpu *pc;
166174070Speter	int i, j;
167174070Speter
168174070Speter	/* Sum up global cp_time[]. */
169174070Speter	bzero(cp_time, sizeof(long) * CPUSTATES);
170174070Speter	for (i = 0; i <= mp_maxid; i++) {
171174070Speter		if (CPU_ABSENT(i))
172174070Speter			continue;
173174070Speter		pc = pcpu_find(i);
174174070Speter		for (j = 0; j < CPUSTATES; j++)
175174070Speter			cp_time[j] += pc->pc_cp_time[j];
176174070Speter	}
177174070Speter}
178174070Speter
179126383Sphk#ifdef SW_WATCHDOG
180126383Sphk#include <sys/watchdog.h>
181116874Ssmkelly
182126383Sphkstatic int watchdog_ticks;
183116874Ssmkellystatic int watchdog_enabled;
184126383Sphkstatic void watchdog_fire(void);
185126383Sphkstatic void watchdog_config(void *, u_int, int *);
186126383Sphk#endif /* SW_WATCHDOG */
187116874Ssmkelly
1881541Srgrimes/*
1891541Srgrimes * Clock handling routines.
1901541Srgrimes *
19134618Sphk * This code is written to operate with two timers that run independently of
19234618Sphk * each other.
19333690Sphk *
19434618Sphk * The main timer, running hz times per second, is used to trigger interval
19534618Sphk * timers, timeouts and rescheduling as needed.
19633690Sphk *
19734618Sphk * The second timer handles kernel and user profiling,
19834618Sphk * and does resource use estimation.  If the second timer is programmable,
19934618Sphk * it is randomized to avoid aliasing between the two clocks.  For example,
20034618Sphk * the randomization prevents an adversary from always giving up the cpu
2011541Srgrimes * just before its quantum expires.  Otherwise, it would never accumulate
2021541Srgrimes * cpu ticks.  The mean frequency of the second timer is stathz.
20334618Sphk *
20434618Sphk * If no second timer exists, stathz will be zero; in this case we drive
20534618Sphk * profiling and statistics off the main clock.  This WILL NOT be accurate;
20634618Sphk * do not do it unless absolutely necessary.
20734618Sphk *
2081541Srgrimes * The statistics clock may (or may not) be run at a higher rate while
20934618Sphk * profiling.  This profile clock runs at profhz.  We require that profhz
21034618Sphk * be an integral multiple of stathz.
2111541Srgrimes *
21234618Sphk * If the statistics clock is running fast, it must be divided by the ratio
21334618Sphk * profhz/stathz for statistics.  (For profiling, every tick counts.)
21434618Sphk *
21533690Sphk * Time-of-day is maintained using a "timecounter", which may or may
21633690Sphk * not be related to the hardware generating the above mentioned
21733690Sphk * interrupts.
2181541Srgrimes */
2191541Srgrimes
2201541Srgrimesint	stathz;
2211541Srgrimesint	profhz;
222110296Sjakeint	profprocs;
2231541Srgrimesint	ticks;
224110296Sjakeint	psratio;
2251541Srgrimes
2261541Srgrimes/*
2271541Srgrimes * Initialize clock frequencies and start both clocks running.
2281541Srgrimes */
22910358Sjulian/* ARGSUSED*/
23010358Sjulianstatic void
23112569Sbdeinitclocks(dummy)
23212569Sbde	void *dummy;
2331541Srgrimes{
2341541Srgrimes	register int i;
2351541Srgrimes
2361541Srgrimes	/*
2371541Srgrimes	 * Set divisors to 1 (normal case) and let the machine-specific
2381541Srgrimes	 * code do its bit.
2391541Srgrimes	 */
240169906Srwatson	mtx_init(&time_lock, "time lock", NULL, MTX_SPIN);
2411541Srgrimes	cpu_initclocks();
2421541Srgrimes
2431541Srgrimes	/*
2441541Srgrimes	 * Compute profhz/stathz, and fix profhz if needed.
2451541Srgrimes	 */
2461541Srgrimes	i = stathz ? stathz : hz;
2471541Srgrimes	if (profhz == 0)
2481541Srgrimes		profhz = i;
2491541Srgrimes	psratio = profhz / i;
250126383Sphk#ifdef SW_WATCHDOG
251126383Sphk	EVENTHANDLER_REGISTER(watchdog_list, watchdog_config, NULL, 0);
252126383Sphk#endif
2531541Srgrimes}
2541541Srgrimes
2551541Srgrimes/*
256110296Sjake * Each time the real-time timer fires, this function is called on all CPUs.
257153666Sjhb * Note that hardclock() calls hardclock_cpu() for the boot CPU, so only
258110296Sjake * the other CPUs in the system need to call this function.
25976078Sjhb */
26076078Sjhbvoid
261153666Sjhbhardclock_cpu(int usermode)
26276078Sjhb{
26376078Sjhb	struct pstats *pstats;
264110296Sjake	struct thread *td = curthread;
26583366Sjulian	struct proc *p = td->td_proc;
266172207Sjeff	int flags;
26776078Sjhb
26876078Sjhb	/*
26976078Sjhb	 * Run current process's virtual and profile time, as needed.
27076078Sjhb	 */
271163709Sjb	pstats = p->p_stats;
272172207Sjeff	flags = 0;
273163709Sjb	if (usermode &&
274170297Sjeff	    timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value)) {
275170297Sjeff		PROC_SLOCK(p);
276172207Sjeff		if (itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0)
277172207Sjeff			flags |= TDF_ALRMPEND | TDF_ASTPENDING;
278170297Sjeff		PROC_SUNLOCK(p);
279163709Sjb	}
280170297Sjeff	if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)) {
281170297Sjeff		PROC_SLOCK(p);
282172207Sjeff		if (itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0)
283172207Sjeff			flags |= TDF_PROFPEND | TDF_ASTPENDING;
284170297Sjeff		PROC_SUNLOCK(p);
285170297Sjeff	}
286170297Sjeff	thread_lock(td);
287170297Sjeff	sched_tick();
288172207Sjeff	td->td_flags |= flags;
289170297Sjeff	thread_unlock(td);
290146799Sjkoshy
291146799Sjkoshy#ifdef	HWPMC_HOOKS
292146799Sjkoshy	if (PMC_CPU_HAS_SAMPLES(PCPU_GET(cpuid)))
293146799Sjkoshy		PMC_CALL_HOOK_UNLOCKED(curthread, PMC_FN_DO_SAMPLES, NULL);
294146799Sjkoshy#endif
29576078Sjhb}
29676078Sjhb
29776078Sjhb/*
2981541Srgrimes * The real-time timer, interrupting hz times per second.
2991541Srgrimes */
3001541Srgrimesvoid
301153666Sjhbhardclock(int usermode, uintfptr_t pc)
3021541Srgrimes{
30368889Sjake	int need_softclock = 0;
3041541Srgrimes
305153666Sjhb	hardclock_cpu(usermode);
3061541Srgrimes
307102926Sphk	tc_ticktock();
3081541Srgrimes	/*
3091541Srgrimes	 * If no separate statistics clock is available, run it from here.
31076078Sjhb	 *
31176078Sjhb	 * XXX: this only works for UP
3121541Srgrimes	 */
313110296Sjake	if (stathz == 0) {
314153666Sjhb		profclock(usermode, pc);
315153666Sjhb		statclock(usermode);
316110296Sjake	}
3171541Srgrimes
31887902Sluigi#ifdef DEVICE_POLLING
31990550Sluigi	hardclock_device_poll();	/* this is very short and quick */
32087902Sluigi#endif /* DEVICE_POLLING */
3212858Swollman
32234618Sphk	/*
32334618Sphk	 * Process callouts at a very low cpu priority, so we don't keep the
32434618Sphk	 * relatively high clock interrupt priority any longer than necessary.
32534618Sphk	 */
32686423Sjhb	mtx_lock_spin_flags(&callout_lock, MTX_QUIET);
32768889Sjake	ticks++;
328159598Sdelphij	if (!TAILQ_EMPTY(&callwheel[ticks & callwheelmask])) {
32968889Sjake		need_softclock = 1;
33034618Sphk	} else if (softticks + 1 == ticks)
33134618Sphk		++softticks;
33286423Sjhb	mtx_unlock_spin_flags(&callout_lock, MTX_QUIET);
33368889Sjake
33468889Sjake	/*
335170297Sjeff	 * swi_sched acquires the thread lock, so we don't want to call it
336170297Sjeff	 * with callout_lock held; incorrect locking order.
33768889Sjake	 */
33868889Sjake	if (need_softclock)
33988900Sjhb		swi_sched(softclock_ih, 0);
340116874Ssmkelly
341126383Sphk#ifdef SW_WATCHDOG
342126383Sphk	if (watchdog_enabled > 0 && --watchdog_ticks <= 0)
343116874Ssmkelly		watchdog_fire();
344126383Sphk#endif /* SW_WATCHDOG */
3451541Srgrimes}
3461541Srgrimes
3471541Srgrimes/*
34834961Sphk * Compute number of ticks in the specified amount of time.
3491541Srgrimes */
3501541Srgrimesint
35134961Sphktvtohz(tv)
3521541Srgrimes	struct timeval *tv;
3531541Srgrimes{
3545081Sbde	register unsigned long ticks;
3555081Sbde	register long sec, usec;
3561541Srgrimes
3571541Srgrimes	/*
3585081Sbde	 * If the number of usecs in the whole seconds part of the time
3595081Sbde	 * difference fits in a long, then the total number of usecs will
3605081Sbde	 * fit in an unsigned long.  Compute the total and convert it to
3615081Sbde	 * ticks, rounding up and adding 1 to allow for the current tick
3625081Sbde	 * to expire.  Rounding also depends on unsigned long arithmetic
3635081Sbde	 * to avoid overflow.
3641541Srgrimes	 *
3655081Sbde	 * Otherwise, if the number of ticks in the whole seconds part of
3665081Sbde	 * the time difference fits in a long, then convert the parts to
3675081Sbde	 * ticks separately and add, using similar rounding methods and
3685081Sbde	 * overflow avoidance.  This method would work in the previous
3695081Sbde	 * case but it is slightly slower and assumes that hz is integral.
3705081Sbde	 *
3715081Sbde	 * Otherwise, round the time difference down to the maximum
3725081Sbde	 * representable value.
3735081Sbde	 *
3745081Sbde	 * If ints have 32 bits, then the maximum value for any timeout in
3755081Sbde	 * 10ms ticks is 248 days.
3761541Srgrimes	 */
37734961Sphk	sec = tv->tv_sec;
37834961Sphk	usec = tv->tv_usec;
3795081Sbde	if (usec < 0) {
3805081Sbde		sec--;
3815081Sbde		usec += 1000000;
3825081Sbde	}
3835081Sbde	if (sec < 0) {
3845081Sbde#ifdef DIAGNOSTIC
38534618Sphk		if (usec > 0) {
38633690Sphk			sec++;
38733690Sphk			usec -= 1000000;
38833690Sphk		}
38934961Sphk		printf("tvotohz: negative time difference %ld sec %ld usec\n",
3905081Sbde		       sec, usec);
3915081Sbde#endif
3925081Sbde		ticks = 1;
3935081Sbde	} else if (sec <= LONG_MAX / 1000000)
3945081Sbde		ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
3955081Sbde			/ tick + 1;
3965081Sbde	else if (sec <= LONG_MAX / hz)
3975081Sbde		ticks = sec * hz
3985081Sbde			+ ((unsigned long)usec + (tick - 1)) / tick + 1;
3991541Srgrimes	else
4005081Sbde		ticks = LONG_MAX;
4015081Sbde	if (ticks > INT_MAX)
4025081Sbde		ticks = INT_MAX;
40340012Salex	return ((int)ticks);
4041541Srgrimes}
4051541Srgrimes
4061541Srgrimes/*
4071541Srgrimes * Start profiling on a process.
4081541Srgrimes *
4091541Srgrimes * Kernel profiling passes proc0 which never exits and hence
4101541Srgrimes * keeps the profile clock running constantly.
4111541Srgrimes */
4121541Srgrimesvoid
4131541Srgrimesstartprofclock(p)
4141541Srgrimes	register struct proc *p;
4151541Srgrimes{
4161541Srgrimes
417113874Sjhb	PROC_LOCK_ASSERT(p, MA_OWNED);
418113874Sjhb	if (p->p_flag & P_STOPPROF)
419110530Sjulian		return;
420113874Sjhb	if ((p->p_flag & P_PROFIL) == 0) {
421113874Sjhb		p->p_flag |= P_PROFIL;
422169803Sjeff		mtx_lock_spin(&time_lock);
423110296Sjake		if (++profprocs == 1)
424110296Sjake			cpu_startprofclock();
425169803Sjeff		mtx_unlock_spin(&time_lock);
4261541Srgrimes	}
4271541Srgrimes}
4281541Srgrimes
4291541Srgrimes/*
4301541Srgrimes * Stop profiling on a process.
4311541Srgrimes */
4321541Srgrimesvoid
4331541Srgrimesstopprofclock(p)
4341541Srgrimes	register struct proc *p;
4351541Srgrimes{
4361541Srgrimes
437110530Sjulian	PROC_LOCK_ASSERT(p, MA_OWNED);
438113874Sjhb	if (p->p_flag & P_PROFIL) {
439113874Sjhb		if (p->p_profthreads != 0) {
440113874Sjhb			p->p_flag |= P_STOPPROF;
441113874Sjhb			while (p->p_profthreads != 0)
442113874Sjhb				msleep(&p->p_profthreads, &p->p_mtx, PPAUSE,
443123740Speter				    "stopprof", 0);
444113874Sjhb			p->p_flag &= ~P_STOPPROF;
445110530Sjulian		}
446128852Scperciva		if ((p->p_flag & P_PROFIL) == 0)
447128852Scperciva			return;
448113874Sjhb		p->p_flag &= ~P_PROFIL;
449169803Sjeff		mtx_lock_spin(&time_lock);
450110296Sjake		if (--profprocs == 0)
451110296Sjake			cpu_stopprofclock();
452169803Sjeff		mtx_unlock_spin(&time_lock);
4531541Srgrimes	}
4541541Srgrimes}
4551541Srgrimes
4561541Srgrimes/*
457170174Sjeff * Statistics clock.  Updates rusage information and calls the scheduler
458170174Sjeff * to adjust priorities of the active thread.
459170174Sjeff *
460110296Sjake * This should be called by all active processors.
4611541Srgrimes */
4621541Srgrimesvoid
463153666Sjhbstatclock(int usermode)
4641541Srgrimes{
46517342Sbde	struct rusage *ru;
46617342Sbde	struct vmspace *vm;
467110296Sjake	struct thread *td;
468110296Sjake	struct proc *p;
469110296Sjake	long rss;
470174070Speter	long *cp_time;
4711541Srgrimes
472110296Sjake	td = curthread;
473110296Sjake	p = td->td_proc;
474110296Sjake
475174070Speter	cp_time = (long *)PCPU_PTR(cp_time);
476153666Sjhb	if (usermode) {
47753751Sbde		/*
47853751Sbde		 * Charge the time as appropriate.
4791541Srgrimes		 */
480163709Sjb#ifdef KSE
481116361Sdavidxu		if (p->p_flag & P_SA)
482111028Sjeff			thread_statclock(1);
483163709Sjb#endif
484155534Sphk		td->td_uticks++;
485130551Sjulian		if (p->p_nice > NZERO)
486174070Speter			cp_time[CP_NICE]++;
4871541Srgrimes		else
488174070Speter			cp_time[CP_USER]++;
4891541Srgrimes	} else {
4901541Srgrimes		/*
4911541Srgrimes		 * Came from kernel mode, so we were:
4921541Srgrimes		 * - handling an interrupt,
4931541Srgrimes		 * - doing syscall or trap work on behalf of the current
4941541Srgrimes		 *   user process, or
4951541Srgrimes		 * - spinning in the idle loop.
4961541Srgrimes		 * Whichever it is, charge the time as appropriate.
4971541Srgrimes		 * Note that we charge interrupts to the current process,
4981541Srgrimes		 * regardless of whether they are ``for'' that process,
4991541Srgrimes		 * so that we know how much of its real time was spent
5001541Srgrimes		 * in ``non-process'' (i.e., interrupt) work.
5011541Srgrimes		 */
502151658Sjhb		if ((td->td_pflags & TDP_ITHREAD) ||
503151658Sjhb		    td->td_intr_nesting_level >= 2) {
504155534Sphk			td->td_iticks++;
505174070Speter			cp_time[CP_INTR]++;
50665557Sjasone		} else {
507163709Sjb#ifdef KSE
508116361Sdavidxu			if (p->p_flag & P_SA)
509111028Sjeff				thread_statclock(0);
510163709Sjb#endif
511155455Sphk			td->td_pticks++;
512155534Sphk			td->td_sticks++;
513167327Sjulian			if (!TD_IS_IDLETHREAD(td))
514174070Speter				cp_time[CP_SYS]++;
51565557Sjasone			else
516174070Speter				cp_time[CP_IDLE]++;
51765557Sjasone		}
5181541Srgrimes	}
5191541Srgrimes
52065782Sjhb	/* Update resource usage integrals and maximums. */
521131436Sjhb	MPASS(p->p_vmspace != NULL);
522131436Sjhb	vm = p->p_vmspace;
523170174Sjeff	ru = &td->td_ru;
524131436Sjhb	ru->ru_ixrss += pgtok(vm->vm_tsize);
525131436Sjhb	ru->ru_idrss += pgtok(vm->vm_dsize);
526131436Sjhb	ru->ru_isrss += pgtok(vm->vm_ssize);
527131436Sjhb	rss = pgtok(vmspace_resident_count(vm));
528131436Sjhb	if (ru->ru_maxrss < rss)
529131436Sjhb		ru->ru_maxrss = rss;
530170297Sjeff	CTR4(KTR_SCHED, "statclock: %p(%s) prio %d stathz %d",
531173600Sjulian	    td, td->td_name, td->td_priority, (stathz)?stathz:hz);
532174070Speter	thread_lock_flags(td, MTX_QUIET);
533170297Sjeff	sched_clock(td);
534170297Sjeff	thread_unlock(td);
53576078Sjhb}
53666716Sjhb
53776078Sjhbvoid
538153666Sjhbprofclock(int usermode, uintfptr_t pc)
53976078Sjhb{
540110296Sjake	struct thread *td;
541110296Sjake#ifdef GPROF
542110296Sjake	struct gmonparam *g;
543153490Sjhb	uintfptr_t i;
544110296Sjake#endif
54576078Sjhb
546111032Sjulian	td = curthread;
547153666Sjhb	if (usermode) {
548110296Sjake		/*
549110296Sjake		 * Came from user mode; CPU was in user state.
550110296Sjake		 * If this process is being profiled, record the tick.
551110530Sjulian		 * if there is no related user location yet, don't
552110530Sjulian		 * bother trying to count it.
553110296Sjake		 */
554113874Sjhb		if (td->td_proc->p_flag & P_PROFIL)
555153666Sjhb			addupc_intr(td, pc, 1);
556110296Sjake	}
557110296Sjake#ifdef GPROF
558110296Sjake	else {
559110296Sjake		/*
560110296Sjake		 * Kernel statistics are just like addupc_intr, only easier.
561110296Sjake		 */
562110296Sjake		g = &_gmonparam;
563153666Sjhb		if (g->state == GMON_PROF_ON && pc >= g->lowpc) {
564153666Sjhb			i = PC_TO_I(g, pc);
565110296Sjake			if (i < g->textsize) {
566153666Sjhb				KCOUNT(g, i)++;
567110296Sjake			}
568110296Sjake		}
569110296Sjake	}
570110296Sjake#endif
5711541Srgrimes}
5721541Srgrimes
5731541Srgrimes/*
5741541Srgrimes * Return information about system clocks.
5751541Srgrimes */
57612152Sphkstatic int
57762573Sphksysctl_kern_clockrate(SYSCTL_HANDLER_ARGS)
5781541Srgrimes{
5791541Srgrimes	struct clockinfo clkinfo;
5801541Srgrimes	/*
5811541Srgrimes	 * Construct clockinfo structure.
5821541Srgrimes	 */
58396052Sbde	bzero(&clkinfo, sizeof(clkinfo));
5841541Srgrimes	clkinfo.hz = hz;
5851541Srgrimes	clkinfo.tick = tick;
5861541Srgrimes	clkinfo.profhz = profhz;
5871541Srgrimes	clkinfo.stathz = stathz ? stathz : hz;
58812243Sphk	return (sysctl_handle_opaque(oidp, &clkinfo, sizeof clkinfo, req));
5891541Srgrimes}
5902858Swollman
59112623SphkSYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, CTLTYPE_STRUCT|CTLFLAG_RD,
59288019Sluigi	0, 0, sysctl_kern_clockrate, "S,clockinfo",
59388019Sluigi	"Rate and period of various kernel clocks");
594116874Ssmkelly
595126383Sphk#ifdef SW_WATCHDOG
596126383Sphk
597126383Sphkstatic void
598165260Sn_hibmawatchdog_config(void *unused __unused, u_int cmd, int *error)
599116874Ssmkelly{
600126383Sphk	u_int u;
601116874Ssmkelly
602126386Sphk	u = cmd & WD_INTERVAL;
603165260Sn_hibma	if (u >= WD_TO_1SEC) {
604126383Sphk		watchdog_ticks = (1 << (u - WD_TO_1SEC)) * hz;
605126383Sphk		watchdog_enabled = 1;
606165260Sn_hibma		*error = 0;
607126383Sphk	} else {
608126383Sphk		watchdog_enabled = 0;
609126383Sphk	}
610116874Ssmkelly}
611116874Ssmkelly
612116874Ssmkelly/*
613116874Ssmkelly * Handle a watchdog timeout by dumping interrupt information and
614170075Semaste * then either dropping to DDB or panicking.
615116874Ssmkelly */
616116874Ssmkellystatic void
617116874Ssmkellywatchdog_fire(void)
618116874Ssmkelly{
619116874Ssmkelly	int nintr;
620116874Ssmkelly	u_int64_t inttotal;
621116874Ssmkelly	u_long *curintr;
622116874Ssmkelly	char *curname;
623116874Ssmkelly
624116874Ssmkelly	curintr = intrcnt;
625116874Ssmkelly	curname = intrnames;
626116874Ssmkelly	inttotal = 0;
627116874Ssmkelly	nintr = eintrcnt - intrcnt;
628157822Sjhb
629116874Ssmkelly	printf("interrupt                   total\n");
630116874Ssmkelly	while (--nintr >= 0) {
631116874Ssmkelly		if (*curintr)
632116874Ssmkelly			printf("%-12s %20lu\n", curname, *curintr);
633116874Ssmkelly		curname += strlen(curname) + 1;
634116874Ssmkelly		inttotal += *curintr++;
635116874Ssmkelly	}
636116908Ssmkelly	printf("Total        %20ju\n", (uintmax_t)inttotal);
637170075Semaste
638170075Semaste#if defined(KDB) && !defined(KDB_UNATTENDED)
639170075Semaste	kdb_backtrace();
640174898Srwatson	kdb_enter(KDB_WHY_WATCHDOG, "watchdog timeout");
641170075Semaste#else
642116874Ssmkelly	panic("watchdog timeout");
643170075Semaste#endif
644116874Ssmkelly}
645116874Ssmkelly
646126383Sphk#endif /* SW_WATCHDOG */
647