Module Name: src Committed By: ad Date: Thu Mar 26 20:19:06 UTC 2020
Modified Files: src/sys/kern: kern_lwp.c kern_softint.c src/sys/sys: intr.h userret.h Log Message: softint_overlay() (slow case) gains ~nothing but creates potential headaches. In the interests of simplicity remove it and always use the kthreads. To generate a diff of this commit: cvs rdiff -u -r1.229 -r1.230 src/sys/kern/kern_lwp.c cvs rdiff -u -r1.62 -r1.63 src/sys/kern/kern_softint.c cvs rdiff -u -r1.19 -r1.20 src/sys/sys/intr.h cvs rdiff -u -r1.32 -r1.33 src/sys/sys/userret.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/kern/kern_lwp.c diff -u src/sys/kern/kern_lwp.c:1.229 src/sys/kern/kern_lwp.c:1.230 --- src/sys/kern/kern_lwp.c:1.229 Sun Mar 8 17:04:45 2020 +++ src/sys/kern/kern_lwp.c Thu Mar 26 20:19:06 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_lwp.c,v 1.229 2020/03/08 17:04:45 ad Exp $ */ +/* $NetBSD: kern_lwp.c,v 1.230 2020/03/26 20:19:06 ad Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2019, 2020 @@ -211,7 +211,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.229 2020/03/08 17:04:45 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.230 2020/03/26 20:19:06 ad Exp $"); #include "opt_ddb.h" #include "opt_lockdebug.h" @@ -1593,12 +1593,6 @@ lwp_userret(struct lwp *l) KASSERT(l->l_stat == LSONPROC); p = l->l_proc; -#ifndef __HAVE_FAST_SOFTINTS - /* Run pending soft interrupts. */ - if (l->l_cpu->ci_data.cpu_softints != 0) - softint_overlay(); -#endif - /* * It is safe to do this read unlocked on a MP system.. */ Index: src/sys/kern/kern_softint.c diff -u src/sys/kern/kern_softint.c:1.62 src/sys/kern/kern_softint.c:1.63 --- src/sys/kern/kern_softint.c:1.62 Sun Mar 8 15:05:18 2020 +++ src/sys/kern/kern_softint.c Thu Mar 26 20:19:06 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_softint.c,v 1.62 2020/03/08 15:05:18 ad Exp $ */ +/* $NetBSD: kern_softint.c,v 1.63 2020/03/26 20:19:06 ad 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.62 2020/03/08 15:05:18 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.63 2020/03/26 20:19:06 ad Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -196,7 +196,7 @@ typedef struct softint { uintptr_t si_machdep; struct evcnt si_evcnt; struct evcnt si_evcnt_block; - int si_active; + volatile int si_active; char si_name[8]; char si_name_block[8+6]; } softint_t; @@ -546,11 +546,7 @@ softint_execute(softint_t *si, lwp_t *l, { softhand_t *sh; -#ifdef __HAVE_FAST_SOFTINTS KASSERT(si->si_lwp == curlwp); -#else - /* May be running in user context. */ -#endif KASSERT(si->si_cpu == curcpu()); KASSERT(si->si_lwp->l_wchan == NULL); KASSERT(si->si_active); @@ -678,12 +674,22 @@ softint_trigger(uintptr_t machdep) ci = curcpu(); ci->ci_data.cpu_softints |= machdep; l = ci->ci_onproc; + + /* + * Arrange for mi_switch() to be called. If called from interrupt + * mode, we don't know if curlwp is executing in kernel or user, so + * post an AST and have it take a trip through userret(). If not in + * interrupt mode, curlwp is running in kernel and will notice the + * resched soon enough; avoid the AST. + */ if (l == ci->ci_data.cpu_idlelwp) { atomic_or_uint(&ci->ci_want_resched, RESCHED_IDLE | RESCHED_UPREEMPT); } else { - /* MI equivalent of aston() */ - cpu_signotify(l); + atomic_or_uint(&ci->ci_want_resched, RESCHED_UPREEMPT); + if (cpu_intr_p()) { + cpu_signotify(l); + } } } @@ -754,65 +760,6 @@ softint_picklwp(void) return l; } -/* - * softint_overlay: - * - * Slow path: called from lwp_userret() to run a soft interrupt - * within the context of a user thread. - */ -void -softint_overlay(void) -{ - struct cpu_info *ci; - u_int softints, oflag; - softint_t *si; - pri_t obase; - lwp_t *l; - int s; - - l = curlwp; - KASSERT((l->l_pflag & LP_INTR) == 0); - - /* - * Arrange to elevate priority if the LWP blocks. Also, bind LWP - * to the CPU. Note: disable kernel preemption before doing that. - */ - s = splhigh(); - ci = l->l_cpu; - si = ((softcpu_t *)ci->ci_data.cpu_softcpu)->sc_int; - - obase = l->l_kpribase; - l->l_kpribase = PRI_KERNEL_RT; - oflag = l->l_pflag; - l->l_pflag = oflag | LP_INTR | LP_BOUND; - - while ((softints = ci->ci_data.cpu_softints) != 0) { - if ((softints & (1 << SOFTINT_SERIAL)) != 0) { - ci->ci_data.cpu_softints &= ~(1 << SOFTINT_SERIAL); - softint_execute(&si[SOFTINT_SERIAL], l, s); - continue; - } - if ((softints & (1 << SOFTINT_NET)) != 0) { - ci->ci_data.cpu_softints &= ~(1 << SOFTINT_NET); - softint_execute(&si[SOFTINT_NET], l, s); - continue; - } - if ((softints & (1 << SOFTINT_BIO)) != 0) { - ci->ci_data.cpu_softints &= ~(1 << SOFTINT_BIO); - softint_execute(&si[SOFTINT_BIO], l, s); - continue; - } - if ((softints & (1 << SOFTINT_CLOCK)) != 0) { - ci->ci_data.cpu_softints &= ~(1 << SOFTINT_CLOCK); - softint_execute(&si[SOFTINT_CLOCK], l, s); - continue; - } - } - l->l_pflag = oflag; - l->l_kpribase = obase; - splx(s); -} - #else /* !__HAVE_FAST_SOFTINTS */ /* @@ -892,20 +839,13 @@ softint_dispatch(lwp_t *pinned, int s) /* * If we blocked while handling the interrupt, the pinned LWP is - * gone so switch to the idle LWP. It will select a new LWP to - * run. - * - * We must drop the priority level as switching at IPL_HIGH could - * deadlock the system. We have already set si->si_active = 0, - * which means another interrupt at this level can be triggered. - * That's not be a problem: we are lowering to level 's' which will - * prevent softint_dispatch() from being reentered at level 's', - * until the priority is finally dropped to IPL_NONE on entry to - * the LWP chosen by mi_switch(). + * gone, so find another LWP to run. It will select a new LWP to + * run. softint_dispatch() won't be reentered until the priority + * is finally dropped to IPL_NONE on entry to the LWP chosen by + * mi_switch(). */ l->l_stat = LSIDL; if (l->l_switchto == NULL) { - splx(s); lwp_lock(l); spc_lock(l->l_cpu); mi_switch(l); Index: src/sys/sys/intr.h diff -u src/sys/sys/intr.h:1.19 src/sys/sys/intr.h:1.20 --- src/sys/sys/intr.h:1.19 Mon Aug 17 06:16:03 2015 +++ src/sys/sys/intr.h Thu Mar 26 20:19:06 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.19 2015/08/17 06:16:03 knakahara Exp $ */ +/* $NetBSD: intr.h,v 1.20 2020/03/26 20:19:06 ad Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -50,7 +50,6 @@ void softint_schedule_cpu(void *, struct /* MI hooks. */ void softint_init(struct cpu_info *); lwp_t *softint_picklwp(void); -void softint_overlay(void); void softint_block(lwp_t *); /* MD-MI interface. */ Index: src/sys/sys/userret.h diff -u src/sys/sys/userret.h:1.32 src/sys/sys/userret.h:1.33 --- src/sys/sys/userret.h:1.32 Wed Jan 22 12:23:04 2020 +++ src/sys/sys/userret.h Thu Mar 26 20:19:06 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: userret.h,v 1.32 2020/01/22 12:23:04 ad Exp $ */ +/* $NetBSD: userret.h,v 1.33 2020/03/26 20:19:06 ad Exp $ */ /*- * Copyright (c) 1998, 2000, 2003, 2006, 2008, 2019, 2020 @@ -91,11 +91,7 @@ mi_userret(struct lwp *l) preempt(); ci = l->l_cpu; } -#ifdef __HAVE_FAST_SOFTINTS if (__predict_false(l->l_flag & LW_USERRET)) { -#else - if (((l->l_flag & LW_USERRET) | ci->ci_data.cpu_softints) != 0) { -#endif KPREEMPT_ENABLE(l); lwp_userret(l); KPREEMPT_DISABLE(l);