From: Matthew Dillon Date: Mon, 20 Jun 2005 17:59:33 +0000 (+0000) Subject: Reimplement the kernel tracepoint facility. The new implementation is X-Git-Tag: v2.0.1~6841 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/d3776285357d737718bee52bc4269ae4eaf7fa9c Reimplement the kernel tracepoint facility. The new implementation is completely generic and very easy to implement in modules. Compile-time optimizations are retained and sysctl generation is completely automatic. Only the DDB command code has been retained from FreeBSD. The logging macros are designed to allow subsystems to trivially declare and use the facility. This implementation is not quite complete, we also want to integrate a stack backtrace logging facility. --- diff --git a/sys/conf/options b/sys/conf/options index c173216253..df50382d24 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/conf/options,v 1.191.2.53 2003/06/04 17:56:58 sam Exp $ -# $DragonFly: src/sys/conf/options,v 1.32 2005/06/20 07:58:37 dillon Exp $ +# $DragonFly: src/sys/conf/options,v 1.33 2005/06/20 17:59:31 dillon Exp $ # # On the handling of kernel options # @@ -524,9 +524,11 @@ HIFN_NO_RNG opt_hifn.h # KTR options KTR opt_global.h -KTR_MASK opt_ktr.h -KTR_CPUMASK opt_ktr.h -KTR_COMPILE opt_global.h +KTR_ALL opt_ktr.h +KTR_TOKENS opt_ktr.h +KTR_MALLOC opt_ktr.h +KTR_IPIQ opt_ktr.h +KTR_MSGPORT opt_ktr.h KTR_ENTRIES opt_global.h KTR_VERBOSE opt_ktr.h diff --git a/sys/config/LINT b/sys/config/LINT index 734d51ee9d..b416a5b796 100644 --- a/sys/config/LINT +++ b/sys/config/LINT @@ -3,7 +3,7 @@ # as much of the source tree as it can. # # $FreeBSD: src/sys/i386/conf/LINT,v 1.749.2.144 2003/06/04 17:56:59 sam Exp $ -# $DragonFly: src/sys/config/LINT,v 1.55 2005/06/12 19:24:10 swildner Exp $ +# $DragonFly: src/sys/config/LINT,v 1.56 2005/06/20 17:59:33 dillon Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -2661,10 +2661,7 @@ options VFS_BIO_DEBUG options XBONEHACK options KTR -options KTR_MASK=1 -options KTR_CPUMASK=1 -options KTR_COMPILE=(KTR_ALL) # Every trace class, see sys/ktr.h for - # the different class numbers +options KTR_ALL options KTR_ENTRIES=1024 options KTR_VERBOSE=1 diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT index 005edfc0c8..08597676ea 100644 --- a/sys/i386/conf/LINT +++ b/sys/i386/conf/LINT @@ -3,7 +3,7 @@ # as much of the source tree as it can. # # $FreeBSD: src/sys/i386/conf/LINT,v 1.749.2.144 2003/06/04 17:56:59 sam Exp $ -# $DragonFly: src/sys/i386/conf/Attic/LINT,v 1.55 2005/06/12 19:24:10 swildner Exp $ +# $DragonFly: src/sys/i386/conf/Attic/LINT,v 1.56 2005/06/20 17:59:33 dillon Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -2661,10 +2661,7 @@ options VFS_BIO_DEBUG options XBONEHACK options KTR -options KTR_MASK=1 -options KTR_CPUMASK=1 -options KTR_COMPILE=(KTR_ALL) # Every trace class, see sys/ktr.h for - # the different class numbers +options KTR_ALL options KTR_ENTRIES=1024 options KTR_VERBOSE=1 diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c index 63ab1ad985..5f536af9b6 100644 --- a/sys/kern/kern_ktr.c +++ b/sys/kern/kern_ktr.c @@ -1,6 +1,39 @@ -/*- - * Copyright (c) 2004 Eirik Nygaard - * All rights reserved. +/* + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * 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. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 + * COPYRIGHT HOLDERS OR CONTRIBUTORS 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. + */ +/* + * The following copyright applies to the DDB command code: + * * Copyright (c) 2000 John Baldwin * All rights reserved. * @@ -28,15 +61,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ - /* - * This module holds the global variables used by KTR and the ktr_tracepoint() - * function that does the actual tracing. + * $DragonFly: src/sys/kern/kern_ktr.c,v 1.5 2005/06/20 17:59:32 dillon Exp $ */ - /* - * $FreeBSD: src/sys/kern/kern_ktr.c,v 1.43 2003/09/10 01:09:32 jhb Exp $ - * $DragonFly: src/sys/kern/kern_ktr.c,v 1.4 2005/04/20 14:27:29 joerg Exp $ + * Kernel tracepoint facility. */ #include "opt_ddb.h" @@ -45,10 +74,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -63,48 +92,31 @@ #include #ifndef KTR_ENTRIES -#define KTR_ENTRIES 1024 -#endif - -#ifndef KTR_MASK -#define KTR_MASK (KTR_ALL) -#endif - -#ifndef KTR_CPUMASK -#define KTR_CPUMASK (~0) -#endif - -#ifndef KTR_TIME -#define KTR_TIME ktr_getts() -#endif - -#ifndef KTR_CPU -#define KTR_CPU mycpu->gd_cpuid; +#define KTR_ENTRIES 2048 #endif +#define KTR_ENTRIES_MASK (KTR_ENTRIES - 1) MALLOC_DEFINE(M_KTR, "ktr", "ktr buffers"); -SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RD, 0, "KTR options"); +SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RW, 0, "ktr"); -int ktr_cpumask = KTR_CPUMASK; +int32_t ktr_cpumask = -1; TUNABLE_INT("debug.ktr.cpumask", &ktr_cpumask); SYSCTL_INT(_debug_ktr, OID_AUTO, cpumask, CTLFLAG_RW, &ktr_cpumask, 0, ""); -int ktr_mask = KTR_MASK; -TUNABLE_INT("debug.ktr.mask", &ktr_mask); -SYSCTL_INT(_debug_ktr, OID_AUTO, mask, CTLFLAG_RW, &ktr_mask, 0, ""); - int ktr_entries = KTR_ENTRIES; SYSCTL_INT(_debug_ktr, OID_AUTO, entries, CTLFLAG_RD, &ktr_entries, 0, ""); int ktr_version = KTR_VERSION; SYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD, &ktr_version, 0, ""); -int ktr_discarded; -SYSCTL_INT(_debug_ktr, OID_AUTO, discarded, CTLFLAG_RD, &ktr_discarded, 0, ""); - -volatile int ktr_idx[MAXCPU], ktr_initiated = 0; -struct ktr_entry *ktr_buf[MAXCPU]; +/* + * Give cpu0 a static buffer so the tracepoint facility can be used during + * early boot (note however that we still use a critical section, XXX). + */ +static struct ktr_entry ktr_buf0[KTR_ENTRIES]; +static struct ktr_entry *ktr_buf[MAXCPU] = { &ktr_buf0[0] }; +static int ktr_idx[MAXCPU]; #ifdef KTR_VERBOSE int ktr_verbose = KTR_VERBOSE; @@ -117,81 +129,68 @@ ktr_sysinit(void *dummy) { int i; - for(i = 0; i < ncpus; i++) { + for(i = 1; i < ncpus; ++i) { ktr_buf[i] = malloc(KTR_ENTRIES * sizeof(struct ktr_entry), - M_KTR, M_WAITOK); - ktr_idx[i] = -1; + M_KTR, M_WAITOK | M_ZERO); } - ktr_initiated++; -} -SYSINIT(announce, SI_SUB_INTRINSIC, SI_ORDER_FIRST, ktr_sysinit, NULL); - -static __inline int -ktr_nextindex(int cpu) -{ - int ktrindex; - - crit_enter(); - ktrindex = ktr_idx[cpu] = (ktr_idx[cpu] + 1) & (KTR_ENTRIES - 1); - crit_exit(); - return(ktrindex); } -static __inline uint64_t -ktr_getts(void) -{ - if (cpu_feature & CPUID_TSC) - return(rdtsc()); - return(get_approximate_time_t()); -} +SYSINIT(announce, SI_SUB_INTRINSIC, SI_ORDER_FIRST, ktr_sysinit, NULL); +static __inline void -ktr_tracepoint(u_int mask, const char *file, int line, const char *format, - u_long arg1, u_long arg2, u_long arg3, u_long arg4, u_long arg5, - u_long arg6) +ktr_write_entry(struct ktr_info *info, const char *file, int line, + const void *ptr) { struct ktr_entry *entry; - int cpu, newindex; - - if (ktr_initiated == 0) { - ktr_discarded++; - return; + int cpu; + + cpu = mycpu->gd_cpuid; + if (ktr_buf[cpu]) { + crit_enter(); + entry = ktr_buf[cpu] + (ktr_idx[cpu] & KTR_ENTRIES_MASK); + ++ktr_idx[cpu]; + crit_exit(); + if (cpu_feature & CPUID_TSC) + entry->ktr_timestamp = rdtsc(); + else + entry->ktr_timestamp = get_approximate_time_t(); + entry->ktr_info = info; + entry->ktr_file = file; + entry->ktr_line = line; + if (info->kf_data_size > KTR_BUFSIZE) + bcopyi(ptr, entry->ktr_data, KTR_BUFSIZE); + else + bcopyi(ptr, entry->ktr_data, info->kf_data_size); } - if (panicstr) - return; - if ((ktr_mask & mask) == 0) - return; - cpu = KTR_CPU; - if (((1 << cpu) & ktr_cpumask) == 0) - return; - newindex = ktr_nextindex(cpu); - entry = &ktr_buf[cpu][newindex]; - entry->ktr_timestamp = KTR_TIME; - entry->ktr_cpu = cpu; - if (file != NULL) - while (strncmp(file, "../", 3) == 0) - file += 3; - entry->ktr_file = file; - entry->ktr_line = line; #ifdef KTR_VERBOSE - if (ktr_verbose) { + if (ktr_verbose && info->kf_format) { #ifdef SMP printf("cpu%d ", cpu); #endif if (ktr_verbose > 1) { printf("%s.%d\t", entry->ktr_file, entry->ktr_line); } - printf(format, arg1, arg2, arg3, arg4, arg5, arg6); + vprintf(info->kf_format, ptr); printf("\n"); } #endif - entry->ktr_desc = format; - entry->ktr_parms[0] = arg1; - entry->ktr_parms[1] = arg2; - entry->ktr_parms[2] = arg3; - entry->ktr_parms[3] = arg4; - entry->ktr_parms[4] = arg5; - entry->ktr_parms[5] = arg6; +} + +void +ktr_log(struct ktr_info *info, const char *file, int line, ...) +{ + __va_list va; + + __va_start(va, line); + ktr_write_entry(info, file, line, va); + __va_end(va); +} + +void +ktr_log_ptr(struct ktr_info *info, const char *file, int line, const void *ptr) +{ + ktr_write_entry(info, file, line, ptr); } #ifdef DDB @@ -202,8 +201,9 @@ struct tstate { int cur; int first; }; + static int db_ktr_verbose; -static int db_mach_vtrace(struct ktr_entry *kp, int idx); +static int db_mach_vtrace(int cpu, struct ktr_entry *kp, int idx); DB_SHOW_COMMAND(ktr, db_ktr_all) { @@ -216,7 +216,7 @@ DB_SHOW_COMMAND(ktr, db_ktr_all) for(i = 0; i < ncpus; i++) { tstate[i].first = -1; - tstate[i].cur = ktr_idx[i]; + tstate[i].cur = ktr_idx[i] & KTR_ENTRIES_MASK; } db_ktr_verbose = 0; while ((c = *(modif++)) != '\0') { @@ -263,6 +263,8 @@ DB_SHOW_COMMAND(ktr, db_ktr_all) * Find the lowest timestamp */ for (i = 0, counter = 0; i < ncpus; i++) { + if (ktr_buf[i] == NULL) + continue; if (printcpu != -1 && printcpu != i) continue; if (tstate[i].cur == -1) { @@ -286,35 +288,41 @@ DB_SHOW_COMMAND(ktr, db_ktr_all) if (--tstate[i].cur < 0) tstate[i].cur = KTR_ENTRIES - 1; if (tstate[i].first == tstate[i].cur) { - db_mach_vtrace(kp, tstate[i].cur + 1); + db_mach_vtrace(i, kp, tstate[i].cur + 1); tstate[i].cur = -1; continue; } - if (ktr_buf[i][tstate[i].cur].ktr_desc == NULL) + if (ktr_buf[i][tstate[i].cur].ktr_info == NULL) tstate[i].cur = -1; if (db_more(&nl) == -1) break; - if (db_mach_vtrace(kp, tstate[i].cur + 1) == 0) + if (db_mach_vtrace(i, kp, tstate[i].cur + 1) == 0) tstate[i].cur = -1; } } static int -db_mach_vtrace(struct ktr_entry *kp, int idx) +db_mach_vtrace(int cpu, struct ktr_entry *kp, int idx) { - if (kp->ktr_desc == NULL) + if (kp->ktr_info == NULL) return(0); #ifdef SMP - db_printf("cpu%d ", kp->ktr_cpu); + db_printf("cpu%d ", cpu); #endif db_printf("%d: ", idx); if (db_ktr_verbose) { db_printf("%10.10lld %s.%d\t", (long long)kp->ktr_timestamp, kp->ktr_file, kp->ktr_line); } - db_printf(kp->ktr_desc, kp->ktr_parms[0], kp->ktr_parms[1], - kp->ktr_parms[2], kp->ktr_parms[3], kp->ktr_parms[4], - kp->ktr_parms[5]); + db_printf("%s\t", kp->ktr_info->kf_name); + if (kp->ktr_info->kf_format) { + int32_t *args = (int32_t *)kp->ktr_data; + db_printf(kp->ktr_info->kf_format, + args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], + args[8], args[9], args[10], args[11]); + + } db_printf("\n"); return(1); diff --git a/sys/sys/ktr.h b/sys/sys/ktr.h index a464af52a7..b259de5476 100644 --- a/sys/sys/ktr.h +++ b/sys/sys/ktr.h @@ -1,37 +1,41 @@ -/*- - * Copyright (c) 1996 Berkeley Software Design, Inc. All rights reserved. - * +/* + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * * 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. - * 3. Berkeley Software Design Inc's name may not be used to endorse or - * promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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 + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 + * COPYRIGHT HOLDERS OR CONTRIBUTORS 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 BSDI $Id: ktr.h,v 1.10.2.7 2000/03/16 21:44:42 cp Exp $ - * $FreeBSD: /repoman/r/ncvs/src/sys/sys/ktr.h,v 1.21 2003/03/11 20:07:22 jhb Exp $ - * $DragonFly: src/sys/sys/ktr.h,v 1.4 2005/03/09 23:26:11 hmp Exp $ + * + * $DragonFly: src/sys/sys/ktr.h,v 1.5 2005/06/20 17:59:30 dillon Exp $ */ - /* - * Wraparound kernel trace buffer support. + * Generic Kernel trace buffer support. + * */ #ifndef _SYS_KTR_H_ @@ -41,141 +45,104 @@ #include "opt_ktr.h" #endif -/* - * Trace classes - */ -#define KTR_GEN 0x00000001 /* General (TR) */ -#define KTR_NET 0x00000002 /* Network */ -#define KTR_DEV 0x00000004 /* Device driver */ -#define KTR_LOCK 0x00000008 /* MP locking */ -#define KTR_SMP 0x00000010 /* MP general */ -#define KTR_FS 0x00000020 /* Filesystem */ -#define KTR_PMAP 0x00000040 /* Pmap tracing */ -#define KTR_MALLOC 0x00000080 /* Malloc tracing */ -#define KTR_TRAP 0x00000100 /* Trap processing */ -#define KTR_INTR 0x00000200 /* Interrupt tracing */ -#define KTR_SIG 0x00000400 /* Signal processing */ -#define KTR_CLK 0x00000800 /* hardclock verbose */ -#define KTR_PROC 0x00001000 /* Process scheduling */ -#define KTR_SYSC 0x00002000 /* System call */ -#define KTR_INIT 0x00004000 /* System initialization */ -#define KTR_KGDB 0x00008000 /* Trace kgdb internals */ -#define KTR_IO 0x00010000 /* Upper I/O */ -#define KTR_EVH 0x00020000 /* Eventhandler */ -#define KTR_NFS 0x00040000 /* NFS */ -#define KTR_VOP 0x00080000 /* VFS and VNODE ops */ -#define KTR_VM 0x00100000 /* The virtual memory system */ -#define KTR_RUNQ 0x00200000 /* Run queue */ -#define KTR_CONTENTION 0x00800000 /* Lock contention */ -#define KTR_ALL 0x00ffffff - -/* - * Trace classes which can be assigned to particular use at compile time - * These must remain in high 22 as some assembly code counts on it - */ -#define KTR_CT1 0x01000000 -#define KTR_CT2 0x02000000 -#define KTR_CT3 0x04000000 -#define KTR_CT4 0x08000000 -#define KTR_CT5 0x10000000 -#define KTR_CT6 0x20000000 -#define KTR_CT7 0x40000000 -#define KTR_CT8 0x80000000 - -/* Trace classes to compile in */ -#ifndef KTR_COMPILE -#define KTR_COMPILE (KTR_ALL) +#if !defined(KTR_ALL) +#define KTR_ALL 0 #endif -/* - * Version number for ktr_entry struct. Increment this when you break binary - * compatibility. - */ -#define KTR_VERSION 1 - -#define KTR_PARMS 6 +#define KTR_BUFSIZE 48 +#define KTR_VERSION 2 #ifndef LOCORE +struct ktr_info { + const char *kf_name; /* human-interpreted subsystem name */ + int32_t *kf_master_enable; /* the master enable variable */ + const char *kf_format; /* data format */ + int kf_data_size; /* relevance of the data buffer */ +}; + struct ktr_entry { u_int64_t ktr_timestamp; - int ktr_cpu; - int ktr_line; + struct ktr_info *ktr_info; const char *ktr_file; - const char *ktr_desc; - u_long ktr_parms[KTR_PARMS]; + void *ktr_caller1; + void *ktr_caller2; + int32_t ktr_line; + int32_t ktr_unused; + char ktr_data[KTR_BUFSIZE]; }; -extern int ktr_cpumask; -extern int ktr_mask; -extern int ktr_entries; -extern int ktr_verbose; - -extern volatile int ktr_idx[MAXCPU]; -extern struct ktr_entry *ktr_buf[MAXCPU]; +void ktr_log(struct ktr_info *info, const char *file, int line, ...); +void ktr_log_ptr(struct ktr_info *info, const char *file, int line, const void *ptr); -#endif /* !LOCORE */ +/* + * Take advantage of constant integer optimizations by the compiler + * to optimize-out disabled code at compile-time. If KTR_ENABLE_ + * is 0, the compiler avoids generating all related code when KTR is enabled. + */ #ifdef KTR -void ktr_tracepoint(u_int mask, const char *file, int line, - const char *format, u_long arg1, u_long arg2, u_long arg3, - u_long arg4, u_long arg5, u_long arg6); - -#define CTR6(m, format, p1, p2, p3, p4, p5, p6) do { \ - if (KTR_COMPILE & (m)) \ - ktr_tracepoint((m), __FILE__, __LINE__, format, \ - (u_long)(p1), (u_long)(p2), (u_long)(p3), \ - (u_long)(p4), (u_long)(p5), (u_long)(p6)); \ - } while(0) -#define CTR0(m, format) CTR6(m, format, 0, 0, 0, 0, 0, 0) -#define CTR1(m, format, p1) CTR6(m, format, p1, 0, 0, 0, 0, 0) -#define CTR2(m, format, p1, p2) CTR6(m, format, p1, p2, 0, 0, 0, 0) -#define CTR3(m, format, p1, p2, p3) CTR6(m, format, p1, p2, p3, 0, 0, 0) -#define CTR4(m, format, p1, p2, p3, p4) CTR6(m, format, p1, p2, p3, p4, 0, 0) -#define CTR5(m, format, p1, p2, p3, p4, p5) CTR6(m, format, p1, p2, p3, p4, p5, 0) -#else /* KTR */ -#undef KTR_COMPILE -#define KTR_COMPILE 0 -#define CTR0(m, d) -#define CTR1(m, d, p1) -#define CTR2(m, d, p1, p2) -#define CTR3(m, d, p1, p2, p3) -#define CTR4(m, d, p1, p2, p3, p4) -#define CTR5(m, d, p1, p2, p3, p4, p5) -#define CTR6(m, d, p1, p2, p3, p4, p5, p6) -#endif /* KTR */ - -#define TR0(d) CTR0(KTR_GEN, d) -#define TR1(d, p1) CTR1(KTR_GEN, d, p1) -#define TR2(d, p1, p2) CTR2(KTR_GEN, d, p1, p2) -#define TR3(d, p1, p2, p3) CTR3(KTR_GEN, d, p1, p2, p3) -#define TR4(d, p1, p2, p3, p4) CTR4(KTR_GEN, d, p1, p2, p3, p4) -#define TR5(d, p1, p2, p3, p4, p5) CTR5(KTR_GEN, d, p1, p2, p3, p4, p5) -#define TR6(d, p1, p2, p3, p4, p5, p6) CTR6(KTR_GEN, d, p1, p2, p3, p4, p5, p6) +SYSCTL_DECL(_debug_ktr); + +#define KTR_INFO_MASTER(master) \ + SYSCTL_NODE(_debug_ktr, OID_AUTO, master, CTLFLAG_RW, 0, ""); \ + int ktr_ ## master ## _enable = -1; \ + SYSCTL_INT(_debug_ktr, OID_AUTO, master ## _enable, CTLFLAG_RW, \ + &ktr_ ## master ## _enable, 0, "") + +#define KTR_INFO_MASTER_EXTERN(master) \ + SYSCTL_DECL(_debug_ktr_ ## master); \ + extern int ktr_ ## master ## _enable \ /* - * Trace initialization events, similar to CTR with KTR_INIT, but - * completely ifdef'ed out if KTR_INIT isn't in KTR_COMPILE (to - * save string space, the compiler doesn't optimize out strings - * for the conditional ones above). + * This creates a read-only sysctl so the user knows what the mask + * definitions are and a number of static const int's which are used + * by the compiler to optimize the trace logging at compile-time and + * run-time. */ -#if (KTR_COMPILE & KTR_INIT) != 0 -#define ITR0(d) CTR0(KTR_INIT, d) -#define ITR1(d, p1) CTR1(KTR_INIT, d, p1) -#define ITR2(d, p1, p2) CTR2(KTR_INIT, d, p1, p2) -#define ITR3(d, p1, p2, p3) CTR3(KTR_INIT, d, p1, p2, p3) -#define ITR4(d, p1, p2, p3, p4) CTR4(KTR_INIT, d, p1, p2, p3, p4) -#define ITR5(d, p1, p2, p3, p4, p5) CTR5(KTR_INIT, d, p1, p2, p3, p4, p5) -#define ITR6(d, p1, p2, p3, p4, p5, p6) CTR6(KTR_INIT, d, p1, p2, p3, p4, p5, p6) +#define KTR_INFO(compile, master, name, maskbit, format, datasize) \ + static const int ktr_ ## master ## _ ## name ## _mask = \ + 1 << maskbit; \ + static const int ktr_ ## master ## _ ## name ## _enable = \ + compile; \ + static int ktr_ ## master ## _ ## name ## _mask_ro = \ + 1 << maskbit; \ + SYSCTL_INT(_debug_ktr_ ## master, OID_AUTO, name ## _mask, \ + CTLFLAG_RD, &ktr_ ## master ## _ ## name ## _mask_ro, \ + 0, ""); \ + static struct ktr_info ktr_info_ ## master ## _ ## name = { \ + #master "_" #name, \ + &ktr_ ## master ## _enable, \ + format, \ + datasize } + +#define KTR_LOG(name, args...) \ + if (ktr_ ## name ## _enable && \ + (ktr_ ## name ## _mask & *ktr_info_ ## name .kf_master_enable)) \ + ktr_log(&ktr_info_ ## name, __FILE__, __LINE__, ##args) + +#define KTR_LOG_PTR(name, ptr) \ + if (ktr_ ## name ## _enable && \ + (ktr_ ## name ## _mask & *ktr_info_ ## name .kf_master_enable)) \ + ktr_log_ptr(&ktr_info_ ## name, __FILE__, __LINE__, ptr) + #else -#define ITR0(d) -#define ITR1(d, p1) -#define ITR2(d, p1, p2) -#define ITR3(d, p1, p2, p3) -#define ITR4(d, p1, p2, p3, p4) -#define ITR5(d, p1, p2, p3, p4, p5) -#define ITR6(d, p1, p2, p3, p4, p5, p6) + +#define KTR_INFO_MASTER(master) \ + const static int ktr_ ## master ## _enable = 0 + +#define KTR_INFO_MASTER_EXTERN(master) \ + const static int ktr_ ## master ## _enable = 0 + +#define KTR_INFO(master, name, maskbit, format, datasize) \ + static const int ktr_ ## master ## _ ## name ## _mask = \ + 1 << maskbit + +#define KTR_LOG(info, args...) +#define KTR_LOG_PTR(info, ptr) + #endif +#endif /* !LOCORE */ #endif /* !_SYS_KTR_H_ */