Module Name: src Committed By: dyoung Date: Tue Nov 3 05:23:28 UTC 2009
Modified Files: src/sys/arch/i386/conf: files.i386 src/sys/arch/i386/i386: spl.S src/sys/arch/x86/x86: patch.c src/sys/arch/xen/conf: files.xen src/sys/kern: init_main.c kern_stub.c subr_prf.c src/sys/sys: systm.h Added Files: src/sys/kern: subr_spldebug.c src/sys/sys: spldebug.h Log Message: Add a kernel configuration flag, SPLDEBUG, that activates a per-CPU log of transitions to IPL_HIGH from lower IPLs. SPLDEBUG is only available on i386 and Xen kernels, today. 'options SPLDEBUG' adds instrumentation to spllower() and splraise() as well as routines to start/stop debugging and to record IPL transitions: spldebug_start(), spldebug_stop(), spldebug_raise(), spldebug_lower(). To generate a diff of this commit: cvs rdiff -u -r1.351 -r1.352 src/sys/arch/i386/conf/files.i386 cvs rdiff -u -r1.32 -r1.33 src/sys/arch/i386/i386/spl.S cvs rdiff -u -r1.18 -r1.19 src/sys/arch/x86/x86/patch.c cvs rdiff -u -r1.105 -r1.106 src/sys/arch/xen/conf/files.xen cvs rdiff -u -r1.407 -r1.408 src/sys/kern/init_main.c cvs rdiff -u -r1.20 -r1.21 src/sys/kern/kern_stub.c cvs rdiff -u -r1.136 -r1.137 src/sys/kern/subr_prf.c cvs rdiff -u -r0 -r1.1 src/sys/kern/subr_spldebug.c cvs rdiff -u -r0 -r1.1 src/sys/sys/spldebug.h cvs rdiff -u -r1.236 -r1.237 src/sys/sys/systm.h 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/i386/conf/files.i386 diff -u src/sys/arch/i386/conf/files.i386:1.351 src/sys/arch/i386/conf/files.i386:1.352 --- src/sys/arch/i386/conf/files.i386:1.351 Sun Aug 9 19:35:02 2009 +++ src/sys/arch/i386/conf/files.i386 Tue Nov 3 05:23:27 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files.i386,v 1.351 2009/08/09 19:35:02 christos Exp $ +# $NetBSD: files.i386,v 1.352 2009/11/03 05:23:27 dyoung Exp $ # # new style config file for i386 architecture # @@ -45,6 +45,9 @@ # kernel stack debug defflag opt_kstack_dr0.h KSTACK_CHECK_DR0 +# splraise()/spllower() debug +defflag opt_spldebug.h SPLDEBUG + # Beep on halt defflag opt_beep.h BEEP_ONHALT defparam opt_beep.h BEEP_ONHALT_COUNT=3 @@ -71,6 +74,7 @@ file arch/i386/i386/db_trace.c ddb file arch/i386/i386/dumpsys.c file kern/subr_disk_mbr.c disk +file kern/subr_spldebug.c spldebug file arch/i386/i386/gdt.c file arch/i386/i386/i386func.S file arch/i386/i386/ipkdb_glue.c ipkdb Index: src/sys/arch/i386/i386/spl.S diff -u src/sys/arch/i386/i386/spl.S:1.32 src/sys/arch/i386/i386/spl.S:1.33 --- src/sys/arch/i386/i386/spl.S:1.32 Tue Jul 1 18:49:21 2008 +++ src/sys/arch/i386/i386/spl.S Tue Nov 3 05:23:27 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: spl.S,v 1.32 2008/07/01 18:49:21 bouyer Exp $ */ +/* $NetBSD: spl.S,v 1.33 2009/11/03 05:23:27 dyoung Exp $ */ /* * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. @@ -30,10 +30,11 @@ */ #include <machine/asm.h> -__KERNEL_RCSID(0, "$NetBSD: spl.S,v 1.32 2008/07/01 18:49:21 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: spl.S,v 1.33 2009/11/03 05:23:27 dyoung Exp $"); #include "opt_vm86.h" #include "opt_ddb.h" +#include "opt_spldebug.h" #include "opt_xen.h" #include <machine/trap.h> @@ -55,6 +56,16 @@ ja 1f movl %edx,CPUVAR(ILEVEL) 1: +#ifdef SPLDEBUG + pushl %ebp + movl %esp,%ebp + pushl %eax + pushl %edx + call _C_LABEL(spldebug_raise) + addl $4, %esp + popl %eax + popl %ebp +#endif /* SPLDEBUG */ ret END(splraise) @@ -66,6 +77,15 @@ * early in boot where interrupts are disabled via eflags/IE. */ ENTRY(spllower) +#ifdef SPLDEBUG + movl 4(%esp), %ecx + pushl %ebp + movl %esp,%ebp + pushl %ecx + call _C_LABEL(spldebug_lower) + addl $4, %esp + popl %ebp +#endif /* SPLDEBUG */ movl 4(%esp), %ecx cmpl CPUVAR(ILEVEL), %ecx jae 1f Index: src/sys/arch/x86/x86/patch.c diff -u src/sys/arch/x86/x86/patch.c:1.18 src/sys/arch/x86/x86/patch.c:1.19 --- src/sys/arch/x86/x86/patch.c:1.18 Fri Apr 24 17:45:40 2009 +++ src/sys/arch/x86/x86/patch.c Tue Nov 3 05:23:28 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: patch.c,v 1.18 2009/04/24 17:45:40 ad Exp $ */ +/* $NetBSD: patch.c,v 1.19 2009/11/03 05:23:28 dyoung Exp $ */ /*- * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -34,9 +34,10 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.18 2009/04/24 17:45:40 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.19 2009/11/03 05:23:28 dyoung Exp $"); #include "opt_lockdebug.h" +#include "opt_spldebug.h" #include <sys/types.h> #include <sys/systm.h> @@ -200,6 +201,7 @@ } #endif /* i386 */ +#if !defined(SPLDEBUG) if (!early && (cpu_feature & CPUID_CX8) != 0) { /* Faster splx(), mutex_spin_exit(). */ patchfunc( @@ -213,8 +215,9 @@ mutex_spin_exit, mutex_spin_exit_end, i686_mutex_spin_exit_patch ); -#endif /* !LOCKDEBUG */ +#endif /* i386 && !LOCKDEBUG */ } +#endif /* !SPLDEBUG */ /* * On some Opteron revisions, locked operations erroneously Index: src/sys/arch/xen/conf/files.xen diff -u src/sys/arch/xen/conf/files.xen:1.105 src/sys/arch/xen/conf/files.xen:1.106 --- src/sys/arch/xen/conf/files.xen:1.105 Mon Oct 5 23:59:31 2009 +++ src/sys/arch/xen/conf/files.xen Tue Nov 3 05:23:28 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files.xen,v 1.105 2009/10/05 23:59:31 rmind Exp $ +# $NetBSD: files.xen,v 1.106 2009/11/03 05:23:28 dyoung Exp $ # NetBSD: files.x86,v 1.10 2003/10/08 17:30:00 bouyer Exp # NetBSD: files.i386,v 1.254 2004/03/25 23:32:10 jmc Exp @@ -14,6 +14,9 @@ # delay before cpu_reset() for reboot. defparam CPURESET_DELAY +# splraise()/spllower() debug +defflag opt_spldebug.h SPLDEBUG + # Beep on halt defflag opt_beep.h BEEP_ONHALT defparam opt_beep.h BEEP_ONHALT_COUNT=3 Index: src/sys/kern/init_main.c diff -u src/sys/kern/init_main.c:1.407 src/sys/kern/init_main.c:1.408 --- src/sys/kern/init_main.c:1.407 Mon Oct 26 19:03:17 2009 +++ src/sys/kern/init_main.c Tue Nov 3 05:23:28 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.407 2009/10/26 19:03:17 rmind Exp $ */ +/* $NetBSD: init_main.c,v 1.408 2009/11/03 05:23:28 dyoung Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.407 2009/10/26 19:03:17 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.408 2009/11/03 05:23:28 dyoung Exp $"); #include "opt_ddb.h" #include "opt_ipsec.h" @@ -130,6 +130,7 @@ #include <sys/errno.h> #include <sys/callout.h> #include <sys/cpu.h> +#include <sys/spldebug.h> #include <sys/kernel.h> #include <sys/mount.h> #include <sys/proc.h> @@ -486,6 +487,8 @@ /* Initialize interfaces. */ ifinit1(); + spldebug_start(); + /* Configure the system hardware. This will enable interrupts. */ configure(); Index: src/sys/kern/kern_stub.c diff -u src/sys/kern/kern_stub.c:1.20 src/sys/kern/kern_stub.c:1.21 --- src/sys/kern/kern_stub.c:1.20 Tue Oct 6 21:07:06 2009 +++ src/sys/kern/kern_stub.c Tue Nov 3 05:23:28 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_stub.c,v 1.20 2009/10/06 21:07:06 elad Exp $ */ +/* $NetBSD: kern_stub.c,v 1.21 2009/11/03 05:23:28 dyoung Exp $ */ /*- * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_stub.c,v 1.20 2009/10/06 21:07:06 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_stub.c,v 1.21 2009/11/03 05:23:28 dyoung Exp $"); #include "opt_ptrace.h" #include "opt_ktrace.h" @@ -130,6 +130,8 @@ __weak_alias(ktr_point,nullop); #endif /* KTRACE */ +__weak_alias(spldebug_start, voidop); +__weak_alias(spldebug_stop, voidop); __weak_alias(machdep_init,nullop); #if !defined(KERN_SA) @@ -434,6 +436,14 @@ } /* + * Generic null operation, void return value. + */ +void +voidop(void) +{ +} + +/* * Generic null operation, always returns success. */ /*ARGSUSED*/ Index: src/sys/kern/subr_prf.c diff -u src/sys/kern/subr_prf.c:1.136 src/sys/kern/subr_prf.c:1.137 --- src/sys/kern/subr_prf.c:1.136 Sun Jun 28 15:30:30 2009 +++ src/sys/kern/subr_prf.c Tue Nov 3 05:23:28 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_prf.c,v 1.136 2009/06/28 15:30:30 rmind Exp $ */ +/* $NetBSD: subr_prf.c,v 1.137 2009/11/03 05:23:28 dyoung Exp $ */ /*- * Copyright (c) 1986, 1988, 1991, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.136 2009/06/28 15:30:30 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.137 2009/11/03 05:23:28 dyoung Exp $"); #include "opt_ddb.h" #include "opt_ipkdb.h" @@ -57,6 +57,7 @@ #include <sys/file.h> #include <sys/tty.h> #include <sys/tprintf.h> +#include <sys/spldebug.h> #include <sys/syslog.h> #include <sys/malloc.h> #include <sys/kprintf.h> @@ -213,6 +214,8 @@ int bootopt; va_list ap; + spldebug_stop(); + if (lwp0.l_cpu && curlwp) { /* * Disable preemption. If already panicing on another CPU, sit Index: src/sys/sys/systm.h diff -u src/sys/sys/systm.h:1.236 src/sys/sys/systm.h:1.237 --- src/sys/sys/systm.h:1.236 Tue Oct 6 21:07:05 2009 +++ src/sys/sys/systm.h Tue Nov 3 05:23:28 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: systm.h,v 1.236 2009/10/06 21:07:05 elad Exp $ */ +/* $NetBSD: systm.h,v 1.237 2009/11/03 05:23:28 dyoung Exp $ */ /*- * Copyright (c) 1982, 1988, 1991, 1993 @@ -139,6 +139,7 @@ /* * General function declarations. */ +void voidop(void); int nullop(void *); int enodev(void); int enosys(void); Added files: Index: src/sys/kern/subr_spldebug.c diff -u /dev/null src/sys/kern/subr_spldebug.c:1.1 --- /dev/null Tue Nov 3 05:23:28 2009 +++ src/sys/kern/subr_spldebug.c Tue Nov 3 05:23:28 2009 @@ -0,0 +1,134 @@ +/* $NetBSD: subr_spldebug.c,v 1.1 2009/11/03 05:23:28 dyoung Exp $ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David Young. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Interrupt priority level debugging code. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: subr_spldebug.c,v 1.1 2009/11/03 05:23:28 dyoung Exp $"); + +#include <sys/param.h> +#include <sys/spldebug.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/cpu.h> +#include <machine/return.h> + +__strong_alias(spldebug_start, _spldebug_start); +__strong_alias(spldebug_stop, _spldebug_stop); + +#define SPLRAISE_STACKLEN 32 + +void *splraise_retaddrs[MAXCPUS][SPLRAISE_STACKLEN][4]; +int splraise_depth[MAXCPUS] = {0}; +int spllowered_to[MAXCPUS] = {0}; +void *spllowered_from[MAXCPUS][2] = {{0}}; +bool spldebug = false; + +void _spldebug_start(void); +void _spldebug_stop(void); + +void +_spldebug_start(void) +{ + spldebug = true; +} + +void +_spldebug_stop(void) +{ + spldebug = false; +} + +void +spldebug_lower(int ipl) +{ + struct cpu_info *ci; + + if (!spldebug) + return; + + if (ipl >= IPL_HIGH) + return; + + if (cold) + ci = &cpu_info_primary; + else + ci = curcpu(); + + if (cpu_index(ci) > MAXCPUS) + return; + + splraise_depth[cpu_index(ci)] = 0; + spllowered_to[cpu_index(ci)] = ipl; +#if 0 + spllowered_from[cpu_index(ci)][0] = return_address(0); + spllowered_from[cpu_index(ci)][1] = return_address(1); +#endif +} + +void +spldebug_raise(int ipl) +{ + int i; + void **retaddrs; + struct cpu_info *ci; + + if (!spldebug) + return; + + if (ipl < IPL_HIGH) + return; + + if (cold) + ci = &cpu_info_primary; + else + ci = curcpu(); + + if (cpu_index(ci) >= MAXCPUS) + return; + + if (splraise_depth[cpu_index(ci)] >= SPLRAISE_STACKLEN) + return; + + retaddrs = &splraise_retaddrs[cpu_index(ci)] + [splraise_depth[cpu_index(ci)]++][0]; + + retaddrs[0] = retaddrs[1] = retaddrs[2] = retaddrs[3] = NULL; + + for (i = 0; i < 4; i++) { + retaddrs[i] = return_address(i); + + if (retaddrs[i] == NULL) + break; + } +} Index: src/sys/sys/spldebug.h diff -u /dev/null src/sys/sys/spldebug.h:1.1 --- /dev/null Tue Nov 3 05:23:28 2009 +++ src/sys/sys/spldebug.h Tue Nov 3 05:23:28 2009 @@ -0,0 +1,41 @@ +/* $NetBSD: spldebug.h,v 1.1 2009/11/03 05:23:28 dyoung Exp $ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David Young. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef __SYS_SPLDEBUG_H__ +#define __SYS_SPLDEBUG_H__ + +void spldebug_start(void); +void spldebug_stop(void); + +void spldebug_lower(int); +void spldebug_raise(int); + +#endif /* __SYS_SPLDEBUG_H__ */