Module Name: src Committed By: mrg Date: Tue May 17 04:18:07 UTC 2011
Modified Files: src/sys/arch/sparc64/conf: GENERIC src/sys/conf: files src/sys/ddb: db_command.c src/sys/dev/ic: sl811hs.c src/sys/uvm: uvm.h uvm_ddb.h uvm_map.c uvm_stat.c uvm_stat.h src/usr.bin/vmstat: vmstat.c Added Files: src/sys/kern: kern_history.c src/sys/sys: kernhist.h Log Message: move and rename the uvm history code out of uvm_stat to "kernhist". rename "UVMHIST" option to enable the uvm histories. TODO: - make UVMHIST properly depend upon KERNHIST - enable dynamic registration of histories. this is mostly just allocating something in a bitmap, and is only for viewing multiple histories in a merged form. tested on amd64 and sparc64. To generate a diff of this commit: cvs rdiff -u -r1.137 -r1.138 src/sys/arch/sparc64/conf/GENERIC cvs rdiff -u -r1.1011 -r1.1012 src/sys/conf/files cvs rdiff -u -r1.135 -r1.136 src/sys/ddb/db_command.c cvs rdiff -u -r1.27 -r1.28 src/sys/dev/ic/sl811hs.c cvs rdiff -u -r0 -r1.1 src/sys/kern/kern_history.c cvs rdiff -u -r0 -r1.1 src/sys/sys/kernhist.h cvs rdiff -u -r1.61 -r1.62 src/sys/uvm/uvm.h cvs rdiff -u -r1.14 -r1.15 src/sys/uvm/uvm_ddb.h cvs rdiff -u -r1.296 -r1.297 src/sys/uvm/uvm_map.c cvs rdiff -u -r1.36 -r1.37 src/sys/uvm/uvm_stat.c cvs rdiff -u -r1.49 -r1.50 src/sys/uvm/uvm_stat.h cvs rdiff -u -r1.180 -r1.181 src/usr.bin/vmstat/vmstat.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc64/conf/GENERIC diff -u src/sys/arch/sparc64/conf/GENERIC:1.137 src/sys/arch/sparc64/conf/GENERIC:1.138 --- src/sys/arch/sparc64/conf/GENERIC:1.137 Thu May 12 07:06:00 2011 +++ src/sys/arch/sparc64/conf/GENERIC Tue May 17 04:18:05 2011 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.137 2011/05/12 07:06:00 mrg Exp $ +# $NetBSD: GENERIC,v 1.138 2011/05/17 04:18:05 mrg Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.137 $" +#ident "GENERIC-$Revision: 1.138 $" maxusers 64 @@ -99,7 +99,7 @@ ## Compile the kernel with debugging symbols (`netbsd.gdb' is the debug file), ## such that gdb(1) can be used on a kernel coredump. -#makeoptions DEBUG="-g" +makeoptions DEBUG="-g" ## Adds code to the kernel that does internal consistency checks, and will Index: src/sys/conf/files diff -u src/sys/conf/files:1.1011 src/sys/conf/files:1.1012 --- src/sys/conf/files:1.1011 Thu May 5 17:38:35 2011 +++ src/sys/conf/files Tue May 17 04:18:06 2011 @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.1011 2011/05/05 17:38:35 drochner Exp $ +# $NetBSD: files,v 1.1012 2011/05/17 04:18:06 mrg Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20100430 @@ -1384,6 +1384,13 @@ include "uvm/files.uvm" # +# Kernel history/tracing. Old UVMHIST depends upon this. +# XXXMRG can't make UVMHIST depend properly on KERNHIST? +# +defflag opt_kernhist.h KERNHIST KERNHIST_PRINT +file kern/kern_history.c kernhist + +# # Security models # include "secmodel/files.secmodel" Index: src/sys/ddb/db_command.c diff -u src/sys/ddb/db_command.c:1.135 src/sys/ddb/db_command.c:1.136 --- src/sys/ddb/db_command.c:1.135 Sun Apr 10 20:59:22 2011 +++ src/sys/ddb/db_command.c Tue May 17 04:18:06 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: db_command.c,v 1.135 2011/04/10 20:59:22 christos Exp $ */ +/* $NetBSD: db_command.c,v 1.136 2011/05/17 04:18:06 mrg Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 1999, 2002, 2009 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.135 2011/04/10 20:59:22 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.136 2011/05/17 04:18:06 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_aio.h" @@ -68,7 +68,7 @@ #include "opt_kgdb.h" #include "opt_mqueue.h" #include "opt_inet.h" -#include "opt_uvmhist.h" +#include "opt_kernhist.h" #include "opt_ddbparam.h" #include "opt_multiprocessor.h" #include "arp.h" @@ -90,6 +90,7 @@ #include <sys/cpu.h> #include <sys/buf.h> #include <sys/module.h> +#include <sys/kernhist.h> /*include queue macros*/ #include <sys/queue.h> @@ -205,8 +206,8 @@ static void db_sync_cmd(db_expr_t, bool, db_expr_t, const char *); static void db_whatis_cmd(db_expr_t, bool, db_expr_t, const char *); static void db_uvmexp_print_cmd(db_expr_t, bool, db_expr_t, const char *); -#ifdef UVMHIST -static void db_uvmhist_print_cmd(db_expr_t, bool, db_expr_t, const char *); +#ifdef KERNHIST +static void db_kernhist_print_cmd(db_expr_t, bool, db_expr_t, const char *); #endif static void db_vnode_print_cmd(db_expr_t, bool, db_expr_t, const char *); static void db_vmem_print_cmd(db_expr_t, bool, db_expr_t, const char *); @@ -276,8 +277,8 @@ { DDB_ADD_CMD("uvmexp", db_uvmexp_print_cmd, 0, "Print a selection of UVM counters and statistics.", NULL,NULL) }, -#ifdef UVMHIST - { DDB_ADD_CMD("uvmhist", db_uvmhist_print_cmd, 0, +#ifdef KERNHIST + { DDB_ADD_CMD("kernhist", db_kernhist_print_cmd, 0, "Print the UVM history logs.", NULL,NULL) }, #endif @@ -1197,14 +1198,14 @@ #endif } -#ifdef UVMHIST +#ifdef KERNHIST /*ARGSUSED*/ static void -db_uvmhist_print_cmd(db_expr_t addr, bool have_addr, +db_kernhist_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { - uvmhist_print(db_printf); + kernhist_print(db_printf); } #endif Index: src/sys/dev/ic/sl811hs.c diff -u src/sys/dev/ic/sl811hs.c:1.27 src/sys/dev/ic/sl811hs.c:1.28 --- src/sys/dev/ic/sl811hs.c:1.27 Sun Mar 13 05:26:14 2011 +++ src/sys/dev/ic/sl811hs.c Tue May 17 04:18:06 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: sl811hs.c,v 1.27 2011/03/13 05:26:14 kiyohara Exp $ */ +/* $NetBSD: sl811hs.c,v 1.28 2011/05/17 04:18:06 mrg Exp $ */ /* * Not (c) 2007 Matthew Orgass @@ -84,7 +84,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.27 2011/03/13 05:26:14 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.28 2011/05/17 04:18:06 mrg Exp $"); #include "opt_slhci.h" @@ -561,35 +561,42 @@ int slhci_usbdebug = -1; /* value to set usbdebug on attach, -1 = leave alone */ #endif -/* Add UVMHIST history for debugging: +/* + * XXXMRG the SLHCI UVMHIST code has been converted to KERNHIST, but it has + * not been tested. the extra instructions to enable it can probably be + * commited to the kernhist code, and these instructions reduced to simply + * enabling SLHCI_DEBUG. + */ + +/* Add KERNHIST history for debugging: * - * Before uvm_hist in sys/uvm/uvm_stat.c add: - * UVMHIST_DECL(slhcihist); + * Before kern_hist in sys/kern/subr_kernhist.c add: + * KERNHIST_DECL(slhcihist); * - * In uvm_hist add: - * if ((bitmask & UVMHIST_SLHCI)) + * In kern_hist add: + * if ((bitmask & KERNHIST_SLHCI)) * hists[i++] = &slhcihist; * - * In sys/uvm/uvm_stat.h add UVMHIST_SLHCI define. + * In sys/sys/kernhist.h add KERNHIST_SLHCI define. */ -#include <uvm/uvm_stat.h> -UVMHIST_DECL(slhcihist); +#include <sys/kernhist.h> +KERNHIST_DECL(slhcihist); -#if !defined(UVMHIST) || !defined(UVMHIST_SLHCI) -#error "SLHCI_DEBUG requires UVMHIST (with modifications, see sys/dev/ic/sl81hs.c)" +#if !defined(KERNHIST) || !defined(KERNHIST_SLHCI) +#error "SLHCI_DEBUG requires KERNHIST (with modifications, see sys/dev/ic/sl81hs.c)" #endif #ifndef SLHCI_NHIST #define SLHCI_NHIST 409600 #endif -const unsigned int SLHCI_HISTMASK = UVMHIST_SLHCI; -struct uvm_history_ent slhci_he[SLHCI_NHIST]; +const unsigned int SLHCI_HISTMASK = KERNHIST_SLHCI; +struct kern_history_ent slhci_he[SLHCI_NHIST]; #define SLHCI_DEXEC(x, y) do { if ((slhci_debug & SLHCI_ ## x)) { y; } \ } while (/*CONSTCOND*/ 0) -#define DDOLOG(f, a, b, c, d) do { const char *_uvmhist_name = __func__; \ - u_long _uvmhist_call = 0; UVMHIST_LOG(slhcihist, f, a, b, c, d); \ +#define DDOLOG(f, a, b, c, d) do { const char *_kernhist_name = __func__; \ + u_long _kernhist_call = 0; KERNHIST_LOG(slhcihist, f, a, b, c, d); \ } while (/*CONSTCOND*/0) #define DLOG(x, f, a, b, c, d) SLHCI_DEXEC(x, DDOLOG(f, a, b, c, d)) /* DLOGFLAG8 is a macro not a function so that flag name expressions are not @@ -597,10 +604,10 @@ * x is debug mask, y is flag identifier, z is flag variable, * a-h are flag names (must evaluate to string constants, msb first). */ #define DDOLOGFLAG8(y, z, a, b, c, d, e, f, g, h) do { uint8_t _DLF8 = (z); \ - const char *_uvmhist_name = __func__; u_long _uvmhist_call = 0; \ - if (_DLF8 & 0xf0) UVMHIST_LOG(slhcihist, y " %s %s %s %s", _DLF8 & 0x80 ? \ + const char *_kernhist_name = __func__; u_long _kernhist_call = 0; \ + if (_DLF8 & 0xf0) KERNHIST_LOG(slhcihist, y " %s %s %s %s", _DLF8 & 0x80 ? \ (a) : "", _DLF8 & 0x40 ? (b) : "", _DLF8 & 0x20 ? (c) : "", _DLF8 & 0x10 ? \ - (d) : ""); if (_DLF8 & 0x0f) UVMHIST_LOG(slhcihist, y " %s %s %s %s", \ + (d) : ""); if (_DLF8 & 0x0f) KERNHIST_LOG(slhcihist, y " %s %s %s %s", \ _DLF8 & 0x08 ? (e) : "", _DLF8 & 0x04 ? (f) : "", _DLF8 & 0x02 ? (g) : "", \ _DLF8 & 0x01 ? (h) : ""); \ } while (/*CONSTCOND*/ 0) @@ -1143,7 +1150,7 @@ t = &sc->sc_transfers; #ifdef SLHCI_DEBUG - UVMHIST_INIT_STATIC(slhcihist, slhci_he); + KERNHIST_INIT_STATIC(slhcihist, slhci_he); #endif simple_lock_init(&sc->sc_lock); #ifdef SLHCI_WAITLOCK Index: src/sys/uvm/uvm.h diff -u src/sys/uvm/uvm.h:1.61 src/sys/uvm/uvm.h:1.62 --- src/sys/uvm/uvm.h:1.61 Wed Feb 2 17:53:42 2011 +++ src/sys/uvm/uvm.h Tue May 17 04:18:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm.h,v 1.61 2011/02/02 17:53:42 chuck Exp $ */ +/* $NetBSD: uvm.h,v 1.62 2011/05/17 04:18:07 mrg Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -39,7 +39,9 @@ #include <uvm/uvm_extern.h> +#ifdef _KERNEL #include <uvm/uvm_stat.h> +#endif /* * pull in prototypes Index: src/sys/uvm/uvm_ddb.h diff -u src/sys/uvm/uvm_ddb.h:1.14 src/sys/uvm/uvm_ddb.h:1.15 --- src/sys/uvm/uvm_ddb.h:1.14 Wed Feb 2 15:13:34 2011 +++ src/sys/uvm/uvm_ddb.h Tue May 17 04:18:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_ddb.h,v 1.14 2011/02/02 15:13:34 chuck Exp $ */ +/* $NetBSD: uvm_ddb.h,v 1.15 2011/05/17 04:18:07 mrg Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -41,7 +41,6 @@ void (*)(const char *, ...)); void uvm_page_printall(void (*)(const char *, ...)); void uvmexp_print(void (*)(const char *, ...)); -void uvmhist_print(void (*)(const char *, ...)); #endif /* DDB || DEBUGPRINT */ #endif /* _KERNEL */ Index: src/sys/uvm/uvm_map.c diff -u src/sys/uvm/uvm_map.c:1.296 src/sys/uvm/uvm_map.c:1.297 --- src/sys/uvm/uvm_map.c:1.296 Fri Apr 8 10:38:36 2011 +++ src/sys/uvm/uvm_map.c Tue May 17 04:18:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_map.c,v 1.296 2011/04/08 10:38:36 yamt Exp $ */ +/* $NetBSD: uvm_map.c,v 1.297 2011/05/17 04:18:07 mrg Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.296 2011/04/08 10:38:36 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.297 2011/05/17 04:18:07 mrg Exp $"); #include "opt_ddb.h" #include "opt_uvmhist.h" @@ -1013,8 +1013,8 @@ uvm_map_init(void) { #if defined(UVMHIST) - static struct uvm_history_ent maphistbuf[100]; - static struct uvm_history_ent pdhistbuf[100]; + static struct kern_history_ent maphistbuf[100]; + static struct kern_history_ent pdhistbuf[100]; #endif /* Index: src/sys/uvm/uvm_stat.c diff -u src/sys/uvm/uvm_stat.c:1.36 src/sys/uvm/uvm_stat.c:1.37 --- src/sys/uvm/uvm_stat.c:1.36 Wed Feb 2 15:13:34 2011 +++ src/sys/uvm/uvm_stat.c Tue May 17 04:18:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_stat.c,v 1.36 2011/02/02 15:13:34 chuck Exp $ */ +/* $NetBSD: uvm_stat.c,v 1.37 2011/05/17 04:18:07 mrg Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -32,9 +32,8 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_stat.c,v 1.36 2011/02/02 15:13:34 chuck Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_stat.c,v 1.37 2011/05/17 04:18:07 mrg Exp $"); -#include "opt_uvmhist.h" #include "opt_readahead.h" #include "opt_ddb.h" @@ -45,157 +44,9 @@ #include <uvm/uvm.h> #include <uvm/uvm_ddb.h> -/* - * globals - */ - -#ifdef UVMHIST -struct uvm_history_head uvm_histories; -#endif - -#ifdef UVMHIST_PRINT -int uvmhist_print_enabled = 1; -#endif - #ifdef DDB /* - * prototypes - */ - -#ifdef UVMHIST -void uvmhist_dump(struct uvm_history *); -void uvm_hist(u_int32_t); -static void uvmhist_dump_histories(struct uvm_history *[]); -#endif -void uvmcnt_dump(void); - - -#ifdef UVMHIST -/* call this from ddb */ -void -uvmhist_dump(struct uvm_history *l) -{ - int lcv, s; - - s = splhigh(); - lcv = l->f; - do { - if (l->e[lcv].fmt) - uvmhist_entry_print(&l->e[lcv]); - lcv = (lcv + 1) % l->n; - } while (lcv != l->f); - splx(s); -} - -/* - * print a merged list of uvm_history structures - */ -static void -uvmhist_dump_histories(struct uvm_history *hists[]) -{ - struct timeval tv; - int cur[MAXHISTS]; - int s, lcv, hi; - - /* so we don't get corrupted lists! */ - s = splhigh(); - - /* find the first of each list */ - for (lcv = 0; hists[lcv]; lcv++) - cur[lcv] = hists[lcv]->f; - - /* - * here we loop "forever", finding the next earliest - * history entry and printing it. cur[X] is the current - * entry to test for the history in hists[X]. if it is - * -1, then this history is finished. - */ - for (;;) { - hi = -1; - tv.tv_sec = tv.tv_usec = 0; - - /* loop over each history */ - for (lcv = 0; hists[lcv]; lcv++) { -restart: - if (cur[lcv] == -1) - continue; - - /* - * if the format is empty, go to the next entry - * and retry. - */ - if (hists[lcv]->e[cur[lcv]].fmt == NULL) { - cur[lcv] = (cur[lcv] + 1) % (hists[lcv]->n); - if (cur[lcv] == hists[lcv]->f) - cur[lcv] = -1; - goto restart; - } - - /* - * if the time hasn't been set yet, or this entry is - * earlier than the current tv, set the time and history - * index. - */ - if (tv.tv_sec == 0 || - timercmp(&hists[lcv]->e[cur[lcv]].tv, &tv, <)) { - tv = hists[lcv]->e[cur[lcv]].tv; - hi = lcv; - } - } - - /* if we didn't find any entries, we must be done */ - if (hi == -1) - break; - - /* print and move to the next entry */ - uvmhist_entry_print(&hists[hi]->e[cur[hi]]); - cur[hi] = (cur[hi] + 1) % (hists[hi]->n); - if (cur[hi] == hists[hi]->f) - cur[hi] = -1; - } - splx(s); -} - -/* - * call this from ddb. `bitmask' is from <uvm/uvm_stat.h>. it - * merges the named histories. - */ -void -uvm_hist(u_int32_t bitmask) /* XXX only support 32 hists */ -{ - struct uvm_history *hists[MAXHISTS + 1]; - int i = 0; - - if ((bitmask & UVMHIST_MAPHIST) || bitmask == 0) - hists[i++] = &maphist; - - if ((bitmask & UVMHIST_PDHIST) || bitmask == 0) - hists[i++] = &pdhist; - - if ((bitmask & UVMHIST_UBCHIST) || bitmask == 0) - hists[i++] = &ubchist; - - if ((bitmask & UVMHIST_LOANHIST) || bitmask == 0) - hists[i++] = &loanhist; - - hists[i] = NULL; - - uvmhist_dump_histories(hists); -} - -/* - * uvmhist_print: ddb hook to print uvm history - */ -void -uvmhist_print(void (*pr)(const char *, ...)) -{ - uvmhist_dump(LIST_FIRST(&uvm_histories)); -} - -#endif /* UVMHIST */ - -/* * uvmexp_print: ddb hook to print interesting uvm counters */ void Index: src/sys/uvm/uvm_stat.h diff -u src/sys/uvm/uvm_stat.h:1.49 src/sys/uvm/uvm_stat.h:1.50 --- src/sys/uvm/uvm_stat.h:1.49 Sat Apr 23 18:14:13 2011 +++ src/sys/uvm/uvm_stat.h Tue May 17 04:18:07 2011 @@ -1,7 +1,7 @@ -/* $NetBSD: uvm_stat.h,v 1.49 2011/04/23 18:14:13 rmind Exp $ */ +/* $NetBSD: uvm_stat.h,v 1.50 2011/05/17 04:18:07 mrg Exp $ */ /* - * Copyright (c) 1997 Charles D. Cranor and Washington University. + * Copyright (c) 2011 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -12,19 +12,24 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * from: Id: uvm_stat.h,v 1.1.2.4 1998/02/07 01:16:56 chs Exp + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Backwards compat for UVMHIST, in the new KERNHIST form. */ #ifndef _UVM_UVM_STAT_H_ @@ -32,162 +37,36 @@ #if defined(_KERNEL_OPT) #include "opt_uvmhist.h" +#include "opt_kernhist.h" #endif -#include <sys/queue.h> -#ifdef UVMHIST -#include <sys/cpu.h> -#endif - -/* - * uvm_stat: monitor what is going on with uvm (or whatever) - */ - /* - * history/tracing + * Make UVMHIST_PRINT force on KERNHIST_PRINT for at least UVMHIST_* usage. */ +#if defined(UVMHIST_PRINT) && !defined(KERNHIST_PRINT) +#define KERNHIST_PRINT 1 +#endif -struct uvm_history_ent { - struct timeval tv; /* time stamp */ - int cpunum; - const char *fmt; /* printf format */ - size_t fmtlen; /* length of printf format */ - const char *fn; /* function name */ - size_t fnlen; /* length of function name */ - u_long call; /* function call number */ - u_long v[4]; /* values */ -}; - -struct uvm_history { - const char *name; /* name of this history */ - size_t namelen; /* length of name, not including null */ - LIST_ENTRY(uvm_history) list; /* link on list of all histories */ - unsigned int n; /* number of entries */ - unsigned int f; /* next free one */ - struct uvm_history_ent *e; /* the allocated entries */ -}; - -LIST_HEAD(uvm_history_head, uvm_history); - -/* - * grovelling lists all at once. we currently do not allow more than - * 32 histories to exist, as the way to dump a number of them at once - * is by calling uvm_hist() with a bitmask. - */ +#include <sys/kernhist.h> -/* this is used to set the size of some arrays */ -#define MAXHISTS 32 /* do not change this! */ +#ifdef UVMHIST -/* and these are the bit values of each history */ -#define UVMHIST_MAPHIST 0x00000001 /* maphist */ -#define UVMHIST_PDHIST 0x00000002 /* pdhist */ -#define UVMHIST_UBCHIST 0x00000004 /* ubchist */ -#define UVMHIST_LOANHIST 0x00000008 /* loanhist */ +#define UVMHIST_DECL(NAME) KERNHIST_DECL(NAME) +#define UVMHIST_INIT(NAME,N) KERNHIST_INIT(NAME,N) +#define UVMHIST_INIT_STATIC(NAME,BUF) KERNHIST_INIT_STATIC(NAME,BUF) +#define UVMHIST_LOG(NAME,FMT,A,B,C,D) KERNHIST_LOG(NAME,FMT,A,B,C,D) +#define UVMHIST_CALLED(NAME) KERNHIST_CALLED(NAME) +#define UVMHIST_FUNC(FNAME) KERNHIST_FUNC(FNAME) -#ifdef _KERNEL +#else -/* - * macros to use the history/tracing code. note that UVMHIST_LOG - * must take 4 arguments (even if they are ignored by the format). - */ -#ifndef UVMHIST #define UVMHIST_DECL(NAME) #define UVMHIST_INIT(NAME,N) #define UVMHIST_INIT_STATIC(NAME,BUF) #define UVMHIST_LOG(NAME,FMT,A,B,C,D) #define UVMHIST_CALLED(NAME) #define UVMHIST_FUNC(FNAME) -#define uvmhist_dump(NAME) -#else -#include <sys/kernel.h> /* for "cold" variable */ -#include <sys/atomic.h> -#include <sys/kmem.h> - -extern struct uvm_history_head uvm_histories; - -#define UVMHIST_DECL(NAME) struct uvm_history NAME - -#define UVMHIST_INIT(NAME,N) \ -do { \ - (NAME).name = __STRING(NAME); \ - (NAME).namelen = strlen(__STRING(NAME)); \ - (NAME).n = (N); \ - (NAME).f = 0; \ - (NAME).e = (struct uvm_history_ent *) \ - kmem_zalloc(sizeof(struct uvm_history_ent) * (N), KM_SLEEP); \ - LIST_INSERT_HEAD(&uvm_histories, &(NAME), list); \ -} while (/*CONSTCOND*/ 0) - -#define UVMHIST_INIT_STATIC(NAME,BUF) \ -do { \ - (NAME).name = __STRING(NAME); \ - (NAME).namelen = strlen(__STRING(NAME)); \ - (NAME).n = sizeof(BUF) / sizeof(struct uvm_history_ent); \ - (NAME).f = 0; \ - (NAME).e = (struct uvm_history_ent *) (BUF); \ - memset((NAME).e, 0, sizeof(struct uvm_history_ent) * (NAME).n); \ - LIST_INSERT_HEAD(&uvm_histories, &(NAME), list); \ -} while (/*CONSTCOND*/ 0) - -#if defined(UVMHIST_PRINT) -extern int uvmhist_print_enabled; -#define UVMHIST_PRINTNOW(E) \ -do { \ - if (uvmhist_print_enabled) { \ - uvmhist_entry_print(E); \ - DELAY(100000); \ - } \ -} while (/*CONSTCOND*/ 0) -#else -#define UVMHIST_PRINTNOW(E) /* nothing */ -#endif - -#define UVMHIST_LOG(NAME,FMT,A,B,C,D) \ -do { \ - unsigned int _i_, _j_; \ - do { \ - _i_ = (NAME).f; \ - _j_ = (_i_ + 1 < (NAME).n) ? _i_ + 1 : 0; \ - } while (atomic_cas_uint(&(NAME).f, _i_, _j_) != _i_); \ - if (!cold) \ - microtime(&(NAME).e[_i_].tv); \ - (NAME).e[_i_].cpunum = cpu_number(); \ - (NAME).e[_i_].fmt = (FMT); \ - (NAME).e[_i_].fmtlen = strlen(FMT); \ - (NAME).e[_i_].fn = _uvmhist_name; \ - (NAME).e[_i_].fnlen = strlen(_uvmhist_name); \ - (NAME).e[_i_].call = _uvmhist_call; \ - (NAME).e[_i_].v[0] = (u_long)(A); \ - (NAME).e[_i_].v[1] = (u_long)(B); \ - (NAME).e[_i_].v[2] = (u_long)(C); \ - (NAME).e[_i_].v[3] = (u_long)(D); \ - UVMHIST_PRINTNOW(&((NAME).e[_i_])); \ -} while (/*CONSTCOND*/ 0) - -#define UVMHIST_CALLED(NAME) \ -do { \ - _uvmhist_call = atomic_inc_uint_nv(&_uvmhist_cnt); \ - UVMHIST_LOG(NAME,"called!", 0, 0, 0, 0); \ -} while (/*CONSTCOND*/ 0) - -#define UVMHIST_FUNC(FNAME) \ - static unsigned int _uvmhist_cnt = 0; \ - static const char *const _uvmhist_name = FNAME; \ - int _uvmhist_call; - -static inline void uvmhist_entry_print(struct uvm_history_ent *); - -static inline void -uvmhist_entry_print(e) - struct uvm_history_ent *e; -{ - printf("%06" PRIu64 ".%06d ", e->tv.tv_sec, e->tv.tv_usec); - printf("%s#%ld@%d: ", e->fn, e->call, e->cpunum); - printf(e->fmt, e->v[0], e->v[1], e->v[2], e->v[3]); - printf("\n"); -} -#endif /* UVMHIST */ -#endif /* _KERNEL */ +#endif #endif /* _UVM_UVM_STAT_H_ */ Index: src/usr.bin/vmstat/vmstat.c diff -u src/usr.bin/vmstat/vmstat.c:1.180 src/usr.bin/vmstat/vmstat.c:1.181 --- src/usr.bin/vmstat/vmstat.c:1.180 Wed Feb 16 12:58:38 2011 +++ src/usr.bin/vmstat/vmstat.c Tue May 17 04:18:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: vmstat.c,v 1.180 2011/02/16 12:58:38 nakayama Exp $ */ +/* $NetBSD: vmstat.c,v 1.181 2011/05/17 04:18:07 mrg Exp $ */ /*- * Copyright (c) 1998, 2000, 2001, 2007 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ #if 0 static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95"; #else -__RCSID("$NetBSD: vmstat.c,v 1.180 2011/02/16 12:58:38 nakayama Exp $"); +__RCSID("$NetBSD: vmstat.c,v 1.181 2011/05/17 04:18:07 mrg Exp $"); #endif #endif /* not lint */ @@ -95,6 +95,7 @@ #include <sys/time.h> #include <sys/user.h> #include <sys/queue.h> +#include <sys/kernhist.h> #include <uvm/uvm_extern.h> #include <uvm/uvm_stat.h> @@ -236,12 +237,12 @@ }; /* - * Namelist for UVM histories + * Namelist for kernel histories */ struct nlist histnl[] = { - { .n_name = "_uvm_histories" }, -#define X_UVM_HISTORIES 0 + { .n_name = "_kern_histories" }, +#define X_KERN_HISTORIES 0 { .n_name = NULL }, }; @@ -319,7 +320,7 @@ void doforkst(void); void hist_traverse(int, const char *); -void hist_dodump(struct uvm_history *); +void hist_dodump(struct kern_history *); int main(int, char **); char **choosedrives(char **); @@ -1752,34 +1753,34 @@ } /* - * Traverse the UVM history buffers, performing the requested action. + * Traverse the kernel history buffers, performing the requested action. * * Note, we assume that if we're not listing, we're dumping. */ void hist_traverse(int todo, const char *histname) { - struct uvm_history_head histhead; - struct uvm_history hist, *histkva; + struct kern_history_head histhead; + struct kern_history hist, *histkva; char *name = NULL; size_t namelen = 0; getnlist(todo); if (histnl[0].n_value == 0) { - warnx("UVM history is not compiled into the kernel."); + warnx("kernel history is not compiled into the kernel."); return; } - deref_kptr((void *)histnl[X_UVM_HISTORIES].n_value, &histhead, - sizeof(histhead), histnl[X_UVM_HISTORIES].n_name); + deref_kptr((void *)histnl[X_KERN_HISTORIES].n_value, &histhead, + sizeof(histhead), histnl[X_KERN_HISTORIES].n_name); if (histhead.lh_first == NULL) { - warnx("No active UVM history logs."); + warnx("No active kernel history logs."); return; } if (todo & HISTLIST) - (void)printf("Active UVM histories:"); + (void)printf("Active kernel histories:"); for (histkva = LIST_FIRST(&histhead); histkva != NULL; histkva = LIST_NEXT(&hist, list)) { @@ -1804,7 +1805,7 @@ if (histname == NULL || strcmp(histname, name) == 0) { if (histname == NULL) (void)printf( - "\nUVM history `%s':\n", name); + "\nkernel history `%s':\n", name); hist_dodump(&hist); } } @@ -1821,15 +1822,15 @@ * Actually dump the history buffer at the specified KVA. */ void -hist_dodump(struct uvm_history *histp) +hist_dodump(struct kern_history *histp) { - struct uvm_history_ent *histents, *e; + struct kern_history_ent *histents, *e; size_t histsize; char *fmt = NULL, *fn = NULL; size_t fmtlen = 0, fnlen = 0; unsigned i; - histsize = sizeof(struct uvm_history_ent) * histp->n; + histsize = sizeof(struct kern_history_ent) * histp->n; if ((histents = malloc(histsize)) == NULL) err(1, "malloc history entries"); Added files: Index: src/sys/kern/kern_history.c diff -u /dev/null src/sys/kern/kern_history.c:1.1 --- /dev/null Tue May 17 04:18:07 2011 +++ src/sys/kern/kern_history.c Tue May 17 04:18:06 2011 @@ -0,0 +1,191 @@ +/* $NetBSD: kern_history.c,v 1.1 2011/05/17 04:18:06 mrg Exp $ */ + +/* + * Copyright (c) 1997 Charles D. Cranor and Washington University. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * from: NetBSD: uvm_stat.c,v 1.36 2011/02/02 15:13:34 chuck Exp + * from: Id: uvm_stat.c,v 1.1.2.3 1997/12/19 15:01:00 mrg Exp + */ + +/* + * subr_kernhist.c + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: kern_history.c,v 1.1 2011/05/17 04:18:06 mrg Exp $"); + +#include "opt_kernhist.h" +#include "opt_uvmhist.h" +#include "opt_ddb.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/cpu.h> +#include <sys/kernhist.h> + +#include <uvm/uvm.h> + +/* + * globals + */ + +struct kern_history_head kern_histories; + +int kernhist_print_enabled = 1; + +#ifdef DDB + +/* + * prototypes + */ + +void kernhist_dump(struct kern_history *); +void kernhist_dumpmask(u_int32_t); +static void kernhist_dump_histories(struct kern_history *[]); + + +/* + * call this from ddb + * + * expects the system to be quiesced, no locking + */ +void +kernhist_dump(struct kern_history *l) +{ + int lcv; + + lcv = l->f; + do { + if (l->e[lcv].fmt) + kernhist_entry_print(&l->e[lcv]); + lcv = (lcv + 1) % l->n; + } while (lcv != l->f); +} + +/* + * print a merged list of kern_history structures + */ +static void +kernhist_dump_histories(struct kern_history *hists[]) +{ + struct timeval tv; + int cur[MAXHISTS]; + int lcv, hi; + + /* find the first of each list */ + for (lcv = 0; hists[lcv]; lcv++) + cur[lcv] = hists[lcv]->f; + + /* + * here we loop "forever", finding the next earliest + * history entry and printing it. cur[X] is the current + * entry to test for the history in hists[X]. if it is + * -1, then this history is finished. + */ + for (;;) { + hi = -1; + tv.tv_sec = tv.tv_usec = 0; + + /* loop over each history */ + for (lcv = 0; hists[lcv]; lcv++) { +restart: + if (cur[lcv] == -1) + continue; + + /* + * if the format is empty, go to the next entry + * and retry. + */ + if (hists[lcv]->e[cur[lcv]].fmt == NULL) { + cur[lcv] = (cur[lcv] + 1) % (hists[lcv]->n); + if (cur[lcv] == hists[lcv]->f) + cur[lcv] = -1; + goto restart; + } + + /* + * if the time hasn't been set yet, or this entry is + * earlier than the current tv, set the time and history + * index. + */ + if (tv.tv_sec == 0 || + timercmp(&hists[lcv]->e[cur[lcv]].tv, &tv, <)) { + tv = hists[lcv]->e[cur[lcv]].tv; + hi = lcv; + } + } + + /* if we didn't find any entries, we must be done */ + if (hi == -1) + break; + + /* print and move to the next entry */ + kernhist_entry_print(&hists[hi]->e[cur[hi]]); + cur[hi] = (cur[hi] + 1) % (hists[hi]->n); + if (cur[hi] == hists[hi]->f) + cur[hi] = -1; + } +} + +/* + * call this from ddb. `bitmask' is from <sys/kernhist.h>. it + * merges the named histories. + * + * expects the system to be quiesced, no locking + */ +void +kernhist_dumpmask(u_int32_t bitmask) /* XXX only support 32 hists */ +{ + struct kern_history *hists[MAXHISTS + 1]; + int i = 0; + +#ifdef UVMHIST + if ((bitmask & KERNHIST_UVMMAPHIST) || bitmask == 0) + hists[i++] = &maphist; + + if ((bitmask & KERNHIST_UVMPDHIST) || bitmask == 0) + hists[i++] = &pdhist; + + if ((bitmask & KERNHIST_UVMUBCHIST) || bitmask == 0) + hists[i++] = &ubchist; + + if ((bitmask & KERNHIST_UVMLOANHIST) || bitmask == 0) + hists[i++] = &loanhist; +#endif + + hists[i] = NULL; + + kernhist_dump_histories(hists); +} + +/* + * kernhist_print: ddb hook to print kern history + */ +void +kernhist_print(void (*pr)(const char *, ...)) +{ + kernhist_dump(LIST_FIRST(&kern_histories)); +} + +#endif Index: src/sys/sys/kernhist.h diff -u /dev/null src/sys/sys/kernhist.h:1.1 --- /dev/null Tue May 17 04:18:07 2011 +++ src/sys/sys/kernhist.h Tue May 17 04:18:07 2011 @@ -0,0 +1,199 @@ +/* $NetBSD: kernhist.h,v 1.1 2011/05/17 04:18:07 mrg Exp $ */ + +/* + * Copyright (c) 1997 Charles D. Cranor and Washington University. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * from: NetBSD: uvm_stat.h,v 1.49 2011/04/23 18:14:13 rmind Exp + * from: Id: uvm_stat.h,v 1.1.2.4 1998/02/07 01:16:56 chs Exp + */ + +#ifndef _SYS_KERNHIST_H_ +#define _SYS_KERNHIST_H_ + +#if defined(_KERNEL_OPT) +#include "opt_kernhist.h" +#endif + +#include <sys/queue.h> +#ifdef KERNHIST +#include <sys/cpu.h> +#endif + +/* + * kernel history/tracing, was uvm_stat + */ + +struct kern_history_ent { + struct timeval tv; /* time stamp */ + int cpunum; + const char *fmt; /* printf format */ + size_t fmtlen; /* length of printf format */ + const char *fn; /* function name */ + size_t fnlen; /* length of function name */ + u_long call; /* function call number */ + u_long v[4]; /* values */ +}; + +struct kern_history { + const char *name; /* name of this history */ + size_t namelen; /* length of name, not including null */ + LIST_ENTRY(kern_history) list; /* link on list of all histories */ + unsigned int n; /* number of entries */ + unsigned int f; /* next free one */ + struct kern_history_ent *e; /* the allocated entries */ +}; + +LIST_HEAD(kern_history_head, kern_history); + +/* + * grovelling lists all at once. we currently do not allow more than + * 32 histories to exist, as the way to dump a number of them at once + * is by calling kern_hist() with a bitmask. + * + * XXX extend this to have a registration function? however, there + * needs to be static ones as UVM requires this before almost anything + * else is setup. + */ + +/* this is used to set the size of some arrays */ +#define MAXHISTS 32 + +/* and these are the bit values of each history */ +#define KERNHIST_UVMMAPHIST 0x00000001 /* maphist */ +#define KERNHIST_UVMPDHIST 0x00000002 /* pdhist */ +#define KERNHIST_UVMUBCHIST 0x00000004 /* ubchist */ +#define KERNHIST_UVMLOANHIST 0x00000008 /* loanhist */ + +#ifdef _KERNEL + +/* + * macros to use the history/tracing code. note that KERNHIST_LOG + * must take 4 arguments (even if they are ignored by the format). + */ +#ifndef KERNHIST +#define KERNHIST_DECL(NAME) +#define KERNHIST_INIT(NAME,N) +#define KERNHIST_INIT_STATIC(NAME,BUF) +#define KERNHIST_LOG(NAME,FMT,A,B,C,D) +#define KERNHIST_CALLED(NAME) +#define KERNHIST_FUNC(FNAME) +#define kernhist_dump(NAME) +#else +#include <sys/kernel.h> /* for "cold" variable */ +#include <sys/atomic.h> +#include <sys/kmem.h> + +extern struct kern_history_head kern_histories; + +#define KERNHIST_DECL(NAME) struct kern_history NAME + +#define KERNHIST_INIT(NAME,N) \ +do { \ + (NAME).name = __STRING(NAME); \ + (NAME).namelen = strlen(__STRING(NAME)); \ + (NAME).n = (N); \ + (NAME).f = 0; \ + (NAME).e = (struct kern_history_ent *) \ + kmem_zalloc(sizeof(struct kern_history_ent) * (N), KM_SLEEP); \ + LIST_INSERT_HEAD(&kern_histories, &(NAME), list); \ +} while (/*CONSTCOND*/ 0) + +#define KERNHIST_INIT_STATIC(NAME,BUF) \ +do { \ + (NAME).name = __STRING(NAME); \ + (NAME).namelen = strlen(__STRING(NAME)); \ + (NAME).n = sizeof(BUF) / sizeof(struct kern_history_ent); \ + (NAME).f = 0; \ + (NAME).e = (struct kern_history_ent *) (BUF); \ + memset((NAME).e, 0, sizeof(struct kern_history_ent) * (NAME).n); \ + LIST_INSERT_HEAD(&kern_histories, &(NAME), list); \ +} while (/*CONSTCOND*/ 0) + +#if defined(KERNHIST_PRINT) +extern int kernhist_print_enabled; +#define KERNHIST_PRINTNOW(E) \ +do { \ + if (kernhist_print_enabled) { \ + kernhist_entry_print(E); \ + DELAY(100000); \ + } \ +} while (/*CONSTCOND*/ 0) +#else +#define KERNHIST_PRINTNOW(E) /* nothing */ +#endif + +#define KERNHIST_LOG(NAME,FMT,A,B,C,D) \ +do { \ + unsigned int _i_, _j_; \ + do { \ + _i_ = (NAME).f; \ + _j_ = (_i_ + 1 < (NAME).n) ? _i_ + 1 : 0; \ + } while (atomic_cas_uint(&(NAME).f, _i_, _j_) != _i_); \ + if (!cold) \ + microtime(&(NAME).e[_i_].tv); \ + (NAME).e[_i_].cpunum = cpu_number(); \ + (NAME).e[_i_].fmt = (FMT); \ + (NAME).e[_i_].fmtlen = strlen(FMT); \ + (NAME).e[_i_].fn = _kernhist_name; \ + (NAME).e[_i_].fnlen = strlen(_kernhist_name); \ + (NAME).e[_i_].call = _kernhist_call; \ + (NAME).e[_i_].v[0] = (u_long)(A); \ + (NAME).e[_i_].v[1] = (u_long)(B); \ + (NAME).e[_i_].v[2] = (u_long)(C); \ + (NAME).e[_i_].v[3] = (u_long)(D); \ + KERNHIST_PRINTNOW(&((NAME).e[_i_])); \ +} while (/*CONSTCOND*/ 0) + +#define KERNHIST_CALLED(NAME) \ +do { \ + _kernhist_call = atomic_inc_uint_nv(&_kernhist_cnt); \ + KERNHIST_LOG(NAME,"called!", 0, 0, 0, 0); \ +} while (/*CONSTCOND*/ 0) + +#define KERNHIST_FUNC(FNAME) \ + static unsigned int _kernhist_cnt = 0; \ + static const char *const _kernhist_name = FNAME; \ + int _kernhist_call = 0; + +static inline void kernhist_entry_print(struct kern_history_ent *); + +static inline void +kernhist_entry_print(e) + struct kern_history_ent *e; +{ + printf("%06" PRIu64 ".%06d ", e->tv.tv_sec, e->tv.tv_usec); + printf("%s#%ld@%d: ", e->fn, e->call, e->cpunum); + printf(e->fmt, e->v[0], e->v[1], e->v[2], e->v[3]); + printf("\n"); +} + +#if defined(DDB) +void kernhist_print(void (*)(const char *, ...)); +#endif /* DDB */ + +#endif /* KERNHIST */ + +#endif /* _KERNEL */ + +#endif /* _SYS_KERNHIST_H_ */