kern_clock.c revision 174070
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 174070 2007-11-29 06:34:30Z peter $");
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;
125174070Speter	int i, c;
126174070Speter	long *cp_time;
127174070Speter#ifdef SCTL_MASK32
128174070Speter	unsigned int cp_time32[CPUSTATES];
129174070Speter#endif
130174070Speter
131174070Speter	if (!req->oldptr) {
132174070Speter#ifdef SCTL_MASK32
133174070Speter		if (req->flags & SCTL_MASK32)
134174070Speter			return SYSCTL_OUT(req, 0, sizeof(cp_time32) * (mp_maxid + 1));
135174070Speter		else
136174070Speter#endif
137174070Speter			return SYSCTL_OUT(req, 0, sizeof(long) * CPUSTATES * (mp_maxid + 1));
138174070Speter	}
139174070Speter	for (error = 0, c = 0; error == 0 && c <= mp_maxid; c++) {
140174070Speter		if (!CPU_ABSENT(c)) {
141174070Speter			pcpu = pcpu_find(c);
142174070Speter			cp_time = pcpu->pc_cp_time;
143174070Speter		} else {
144174070Speter			cp_time = empty;
145174070Speter		}
146174070Speter#ifdef SCTL_MASK32
147174070Speter		if (req->flags & SCTL_MASK32) {
148174070Speter			for (i = 0; i < CPUSTATES; i++)
149174070Speter				cp_time32[i] = (unsigned int)cp_time[i];
150174070Speter			error = SYSCTL_OUT(req, cp_time32, sizeof(cp_time32));
151174070Speter		} else
152174070Speter#endif
153174070Speter			error = SYSCTL_OUT(req, cp_time, sizeof(long) * CPUSTATES);
154174070Speter	}
155174070Speter	return error;
156174070Speter}
157174070Speter
158174070SpeterSYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD,
159174070Speter    0,0, sysctl_kern_cp_times, "LU", "per-CPU time statistics");
160174070Speter
161174070Spetervoid
162174070Speterread_cpu_time(long *cp_time)
163174070Speter{
164174070Speter	struct pcpu *pc;
165174070Speter	int i, j;
166174070Speter
167174070Speter	/* Sum up global cp_time[]. */
168174070Speter	bzero(cp_time, sizeof(long) * CPUSTATES);
169174070Speter	for (i = 0; i <= mp_maxid; i++) {
170174070Speter		if (CPU_ABSENT(i))
171174070Speter			continue;
172174070Speter		pc = pcpu_find(i);
173174070Speter		for (j = 0; j < CPUSTATES; j++)
174174070Speter			cp_time[j] += pc->pc_cp_time[j];
175174070Speter	}
176174070Speter}
177174070Speter
178126383Sphk#ifdef SW_WATCHDOG
179126383Sphk#include <sys/watchdog.h>
180116874Ssmkelly
181126383Sphkstatic int watchdog_ticks;
182116874Ssmkellystatic int watchdog_enabled;
183126383Sphkstatic void watchdog_fire(void);
184126383Sphkstatic void watchdog_config(void *, u_int, int *);
185126383Sphk#endif /* SW_WATCHDOG */
186116874Ssmkelly
1871541Srgrimes/*
1881541Srgrimes * Clock handling routines.
1891541Srgrimes *
19034618Sphk * This code is written to operate with two timers that run independently of
19134618Sphk * each other.
19233690Sphk *
19334618Sphk * The main timer, running hz times per second, is used to trigger interval
19434618Sphk * timers, timeouts and rescheduling as needed.
19533690Sphk *
19634618Sphk * The second timer handles kernel and user profiling,
19734618Sphk * and does resource use estimation.  If the second timer is programmable,
19834618Sphk * it is randomized to avoid aliasing between the two clocks.  For example,
19934618Sphk * the randomization prevents an adversary from always giving up the cpu
2001541Srgrimes * just before its quantum expires.  Otherwise, it would never accumulate
2011541Srgrimes * cpu ticks.  The mean frequency of the second timer is stathz.
20234618Sphk *
20334618Sphk * If no second timer exists, stathz will be zero; in this case we drive
20434618Sphk * profiling and statistics off the main clock.  This WILL NOT be accurate;
20534618Sphk * do not do it unless absolutely necessary.
20634618Sphk *
2071541Srgrimes * The statistics clock may (or may not) be run at a higher rate while
20834618Sphk * profiling.  This profile clock runs at profhz.  We require that profhz
20934618Sphk * be an integral multiple of stathz.
2101541Srgrimes *
21134618Sphk * If the statistics clock is running fast, it must be divided by the ratio
21234618Sphk * profhz/stathz for statistics.  (For profiling, every tick counts.)
21334618Sphk *
21433690Sphk * Time-of-day is maintained using a "timecounter", which may or may
21533690Sphk * not be related to the hardware generating the above mentioned
21633690Sphk * interrupts.
2171541Srgrimes */
2181541Srgrimes
2191541Srgrimesint	stathz;
2201541Srgrimesint	profhz;
221110296Sjakeint	profprocs;
2221541Srgrimesint	ticks;
223110296Sjakeint	psratio;
2241541Srgrimes
2251541Srgrimes/*
2261541Srgrimes * Initialize clock frequencies and start both clocks running.
2271541Srgrimes */
22810358Sjulian/* ARGSUSED*/
22910358Sjulianstatic void
23012569Sbdeinitclocks(dummy)
23112569Sbde	void *dummy;
2321541Srgrimes{
2331541Srgrimes	register int i;
2341541Srgrimes
2351541Srgrimes	/*
2361541Srgrimes	 * Set divisors to 1 (normal case) and let the machine-specific
2371541Srgrimes	 * code do its bit.
2381541Srgrimes	 */
239169906Srwatson	mtx_init(&time_lock, "time lock", NULL, MTX_SPIN);
2401541Srgrimes	cpu_initclocks();
2411541Srgrimes
2421541Srgrimes	/*
2431541Srgrimes	 * Compute profhz/stathz, and fix profhz if needed.
2441541Srgrimes	 */
2451541Srgrimes	i = stathz ? stathz : hz;
2461541Srgrimes	if (profhz == 0)
2471541Srgrimes		profhz = i;
2481541Srgrimes	psratio = profhz / i;
249126383Sphk#ifdef SW_WATCHDOG
250126383Sphk	EVENTHANDLER_REGISTER(watchdog_list, watchdog_config, NULL, 0);
251126383Sphk#endif
2521541Srgrimes}
2531541Srgrimes
2541541Srgrimes/*
255110296Sjake * Each time the real-time timer fires, this function is called on all CPUs.
256153666Sjhb * Note that hardclock() calls hardclock_cpu() for the boot CPU, so only
257110296Sjake * the other CPUs in the system need to call this function.
25876078Sjhb */
25976078Sjhbvoid
260153666Sjhbhardclock_cpu(int usermode)
26176078Sjhb{
26276078Sjhb	struct pstats *pstats;
263110296Sjake	struct thread *td = curthread;
26483366Sjulian	struct proc *p = td->td_proc;
265172207Sjeff	int flags;
26676078Sjhb
26776078Sjhb	/*
26876078Sjhb	 * Run current process's virtual and profile time, as needed.
26976078Sjhb	 */
270163709Sjb	pstats = p->p_stats;
271172207Sjeff	flags = 0;
272163709Sjb	if (usermode &&
273170297Sjeff	    timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value)) {
274170297Sjeff		PROC_SLOCK(p);
275172207Sjeff		if (itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0)
276172207Sjeff			flags |= TDF_ALRMPEND | TDF_ASTPENDING;
277170297Sjeff		PROC_SUNLOCK(p);
278163709Sjb	}
279170297Sjeff	if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)) {
280170297Sjeff		PROC_SLOCK(p);
281172207Sjeff		if (itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0)
282172207Sjeff			flags |= TDF_PROFPEND | TDF_ASTPENDING;
283170297Sjeff		PROC_SUNLOCK(p);
284170297Sjeff	}
285170297Sjeff	thread_lock(td);
286170297Sjeff	sched_tick();
287172207Sjeff	td->td_flags |= flags;
288170297Sjeff	thread_unlock(td);
289146799Sjkoshy
290146799Sjkoshy#ifdef	HWPMC_HOOKS
291146799Sjkoshy	if (PMC_CPU_HAS_SAMPLES(PCPU_GET(cpuid)))
292146799Sjkoshy		PMC_CALL_HOOK_UNLOCKED(curthread, PMC_FN_DO_SAMPLES, NULL);
293146799Sjkoshy#endif
29476078Sjhb}
29576078Sjhb
29676078Sjhb/*
2971541Srgrimes * The real-time timer, interrupting hz times per second.
2981541Srgrimes */
2991541Srgrimesvoid
300153666Sjhbhardclock(int usermode, uintfptr_t pc)
3011541Srgrimes{
30268889Sjake	int need_softclock = 0;
3031541Srgrimes
304153666Sjhb	hardclock_cpu(usermode);
3051541Srgrimes
306102926Sphk	tc_ticktock();
3071541Srgrimes	/*
3081541Srgrimes	 * If no separate statistics clock is available, run it from here.
30976078Sjhb	 *
31076078Sjhb	 * XXX: this only works for UP
3111541Srgrimes	 */
312110296Sjake	if (stathz == 0) {
313153666Sjhb		profclock(usermode, pc);
314153666Sjhb		statclock(usermode);
315110296Sjake	}
3161541Srgrimes
31787902Sluigi#ifdef DEVICE_POLLING
31890550Sluigi	hardclock_device_poll();	/* this is very short and quick */
31987902Sluigi#endif /* DEVICE_POLLING */
3202858Swollman
32134618Sphk	/*
32234618Sphk	 * Process callouts at a very low cpu priority, so we don't keep the
32334618Sphk	 * relatively high clock interrupt priority any longer than necessary.
32434618Sphk	 */
32586423Sjhb	mtx_lock_spin_flags(&callout_lock, MTX_QUIET);
32668889Sjake	ticks++;
327159598Sdelphij	if (!TAILQ_EMPTY(&callwheel[ticks & callwheelmask])) {
32868889Sjake		need_softclock = 1;
32934618Sphk	} else if (softticks + 1 == ticks)
33034618Sphk		++softticks;
33186423Sjhb	mtx_unlock_spin_flags(&callout_lock, MTX_QUIET);
33268889Sjake
33368889Sjake	/*
334170297Sjeff	 * swi_sched acquires the thread lock, so we don't want to call it
335170297Sjeff	 * with callout_lock held; incorrect locking order.
33668889Sjake	 */
33768889Sjake	if (need_softclock)
33888900Sjhb		swi_sched(softclock_ih, 0);
339116874Ssmkelly
340126383Sphk#ifdef SW_WATCHDOG
341126383Sphk	if (watchdog_enabled > 0 && --watchdog_ticks <= 0)
342116874Ssmkelly		watchdog_fire();
343126383Sphk#endif /* SW_WATCHDOG */
3441541Srgrimes}
3451541Srgrimes
3461541Srgrimes/*
34734961Sphk * Compute number of ticks in the specified amount of time.
3481541Srgrimes */
3491541Srgrimesint
35034961Sphktvtohz(tv)
3511541Srgrimes	struct timeval *tv;
3521541Srgrimes{
3535081Sbde	register unsigned long ticks;
3545081Sbde	register long sec, usec;
3551541Srgrimes
3561541Srgrimes	/*
3575081Sbde	 * If the number of usecs in the whole seconds part of the time
3585081Sbde	 * difference fits in a long, then the total number of usecs will
3595081Sbde	 * fit in an unsigned long.  Compute the total and convert it to
3605081Sbde	 * ticks, rounding up and adding 1 to allow for the current tick
3615081Sbde	 * to expire.  Rounding also depends on unsigned long arithmetic
3625081Sbde	 * to avoid overflow.
3631541Srgrimes	 *
3645081Sbde	 * Otherwise, if the number of ticks in the whole seconds part of
3655081Sbde	 * the time difference fits in a long, then convert the parts to
3665081Sbde	 * ticks separately and add, using similar rounding methods and
3675081Sbde	 * overflow avoidance.  This method would work in the previous
3685081Sbde	 * case but it is slightly slower and assumes that hz is integral.
3695081Sbde	 *
3705081Sbde	 * Otherwise, round the time difference down to the maximum
3715081Sbde	 * representable value.
3725081Sbde	 *
3735081Sbde	 * If ints have 32 bits, then the maximum value for any timeout in
3745081Sbde	 * 10ms ticks is 248 days.
3751541Srgrimes	 */
37634961Sphk	sec = tv->tv_sec;
37734961Sphk	usec = tv->tv_usec;
3785081Sbde	if (usec < 0) {
3795081Sbde		sec--;
3805081Sbde		usec += 1000000;
3815081Sbde	}
3825081Sbde	if (sec < 0) {
3835081Sbde#ifdef DIAGNOSTIC
38434618Sphk		if (usec > 0) {
38533690Sphk			sec++;
38633690Sphk			usec -= 1000000;
38733690Sphk		}
38834961Sphk		printf("tvotohz: negative time difference %ld sec %ld usec\n",
3895081Sbde		       sec, usec);
3905081Sbde#endif
3915081Sbde		ticks = 1;
3925081Sbde	} else if (sec <= LONG_MAX / 1000000)
3935081Sbde		ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
3945081Sbde			/ tick + 1;
3955081Sbde	else if (sec <= LONG_MAX / hz)
3965081Sbde		ticks = sec * hz
3975081Sbde			+ ((unsigned long)usec + (tick - 1)) / tick + 1;
3981541Srgrimes	else
3995081Sbde		ticks = LONG_MAX;
4005081Sbde	if (ticks > INT_MAX)
4015081Sbde		ticks = INT_MAX;
40240012Salex	return ((int)ticks);
4031541Srgrimes}
4041541Srgrimes
4051541Srgrimes/*
4061541Srgrimes * Start profiling on a process.
4071541Srgrimes *
4081541Srgrimes * Kernel profiling passes proc0 which never exits and hence
4091541Srgrimes * keeps the profile clock running constantly.
4101541Srgrimes */
4111541Srgrimesvoid
4121541Srgrimesstartprofclock(p)
4131541Srgrimes	register struct proc *p;
4141541Srgrimes{
4151541Srgrimes
416113874Sjhb	PROC_LOCK_ASSERT(p, MA_OWNED);
417113874Sjhb	if (p->p_flag & P_STOPPROF)
418110530Sjulian		return;
419113874Sjhb	if ((p->p_flag & P_PROFIL) == 0) {
420113874Sjhb		p->p_flag |= P_PROFIL;
421169803Sjeff		mtx_lock_spin(&time_lock);
422110296Sjake		if (++profprocs == 1)
423110296Sjake			cpu_startprofclock();
424169803Sjeff		mtx_unlock_spin(&time_lock);
4251541Srgrimes	}
4261541Srgrimes}
4271541Srgrimes
4281541Srgrimes/*
4291541Srgrimes * Stop profiling on a process.
4301541Srgrimes */
4311541Srgrimesvoid
4321541Srgrimesstopprofclock(p)
4331541Srgrimes	register struct proc *p;
4341541Srgrimes{
4351541Srgrimes
436110530Sjulian	PROC_LOCK_ASSERT(p, MA_OWNED);
437113874Sjhb	if (p->p_flag & P_PROFIL) {
438113874Sjhb		if (p->p_profthreads != 0) {
439113874Sjhb			p->p_flag |= P_STOPPROF;
440113874Sjhb			while (p->p_profthreads != 0)
441113874Sjhb				msleep(&p->p_profthreads, &p->p_mtx, PPAUSE,
442123740Speter				    "stopprof", 0);
443113874Sjhb			p->p_flag &= ~P_STOPPROF;
444110530Sjulian		}
445128852Scperciva		if ((p->p_flag & P_PROFIL) == 0)
446128852Scperciva			return;
447113874Sjhb		p->p_flag &= ~P_PROFIL;
448169803Sjeff		mtx_lock_spin(&time_lock);
449110296Sjake		if (--profprocs == 0)
450110296Sjake			cpu_stopprofclock();
451169803Sjeff		mtx_unlock_spin(&time_lock);
4521541Srgrimes	}
4531541Srgrimes}
4541541Srgrimes
4551541Srgrimes/*
456170174Sjeff * Statistics clock.  Updates rusage information and calls the scheduler
457170174Sjeff * to adjust priorities of the active thread.
458170174Sjeff *
459110296Sjake * This should be called by all active processors.
4601541Srgrimes */
4611541Srgrimesvoid
462153666Sjhbstatclock(int usermode)
4631541Srgrimes{
46417342Sbde	struct rusage *ru;
46517342Sbde	struct vmspace *vm;
466110296Sjake	struct thread *td;
467110296Sjake	struct proc *p;
468110296Sjake	long rss;
469174070Speter	long *cp_time;
4701541Srgrimes
471110296Sjake	td = curthread;
472110296Sjake	p = td->td_proc;
473110296Sjake
474174070Speter	cp_time = (long *)PCPU_PTR(cp_time);
475153666Sjhb	if (usermode) {
47653751Sbde		/*
47753751Sbde		 * Charge the time as appropriate.
4781541Srgrimes		 */
479163709Sjb#ifdef KSE
480116361Sdavidxu		if (p->p_flag & P_SA)
481111028Sjeff			thread_statclock(1);
482163709Sjb#endif
483155534Sphk		td->td_uticks++;
484130551Sjulian		if (p->p_nice > NZERO)
485174070Speter			cp_time[CP_NICE]++;
4861541Srgrimes		else
487174070Speter			cp_time[CP_USER]++;
4881541Srgrimes	} else {
4891541Srgrimes		/*
4901541Srgrimes		 * Came from kernel mode, so we were:
4911541Srgrimes		 * - handling an interrupt,
4921541Srgrimes		 * - doing syscall or trap work on behalf of the current
4931541Srgrimes		 *   user process, or
4941541Srgrimes		 * - spinning in the idle loop.
4951541Srgrimes		 * Whichever it is, charge the time as appropriate.
4961541Srgrimes		 * Note that we charge interrupts to the current process,
4971541Srgrimes		 * regardless of whether they are ``for'' that process,
4981541Srgrimes		 * so that we know how much of its real time was spent
4991541Srgrimes		 * in ``non-process'' (i.e., interrupt) work.
5001541Srgrimes		 */
501151658Sjhb		if ((td->td_pflags & TDP_ITHREAD) ||
502151658Sjhb		    td->td_intr_nesting_level >= 2) {
503155534Sphk			td->td_iticks++;
504174070Speter			cp_time[CP_INTR]++;
50565557Sjasone		} else {
506163709Sjb#ifdef KSE
507116361Sdavidxu			if (p->p_flag & P_SA)
508111028Sjeff				thread_statclock(0);
509163709Sjb#endif
510155455Sphk			td->td_pticks++;
511155534Sphk			td->td_sticks++;
512167327Sjulian			if (!TD_IS_IDLETHREAD(td))
513174070Speter				cp_time[CP_SYS]++;
51465557Sjasone			else
515174070Speter				cp_time[CP_IDLE]++;
51665557Sjasone		}
5171541Srgrimes	}
5181541Srgrimes
51965782Sjhb	/* Update resource usage integrals and maximums. */
520131436Sjhb	MPASS(p->p_vmspace != NULL);
521131436Sjhb	vm = p->p_vmspace;
522170174Sjeff	ru = &td->td_ru;
523131436Sjhb	ru->ru_ixrss += pgtok(vm->vm_tsize);
524131436Sjhb	ru->ru_idrss += pgtok(vm->vm_dsize);
525131436Sjhb	ru->ru_isrss += pgtok(vm->vm_ssize);
526131436Sjhb	rss = pgtok(vmspace_resident_count(vm));
527131436Sjhb	if (ru->ru_maxrss < rss)
528131436Sjhb		ru->ru_maxrss = rss;
529170297Sjeff	CTR4(KTR_SCHED, "statclock: %p(%s) prio %d stathz %d",
530173600Sjulian	    td, td->td_name, td->td_priority, (stathz)?stathz:hz);
531174070Speter	thread_lock_flags(td, MTX_QUIET);
532170297Sjeff	sched_clock(td);
533170297Sjeff	thread_unlock(td);
53476078Sjhb}
53566716Sjhb
53676078Sjhbvoid
537153666Sjhbprofclock(int usermode, uintfptr_t pc)
53876078Sjhb{
539110296Sjake	struct thread *td;
540110296Sjake#ifdef GPROF
541110296Sjake	struct gmonparam *g;
542153490Sjhb	uintfptr_t i;
543110296Sjake#endif
54476078Sjhb
545111032Sjulian	td = curthread;
546153666Sjhb	if (usermode) {
547110296Sjake		/*
548110296Sjake		 * Came from user mode; CPU was in user state.
549110296Sjake		 * If this process is being profiled, record the tick.
550110530Sjulian		 * if there is no related user location yet, don't
551110530Sjulian		 * bother trying to count it.
552110296Sjake		 */
553113874Sjhb		if (td->td_proc->p_flag & P_PROFIL)
554153666Sjhb			addupc_intr(td, pc, 1);
555110296Sjake	}
556110296Sjake#ifdef GPROF
557110296Sjake	else {
558110296Sjake		/*
559110296Sjake		 * Kernel statistics are just like addupc_intr, only easier.
560110296Sjake		 */
561110296Sjake		g = &_gmonparam;
562153666Sjhb		if (g->state == GMON_PROF_ON && pc >= g->lowpc) {
563153666Sjhb			i = PC_TO_I(g, pc);
564110296Sjake			if (i < g->textsize) {
565153666Sjhb				KCOUNT(g, i)++;
566110296Sjake			}
567110296Sjake		}
568110296Sjake	}
569110296Sjake#endif
5701541Srgrimes}
5711541Srgrimes
5721541Srgrimes/*
5731541Srgrimes * Return information about system clocks.
5741541Srgrimes */
57512152Sphkstatic int
57662573Sphksysctl_kern_clockrate(SYSCTL_HANDLER_ARGS)
5771541Srgrimes{
5781541Srgrimes	struct clockinfo clkinfo;
5791541Srgrimes	/*
5801541Srgrimes	 * Construct clockinfo structure.
5811541Srgrimes	 */
58296052Sbde	bzero(&clkinfo, sizeof(clkinfo));
5831541Srgrimes	clkinfo.hz = hz;
5841541Srgrimes	clkinfo.tick = tick;
5851541Srgrimes	clkinfo.profhz = profhz;
5861541Srgrimes	clkinfo.stathz = stathz ? stathz : hz;
58712243Sphk	return (sysctl_handle_opaque(oidp, &clkinfo, sizeof clkinfo, req));
5881541Srgrimes}
5892858Swollman
59012623SphkSYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, CTLTYPE_STRUCT|CTLFLAG_RD,
59188019Sluigi	0, 0, sysctl_kern_clockrate, "S,clockinfo",
59288019Sluigi	"Rate and period of various kernel clocks");
593116874Ssmkelly
594126383Sphk#ifdef SW_WATCHDOG
595126383Sphk
596126383Sphkstatic void
597165260Sn_hibmawatchdog_config(void *unused __unused, u_int cmd, int *error)
598116874Ssmkelly{
599126383Sphk	u_int u;
600116874Ssmkelly
601126386Sphk	u = cmd & WD_INTERVAL;
602165260Sn_hibma	if (u >= WD_TO_1SEC) {
603126383Sphk		watchdog_ticks = (1 << (u - WD_TO_1SEC)) * hz;
604126383Sphk		watchdog_enabled = 1;
605165260Sn_hibma		*error = 0;
606126383Sphk	} else {
607126383Sphk		watchdog_enabled = 0;
608126383Sphk	}
609116874Ssmkelly}
610116874Ssmkelly
611116874Ssmkelly/*
612116874Ssmkelly * Handle a watchdog timeout by dumping interrupt information and
613170075Semaste * then either dropping to DDB or panicking.
614116874Ssmkelly */
615116874Ssmkellystatic void
616116874Ssmkellywatchdog_fire(void)
617116874Ssmkelly{
618116874Ssmkelly	int nintr;
619116874Ssmkelly	u_int64_t inttotal;
620116874Ssmkelly	u_long *curintr;
621116874Ssmkelly	char *curname;
622116874Ssmkelly
623116874Ssmkelly	curintr = intrcnt;
624116874Ssmkelly	curname = intrnames;
625116874Ssmkelly	inttotal = 0;
626116874Ssmkelly	nintr = eintrcnt - intrcnt;
627157822Sjhb
628116874Ssmkelly	printf("interrupt                   total\n");
629116874Ssmkelly	while (--nintr >= 0) {
630116874Ssmkelly		if (*curintr)
631116874Ssmkelly			printf("%-12s %20lu\n", curname, *curintr);
632116874Ssmkelly		curname += strlen(curname) + 1;
633116874Ssmkelly		inttotal += *curintr++;
634116874Ssmkelly	}
635116908Ssmkelly	printf("Total        %20ju\n", (uintmax_t)inttotal);
636170075Semaste
637170075Semaste#if defined(KDB) && !defined(KDB_UNATTENDED)
638170075Semaste	kdb_backtrace();
639170075Semaste	kdb_enter("watchdog timeout");
640170075Semaste#else
641116874Ssmkelly	panic("watchdog timeout");
642170075Semaste#endif
643116874Ssmkelly}
644116874Ssmkelly
645126383Sphk#endif /* SW_WATCHDOG */
646