Module Name: src Committed By: martin Date: Wed Sep 11 10:09:19 UTC 2024
Modified Files: src/sys/arch/x86/x86 [netbsd-10]: intr.c src/sys/kern [netbsd-10]: kern_idle.c kern_softint.c subr_workqueue.c subr_xcall.c Log Message: Pull up following revision(s) (requested by rin in ticket #821): sys/arch/x86/x86/intr.c: revision 1.169 sys/kern/kern_softint.c: revision 1.76 sys/kern/subr_workqueue.c: revision 1.48 sys/kern/kern_idle.c: revision 1.36 sys/kern/subr_xcall.c: revision 1.38 check that l_nopreempt (preemption count) doesn't change after callbacks check that the idle loop, soft interrupt handlers, workqueue, and xcall callbacks do not modify the preemption count, in most cases, knowing it should be 0 currently. this work was originally done by simonb. cleaned up slightly and some minor enhancement made by myself, and with discussion with riastradh@. other callback call sites could check this as well (such as MD interrupt handlers, or really anything that includes a callback registration. x86 version to be commited separately.) 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.163.2.1 -r1.163.2.2 src/sys/arch/x86/x86/intr.c cvs rdiff -u -r1.34 -r1.34.20.1 src/sys/kern/kern_idle.c cvs rdiff -u -r1.72 -r1.72.2.1 src/sys/kern/kern_softint.c cvs rdiff -u -r1.41.2.1 -r1.41.2.2 src/sys/kern/subr_workqueue.c cvs rdiff -u -r1.34 -r1.34.18.1 src/sys/kern/subr_xcall.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.163.2.1 src/sys/arch/x86/x86/intr.c:1.163.2.2 --- src/sys/arch/x86/x86/intr.c:1.163.2.1 Sat Apr 1 15:11:00 2023 +++ src/sys/arch/x86/x86/intr.c Wed Sep 11 10:09:19 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.163.2.1 2023/04/01 15:11:00 martin Exp $ */ +/* $NetBSD: intr.c,v 1.163.2.2 2024/09/11 10:09:19 martin 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.163.2.1 2023/04/01 15:11:00 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.163.2.2 2024/09/11 10:09:19 martin Exp $"); #include "opt_intrdebug.h" #include "opt_multiprocessor.h" @@ -658,21 +658,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); @@ -681,11 +685,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 @@ -693,13 +714,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; } @@ -963,6 +990,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 */ Index: src/sys/kern/kern_idle.c diff -u src/sys/kern/kern_idle.c:1.34 src/sys/kern/kern_idle.c:1.34.20.1 --- src/sys/kern/kern_idle.c:1.34 Sat Sep 5 16:30:12 2020 +++ src/sys/kern/kern_idle.c Wed Sep 11 10:09:19 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_idle.c,v 1.34 2020/09/05 16:30:12 riastradh Exp $ */ +/* $NetBSD: kern_idle.c,v 1.34.20.1 2024/09/11 10:09:19 martin Exp $ */ /*- * Copyright (c)2002, 2006, 2007 YAMAMOTO Takashi, @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_idle.c,v 1.34 2020/09/05 16:30:12 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_idle.c,v 1.34.20.1 2024/09/11 10:09:19 martin Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -74,6 +74,8 @@ idle_loop(void *dummy) KASSERT(l == curlwp); KASSERT(CURCPU_IDLE_P()); KASSERT(l->l_priority == PRI_IDLE); + KASSERTMSG(l->l_nopreempt == 0, "lwp %p nopreempt %d", + l, l->l_nopreempt); sched_idle(); if (!sched_curcpu_runnable_p()) { Index: src/sys/kern/kern_softint.c diff -u src/sys/kern/kern_softint.c:1.72 src/sys/kern/kern_softint.c:1.72.2.1 --- src/sys/kern/kern_softint.c:1.72 Fri Oct 28 21:52:02 2022 +++ src/sys/kern/kern_softint.c Wed Sep 11 10:09:19 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_softint.c,v 1.72 2022/10/28 21:52:02 riastradh Exp $ */ +/* $NetBSD: kern_softint.c,v 1.72.2.1 2024/09/11 10:09:19 martin Exp $ */ /*- * Copyright (c) 2007, 2008, 2019, 2020 The NetBSD Foundation, Inc. @@ -170,7 +170,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.72 2022/10/28 21:52:02 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.72.2.1 2024/09/11 10:09:19 martin Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -567,6 +567,8 @@ softint_execute(lwp_t *l, int s) KASSERT(si->si_cpu == curcpu()); KASSERT(si->si_lwp->l_wchan == NULL); KASSERT(si->si_active); + KASSERTMSG(l->l_nopreempt == 0, "lwp %p nopreempt %d", + l, l->l_nopreempt); /* * Note: due to priority inheritance we may have interrupted a @@ -614,6 +616,10 @@ softint_execute(lwp_t *l, int s) KASSERTMSG(l->l_blcnt == 0, "%s: sh_func=%p leaked %d biglocks", __func__, sh->sh_func, curlwp->l_blcnt); + /* Diagnostic: check that LWP nopreempt remains zero. */ + KASSERTMSG(l->l_nopreempt == 0, + "%s: lwp %p nopreempt %d func %p", + __func__, l, l->l_nopreempt, sh->sh_func); (void)splhigh(); } Index: src/sys/kern/subr_workqueue.c diff -u src/sys/kern/subr_workqueue.c:1.41.2.1 src/sys/kern/subr_workqueue.c:1.41.2.2 --- src/sys/kern/subr_workqueue.c:1.41.2.1 Mon Sep 4 16:57:56 2023 +++ src/sys/kern/subr_workqueue.c Wed Sep 11 10:09:19 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_workqueue.c,v 1.41.2.1 2023/09/04 16:57:56 martin Exp $ */ +/* $NetBSD: subr_workqueue.c,v 1.41.2.2 2024/09/11 10:09:19 martin Exp $ */ /*- * Copyright (c)2002, 2005, 2006, 2007 YAMAMOTO Takashi, @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_workqueue.c,v 1.41.2.1 2023/09/04 16:57:56 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_workqueue.c,v 1.41.2.2 2024/09/11 10:09:19 martin Exp $"); #include <sys/param.h> @@ -140,6 +140,10 @@ workqueue_runlist(struct workqueue *wq, { work_impl_t *wk; work_impl_t *next; + struct lwp *l = curlwp; + + KASSERTMSG(l->l_nopreempt == 0, "lwp %p nopreempt %d", + l, l->l_nopreempt); for (wk = SIMPLEQ_FIRST(list); wk != NULL; wk = next) { next = SIMPLEQ_NEXT(wk, wk_entry); @@ -148,6 +152,9 @@ workqueue_runlist(struct workqueue *wq, (*wq->wq_func)((void *)wk, wq->wq_arg); SDT_PROBE4(sdt, kernel, workqueue, return, wq, wk, wq->wq_func, wq->wq_arg); + KASSERTMSG(l->l_nopreempt == 0, + "lwp %p nopreempt %d func %p", + l, l->l_nopreempt, wq->wq_func); } } Index: src/sys/kern/subr_xcall.c diff -u src/sys/kern/subr_xcall.c:1.34 src/sys/kern/subr_xcall.c:1.34.18.1 --- src/sys/kern/subr_xcall.c:1.34 Tue Dec 22 01:57:29 2020 +++ src/sys/kern/subr_xcall.c Wed Sep 11 10:09:19 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_xcall.c,v 1.34 2020/12/22 01:57:29 ad Exp $ */ +/* $NetBSD: subr_xcall.c,v 1.34.18.1 2024/09/11 10:09:19 martin Exp $ */ /*- * Copyright (c) 2007-2010, 2019 The NetBSD Foundation, Inc. @@ -74,7 +74,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_xcall.c,v 1.34 2020/12/22 01:57:29 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_xcall.c,v 1.34.18.1 2024/09/11 10:09:19 martin Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -420,6 +420,10 @@ xc_thread(void *cookie) xc_state_t *xc = &xc_low_pri; void *arg1, *arg2; xcfunc_t func; + struct lwp *l = curlwp; + + KASSERTMSG(l->l_nopreempt == 0, "lwp %p nopreempt %d", + l, l->l_nopreempt); mutex_enter(&xc->xc_lock); for (;;) { @@ -439,6 +443,9 @@ xc_thread(void *cookie) KASSERT(func != NULL); (*func)(arg1, arg2); + KASSERTMSG(l->l_nopreempt == 0, "lwp %p nopreempt %d func %p", + l, l->l_nopreempt, func); + mutex_enter(&xc->xc_lock); #ifdef __HAVE_ATOMIC64_LOADSTORE atomic_store_release(&xc->xc_donep, xc->xc_donep + 1);