Index: sys/lwp.h =================================================================== RCS file: /cvsroot/src/sys/sys/lwp.h,v retrieving revision 1.179 diff -p -u -r1.179 lwp.h --- sys/lwp.h 19 Apr 2018 21:19:07 -0000 1.179 +++ sys/lwp.h 28 Nov 2018 12:04:10 -0000 @@ -258,6 +258,7 @@ extern int maxlwp __read_mostly; /* max #define LP_VFORKWAIT 0x00000200 /* Waiting at vfork() for a child */ #define LP_SINGLESTEP 0x00000400 /* Single step thread in ptrace(2) */ #define LP_TIMEINTR 0x00010000 /* Time this soft interrupt */ +#define LP_PREEMPTING 0x00020000 /* mi_switch called involuntarily */ #define LP_RUNNING 0x20000000 /* Active on a CPU */ #define LP_BOUND 0x80000000 /* Bound to a CPU */ Index: kern/kern_synch.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_synch.c,v retrieving revision 1.318 diff -p -u -r1.318 kern_synch.c --- kern/kern_synch.c 14 Aug 2018 01:06:01 -0000 1.318 +++ kern/kern_synch.c 28 Nov 2018 12:04:14 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_synch.c,v 1.318 2018/08/14 01:06:01 ozaki-r Exp $ */ +/* $NetBSD: kern_synch.c,v 1.319 2018/11/28 09:44:49 mlelstv Exp $ */ /*- * Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2009 @@ -69,7 +69,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.318 2018/08/14 01:06:01 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.319 2018/11/28 09:44:49 mlelstv Exp $"); #include "opt_kstack.h" #include "opt_dtrace.h" @@ -286,12 +286,16 @@ preempt(void) { struct lwp *l = curlwp; + /* check if the scheduler has another LWP to run */ + if ((l->l_cpu->ci_schedstate.spc_flags & SPCF_SHOULDYIELD) == 0) + return; + KERNEL_UNLOCK_ALL(l, &l->l_biglocks); lwp_lock(l); KASSERT(lwp_locked(l, l->l_cpu->ci_schedstate.spc_lwplock)); KASSERT(l->l_stat == LSONPROC); l->l_kpriority = false; - l->l_nivcsw++; + l->l_pflag |= LP_PREEMPTING; (void)mi_switch(l); KERNEL_LOCK(l->l_biglocks, l); } @@ -649,6 +653,9 @@ mi_switch(lwp_t *l) KASSERT(l->l_ctxswtch == 0); l->l_ctxswtch = 1; l->l_ncsw++; + if ((l->l_pflag & LP_PREEMPTING) != 0) + l->l_nivcsw++; + l->l_pflag &= ~LP_PREEMPTING; KASSERT((l->l_pflag & LP_RUNNING) != 0); l->l_pflag &= ~LP_RUNNING; @@ -752,6 +759,7 @@ mi_switch(lwp_t *l) /* Nothing to do - just unlock and return. */ pserialize_switchpoint(); mutex_spin_exit(spc->spc_mutex); + l->l_pflag &= ~LP_PREEMPTING; lwp_unlock(l); retval = 0; }