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_ */

Reply via email to