Module Name: src Committed By: mrg Date: Wed Sep 11 05:17:45 UTC 2024
Modified Files: src/sys/arch/x86/x86: intr.c Log Message: apply some more diagnostic checks for x86 interrupts convert intr_biglock_wrapper() into a slight less complete intr_wrapper(), and move the kernel lock/unlock points into the new intr_biglock_wrapper(). add curlwp->l_nopreempt checking for interrupt handlers, including the dtrace wrapper. XXX: has to copy the i8254_clockintr hack. tested for a few months by myself, and recently by rin@ on both current and netbsd-10. thanks! To generate a diff of this commit: cvs rdiff -u -r1.168 -r1.169 src/sys/arch/x86/x86/intr.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/x86/x86/intr.c diff -u src/sys/arch/x86/x86/intr.c:1.168 src/sys/arch/x86/x86/intr.c:1.169 --- src/sys/arch/x86/x86/intr.c:1.168 Mon Apr 22 22:29:28 2024 +++ src/sys/arch/x86/x86/intr.c Wed Sep 11 05:17:45 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.168 2024/04/22 22:29:28 andvar Exp $ */ +/* $NetBSD: intr.c,v 1.169 2024/09/11 05:17:45 mrg Exp $ */ /* * Copyright (c) 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc. @@ -133,7 +133,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.168 2024/04/22 22:29:28 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.169 2024/09/11 05:17:45 mrg Exp $"); #include "opt_acpi.h" #include "opt_intrdebug.h" @@ -659,21 +659,25 @@ intr_source_free(struct cpu_info *ci, in #ifdef MULTIPROCESSOR static int intr_biglock_wrapper(void *); +static int intr_wrapper(void *); /* + * intr_wrapper: perform diagnostic checks before and after calling the + * real handler. * intr_biglock_wrapper: grab biglock and call a real interrupt handler. */ static int -intr_biglock_wrapper(void *vp) +intr_wrapper(void *vp) { struct intrhand *ih = vp; + struct lwp *l = curlwp; int locks; + int nopreempt; int ret; - KERNEL_LOCK(1, NULL); - locks = curcpu()->ci_biglock_count; + nopreempt = l->l_nopreempt; SDT_PROBE3(sdt, kernel, intr, entry, ih->ih_realfun, ih->ih_realarg, ih); ret = (*ih->ih_realfun)(ih->ih_realarg); @@ -682,11 +686,28 @@ intr_biglock_wrapper(void *vp) KASSERTMSG(locks == curcpu()->ci_biglock_count, "%s @ %p slipped locks %d -> %d", ih->ih_xname, ih->ih_realfun, locks, curcpu()->ci_biglock_count); + KASSERTMSG(nopreempt == l->l_nopreempt, + "%s @ %p slipped nopreempt %d -> %d lwp %p/%p func %p", + ih->ih_xname, ih->ih_realfun, nopreempt, l->l_nopreempt, l, curlwp, + ih->ih_realfun); + + return ret; +} + +static int +intr_biglock_wrapper(void *vp) +{ + int ret; + + KERNEL_LOCK(1, NULL); + + ret = intr_wrapper(vp); KERNEL_UNLOCK_ONE(NULL); return ret; } + #endif /* MULTIPROCESSOR */ #ifdef KDTRACE_HOOKS @@ -694,13 +715,19 @@ static int intr_kdtrace_wrapper(void *vp) { struct intrhand *ih = vp; + struct lwp *l = curlwp; int ret; + int nopreempt; + nopreempt = l->l_nopreempt; SDT_PROBE3(sdt, kernel, intr, entry, ih->ih_realfun, ih->ih_realarg, ih); ret = (*ih->ih_realfun)(ih->ih_realarg); SDT_PROBE4(sdt, kernel, intr, return, ih->ih_realfun, ih->ih_realarg, ih, ret); + KASSERTMSG(nopreempt == l->l_nopreempt, + "%s @ %p slipped nopreempt %d -> %d lwp %p/%p", + ih->ih_xname, ih->ih_realfun, nopreempt, l->l_nopreempt, l, curlwp); return ret; } @@ -966,6 +993,15 @@ intr_establish_xname(int legacy_irq, str __FPTRCAST(int (*)(void *), i8254_clockintr)); ih->ih_fun = intr_biglock_wrapper; ih->ih_arg = ih; + } else { + if (handler != + __FPTRCAST(int (*)(void *), i8254_clockintr)) { /* XXX */ +#ifdef DIAGNOSTIC + /* wrap all interrupts */ + ih->ih_fun = intr_wrapper; + ih->ih_arg = ih; +#endif + } } #endif /* MULTIPROCESSOR */