Module Name:    src
Committed By:   ad
Date:           Sat Nov 23 19:40:38 UTC 2019

Modified Files:
        src/sys/arch/aarch64/aarch64: cpu_machdep.c
        src/sys/arch/alpha/alpha: machdep.c
        src/sys/arch/amiga/include: cpu.h
        src/sys/arch/arm/arm: arm_machdep.c
        src/sys/arch/arm/arm32: genassym.cf
        src/sys/arch/atari/include: cpu.h
        src/sys/arch/cesfic/include: cpu.h
        src/sys/arch/evbcf/include: cpu.h
        src/sys/arch/hp300/include: cpu.h
        src/sys/arch/hppa/hppa: hppa_machdep.c
        src/sys/arch/ia64/include: cpu.h
        src/sys/arch/luna68k/include: cpu.h
        src/sys/arch/mac68k/include: cpu.h
        src/sys/arch/mips/mips: cpu_subr.c ipifuncs.c
        src/sys/arch/mvme68k/include: cpu.h
        src/sys/arch/news68k/include: cpu.h
        src/sys/arch/next68k/include: cpu.h
        src/sys/arch/powerpc/booke: e500_intr.c
        src/sys/arch/powerpc/include: cpu.h
        src/sys/arch/powerpc/include/booke: intr.h
        src/sys/arch/powerpc/powerpc: genassym.cf powerpc_machdep.c
        src/sys/arch/riscv/riscv: genassym.cf riscv_machdep.c
        src/sys/arch/sh3/include: cpu.h
        src/sys/arch/sparc/include: cpu.h
        src/sys/arch/sparc64/include: cpu.h
        src/sys/arch/sparc64/sparc64: genassym.cf machdep.c
        src/sys/arch/sun68k/include: cpu.h
        src/sys/arch/usermode/dev: cpu.c
        src/sys/arch/usermode/include: cpu.h
        src/sys/arch/vax/include: cpu.h
        src/sys/arch/x68k/include: cpu.h
        src/sys/arch/x86/include: cpu.h intrdefs.h
        src/sys/arch/x86/x86: cpu.c ipi.c x86_machdep.c
        src/sys/arch/xen/include: intrdefs.h
        src/sys/arch/xen/x86: cpu.c xen_ipi.c

Log Message:
cpu_need_resched():

- Remove all code that should be MI, leaving the bare minimum under arch/.
- Make the required actions very explicit.
- Pass in LWP pointer for convenience.
- When a trap is required on another CPU, have the IPI set it locally.
- Expunge cpu_did_resched().


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/aarch64/aarch64/cpu_machdep.c
cvs rdiff -u -r1.354 -r1.355 src/sys/arch/alpha/alpha/machdep.c
cvs rdiff -u -r1.82 -r1.83 src/sys/arch/amiga/include/cpu.h
cvs rdiff -u -r1.55 -r1.56 src/sys/arch/arm/arm/arm_machdep.c
cvs rdiff -u -r1.80 -r1.81 src/sys/arch/arm/arm32/genassym.cf
cvs rdiff -u -r1.72 -r1.73 src/sys/arch/atari/include/cpu.h
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/cesfic/include/cpu.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbcf/include/cpu.h
cvs rdiff -u -r1.71 -r1.72 src/sys/arch/hp300/include/cpu.h
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/hppa/hppa/hppa_machdep.c
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/ia64/include/cpu.h
cvs rdiff -u -r1.36 -r1.37 src/sys/arch/luna68k/include/cpu.h
cvs rdiff -u -r1.101 -r1.102 src/sys/arch/mac68k/include/cpu.h
cvs rdiff -u -r1.35 -r1.36 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/mips/mips/ipifuncs.c
cvs rdiff -u -r1.50 -r1.51 src/sys/arch/mvme68k/include/cpu.h
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/news68k/include/cpu.h
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/next68k/include/cpu.h
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/powerpc/booke/e500_intr.c
cvs rdiff -u -r1.108 -r1.109 src/sys/arch/powerpc/include/cpu.h
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/powerpc/include/booke/intr.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/powerpc/powerpc/genassym.cf
cvs rdiff -u -r1.73 -r1.74 src/sys/arch/powerpc/powerpc/powerpc_machdep.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/riscv/riscv/genassym.cf \
    src/sys/arch/riscv/riscv/riscv_machdep.c
cvs rdiff -u -r1.57 -r1.58 src/sys/arch/sh3/include/cpu.h
cvs rdiff -u -r1.101 -r1.102 src/sys/arch/sparc/include/cpu.h
cvs rdiff -u -r1.126 -r1.127 src/sys/arch/sparc64/include/cpu.h
cvs rdiff -u -r1.81 -r1.82 src/sys/arch/sparc64/sparc64/genassym.cf
cvs rdiff -u -r1.292 -r1.293 src/sys/arch/sparc64/sparc64/machdep.c
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/sun68k/include/cpu.h
cvs rdiff -u -r1.80 -r1.81 src/sys/arch/usermode/dev/cpu.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/usermode/include/cpu.h
cvs rdiff -u -r1.102 -r1.103 src/sys/arch/vax/include/cpu.h
cvs rdiff -u -r1.61 -r1.62 src/sys/arch/x68k/include/cpu.h
cvs rdiff -u -r1.112 -r1.113 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/x86/include/intrdefs.h
cvs rdiff -u -r1.175 -r1.176 src/sys/arch/x86/x86/cpu.c
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/x86/x86/ipi.c
cvs rdiff -u -r1.128 -r1.129 src/sys/arch/x86/x86/x86_machdep.c
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/xen/include/intrdefs.h
cvs rdiff -u -r1.130 -r1.131 src/sys/arch/xen/x86/cpu.c
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/xen/x86/xen_ipi.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/aarch64/aarch64/cpu_machdep.c
diff -u src/sys/arch/aarch64/aarch64/cpu_machdep.c:1.7 src/sys/arch/aarch64/aarch64/cpu_machdep.c:1.8
--- src/sys/arch/aarch64/aarch64/cpu_machdep.c:1.7	Thu Nov 21 19:57:23 2019
+++ src/sys/arch/aarch64/aarch64/cpu_machdep.c	Sat Nov 23 19:40:34 2019
@@ -1,7 +1,7 @@
-/* $NetBSD: cpu_machdep.c,v 1.7 2019/11/21 19:57:23 ad Exp $ */
+/* $NetBSD: cpu_machdep.c,v 1.8 2019/11/23 19:40:34 ad Exp $ */
 
 /*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2014, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: cpu_machdep.c,v 1.7 2019/11/21 19:57:23 ad Exp $");
+__KERNEL_RCSID(1, "$NetBSD: cpu_machdep.c,v 1.8 2019/11/23 19:40:34 ad Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -124,7 +124,8 @@ dosoftints(void)
 		if (softints == 0) {
 #ifdef __HAVE_PREEMPTION
 			if (ci->ci_want_resched & RESCHED_KPREEMPT) {
-				ci->ci_want_resched &= ~RESCHED_KPREEMPT;
+				atomic_and_uint(&ci->ci_want_resched,
+				    ~RESCHED_KPREEMPT);
 				splsched();
 				kpreempt(-2);
 			}
@@ -233,60 +234,25 @@ startlwp(void *arg)
 }
 
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
-	struct lwp * const l = ci->ci_data.cpu_onproc;
-#ifdef MULTIPROCESSOR
-	struct cpu_info * const cur_ci = curcpu();
-#endif
-
 	KASSERT(kpreempt_disabled());
 
-	ci->ci_want_resched |= flags;
-
-	if (__predict_false((l->l_pflag & LP_INTR) != 0)) {
-		/*
-		 * No point doing anything, it will switch soon.
-		 * Also here to prevent an assertion failure in
-		 * kpreempt() due to preemption being set on a
-		 * soft interrupt LWP.
-		 */
-		return;
-	}
-
-	if (__predict_false(l == ci->ci_data.cpu_idlelwp)) {
-#ifdef MULTIPROCESSOR
-		/*
-		 * If the other CPU is idling, it must be waiting for an
-		 * interrupt.  So give it one.
-		 */
-		if (__predict_false(ci != cur_ci))
-			intr_ipi_send(ci->ci_kcpuset, IPI_NOP);
-#endif
-		return;
-	}
-
-#ifdef MULTIPROCESSOR
-	atomic_or_uint(&ci->ci_want_resched, flags);
-#else
-	ci->ci_want_resched |= flags;
-#endif
-
-	if (flags & RESCHED_KPREEMPT) {
+	if ((flags & RESCHED_KPREEMPT) != 0) {
 #ifdef __HAVE_PREEMPTION
-		atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE);
-		if (ci != cur_ci) {
+		if ((flags & RESCHED_REMOTE) != 0) {
 			intr_ipi_send(ci->ci_kcpuset, IPI_KPREEMPT);
 		}
 #endif
 		return;
 	}
-	setsoftast(ci);	/* force call to ast() */
+	if ((flags & RESCHED_REMOTE) != 0) {
 #ifdef MULTIPROCESSOR
-	if (ci != cur_ci && (flags & RESCHED_IMMED)) {
 		intr_ipi_send(ci->ci_kcpuset, IPI_AST);
-	}
 #endif
+	} else {
+		setsoftast(ci);	/* force call to ast() */
+	}
 }
 
 void

Index: src/sys/arch/alpha/alpha/machdep.c
diff -u src/sys/arch/alpha/alpha/machdep.c:1.354 src/sys/arch/alpha/alpha/machdep.c:1.355
--- src/sys/arch/alpha/alpha/machdep.c:1.354	Fri Apr  5 14:12:14 2019
+++ src/sys/arch/alpha/alpha/machdep.c	Sat Nov 23 19:40:34 2019
@@ -1,7 +1,7 @@
-/* $NetBSD: machdep.c,v 1.354 2019/04/05 14:12:14 thorpej Exp $ */
+/* $NetBSD: machdep.c,v 1.355 2019/11/23 19:40:34 ad Exp $ */
 
 /*-
- * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 1999, 2000, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -67,7 +67,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.354 2019/04/05 14:12:14 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.355 2019/11/23 19:40:34 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1866,19 +1866,15 @@ cpu_setmcontext(struct lwp *l, const mco
  * or after the current trap/syscall if in system mode.
  */
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
+	if ((flags & RESCHED_IDLE) == 0) {
+		if ((flags & RESCHED_REMOTE) != 0) {
 #if defined(MULTIPROCESSOR)
-	bool immed = (flags & RESCHED_IMMED) != 0;
+			alpha_send_ipi(ci->ci_cpuid, ALPHA_IPI_AST);
 #endif /* defined(MULTIPROCESSOR) */
-
-	aston(ci->ci_data.cpu_onproc);
-	ci->ci_want_resched = 1;
-	if (ci->ci_data.cpu_onproc != ci->ci_data.cpu_idlelwp) {
-#if defined(MULTIPROCESSOR)
-		if (immed && ci != curcpu()) {
-			alpha_send_ipi(ci->ci_cpuid, 0);
+		} else {
+			aston(l);
 		}
-#endif /* defined(MULTIPROCESSOR) */
 	}
 }

Index: src/sys/arch/amiga/include/cpu.h
diff -u src/sys/arch/amiga/include/cpu.h:1.82 src/sys/arch/amiga/include/cpu.h:1.83
--- src/sys/arch/amiga/include/cpu.h:1.82	Wed Aug 22 01:05:21 2018
+++ src/sys/arch/amiga/include/cpu.h	Sat Nov 23 19:40:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.82 2018/08/22 01:05:21 msaitoh Exp $	*/
+/*	$NetBSD: cpu.h,v 1.83 2019/11/23 19:40:34 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -77,9 +77,8 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	setsoftast();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/arm/arm/arm_machdep.c
diff -u src/sys/arch/arm/arm/arm_machdep.c:1.55 src/sys/arch/arm/arm/arm_machdep.c:1.56
--- src/sys/arch/arm/arm/arm_machdep.c:1.55	Sat Apr  6 03:06:24 2019
+++ src/sys/arch/arm/arm/arm_machdep.c	Sat Nov 23 19:40:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm_machdep.c,v 1.55 2019/04/06 03:06:24 thorpej Exp $	*/
+/*	$NetBSD: arm_machdep.c,v 1.56 2019/11/23 19:40:34 ad Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.55 2019/04/06 03:06:24 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.56 2019/11/23 19:40:34 ad Exp $");
 
 #include <sys/exec.h>
 #include <sys/proc.h>
@@ -223,67 +223,38 @@ startlwp(void *arg)
 }
 
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
-	struct lwp * const l = ci->ci_data.cpu_onproc;
-	const bool immed = (flags & RESCHED_IMMED) != 0;
-#ifdef MULTIPROCESSOR
-	struct cpu_info * const cur_ci = curcpu();
-	u_long ipi = IPI_NOP;
-#endif
-
-	if (__predict_false((l->l_pflag & LP_INTR) != 0)) {
-		/*
-		 * No point doing anything, it will switch soon.
-		 * Also here to prevent an assertion failure in
-		 * kpreempt() due to preemption being set on a
-		 * soft interrupt LWP.
-		 */
-		return;
-	}
-	if (ci->ci_want_resched && !immed)
-		return;
 
-	if (l == ci->ci_data.cpu_idlelwp) {
+	if (flags & RESCHED_IDLE) {
 #ifdef MULTIPROCESSOR
 		/*
 		 * If the other CPU is idling, it must be waiting for an
 		 * event.  So give it one.
 		 */
-		if (ci != cur_ci)
-			goto send_ipi;
+		if (flags & RESCHED_REMOTE) {
+			intr_ipi_send(ci->ci_kcpuset, IPI_NOP);
+		}
 #endif
 		return;
 	}
-#ifdef MULTIPROCESSOR
-	atomic_swap_uint(&ci->ci_want_resched, 1);
-#else
-	ci->ci_want_resched = 1;
-#endif
 	if (flags & RESCHED_KPREEMPT) {
 #ifdef __HAVE_PREEMPTION
-		atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE);
-		if (ci == cur_ci) {
-			atomic_or_uint(&ci->ci_astpending, __BIT(1));
+		if (flags & RESCHED_REMOTE) {
+			intr_ipi_send(ci->ci_kcpuset, IPI_KPREEMPT);
 		} else {
-			ipi = IPI_KPREEMPT;
-			goto send_ipi;
+			atomic_or_uint(&ci->ci_astpending, __BIT(1));
 		}
 #endif /* __HAVE_PREEMPTION */
 		return;
 	}
+	if (flags & RESCHED_REMOTE) {
 #ifdef MULTIPROCESSOR
-	if (ci == cur_ci || !immed) {
+		intr_ipi_send(ci->ci_kcpuset, IPI_AST);
+#endif /* MULTIPROCESSOR */
+	} else {
 		setsoftast(ci);
-		return;
 	}
-	ipi = IPI_AST;
-
-   send_ipi:
-	intr_ipi_send(ci->ci_kcpuset, ipi);
-#else
-	setsoftast(ci);
-#endif /* MULTIPROCESSOR */
 }
 
 bool
@@ -312,14 +283,6 @@ arm_curcpu(void)
 #endif
 
 #ifdef __HAVE_PREEMPTION
-void
-cpu_set_curpri(int pri)
-{
-	kpreempt_disable();
-	curcpu()->ci_schedstate.spc_curpriority = pri;
-	kpreempt_enable();
-}
-
 bool
 cpu_kpreempt_enter(uintptr_t where, int s)
 {

Index: src/sys/arch/arm/arm32/genassym.cf
diff -u src/sys/arch/arm/arm32/genassym.cf:1.80 src/sys/arch/arm/arm32/genassym.cf:1.81
--- src/sys/arch/arm/arm32/genassym.cf:1.80	Thu Oct 18 09:01:52 2018
+++ src/sys/arch/arm/arm32/genassym.cf	Sat Nov 23 19:40:34 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.80 2018/10/18 09:01:52 skrll Exp $
+#	$NetBSD: genassym.cf,v 1.81 2019/11/23 19:40:34 ad Exp $
 
 # Copyright (c) 1982, 1990 The Regents of the University of California.
 # All rights reserved.
@@ -225,7 +225,6 @@ define	CI_ARM_CPUID		offsetof(struct cpu
 define	CI_CURLWP		offsetof(struct cpu_info, ci_curlwp)
 define	CI_CPL			offsetof(struct cpu_info, ci_cpl)
 define	CI_ASTPENDING		offsetof(struct cpu_info, ci_astpending)
-define	CI_WANT_RESCHED		offsetof(struct cpu_info, ci_want_resched)
 define	CI_INTR_DEPTH		offsetof(struct cpu_info, ci_intr_depth)
 define	CI_MTX_COUNT		offsetof(struct cpu_info, ci_mtx_count)
 define	CI_UNDEFSAVE		offsetof(struct cpu_info, ci_undefsave[0])

Index: src/sys/arch/atari/include/cpu.h
diff -u src/sys/arch/atari/include/cpu.h:1.72 src/sys/arch/atari/include/cpu.h:1.73
--- src/sys/arch/atari/include/cpu.h:1.72	Mon Feb 18 01:12:22 2019
+++ src/sys/arch/atari/include/cpu.h	Sat Nov 23 19:40:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.72 2019/02/18 01:12:22 thorpej Exp $	*/
+/*	$NetBSD: cpu.h,v 1.73 2019/11/23 19:40:34 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -85,9 +85,8 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	setsoftast();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/cesfic/include/cpu.h
diff -u src/sys/arch/cesfic/include/cpu.h:1.32 src/sys/arch/cesfic/include/cpu.h:1.33
--- src/sys/arch/cesfic/include/cpu.h:1.32	Mon Feb 18 01:12:22 2019
+++ src/sys/arch/cesfic/include/cpu.h	Sat Nov 23 19:40:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.32 2019/02/18 01:12:22 thorpej Exp $	*/
+/*	$NetBSD: cpu.h,v 1.33 2019/11/23 19:40:34 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -79,9 +79,8 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/evbcf/include/cpu.h
diff -u src/sys/arch/evbcf/include/cpu.h:1.4 src/sys/arch/evbcf/include/cpu.h:1.5
--- src/sys/arch/evbcf/include/cpu.h:1.4	Wed Aug 22 01:05:22 2018
+++ src/sys/arch/evbcf/include/cpu.h	Sat Nov 23 19:40:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.4 2018/08/22 01:05:22 msaitoh Exp $	*/
+/*	$NetBSD: cpu.h,v 1.5 2019/11/23 19:40:35 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -86,8 +86,8 @@ extern volatile unsigned int interrupt_d
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci, flags)	\
-	do { ci->ci_want_resched++; aston(); } while (/* CONSTCOND */0)
+#define	cpu_need_resched(ci,l,flags)	\
+	do { aston(); } while (/* CONSTCOND */0)
 
 /*
  * Give a profiling tick to the current process when the user profiling

Index: src/sys/arch/hp300/include/cpu.h
diff -u src/sys/arch/hp300/include/cpu.h:1.71 src/sys/arch/hp300/include/cpu.h:1.72
--- src/sys/arch/hp300/include/cpu.h:1.71	Mon Feb 18 01:12:23 2019
+++ src/sys/arch/hp300/include/cpu.h	Sat Nov 23 19:40:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.71 2019/02/18 01:12:23 thorpej Exp $	*/
+/*	$NetBSD: cpu.h,v 1.72 2019/11/23 19:40:35 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -88,9 +88,8 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/hppa/hppa/hppa_machdep.c
diff -u src/sys/arch/hppa/hppa/hppa_machdep.c:1.29 src/sys/arch/hppa/hppa/hppa_machdep.c:1.30
--- src/sys/arch/hppa/hppa/hppa_machdep.c:1.29	Mon Feb 24 07:23:43 2014
+++ src/sys/arch/hppa/hppa/hppa_machdep.c	Sat Nov 23 19:40:35 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: hppa_machdep.c,v 1.29 2014/02/24 07:23:43 skrll Exp $	*/
+/*	$NetBSD: hppa_machdep.c,v 1.30 2019/11/23 19:40:35 ad Exp $	*/
 
 /*-
- * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hppa_machdep.c,v 1.29 2014/02/24 07:23:43 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hppa_machdep.c,v 1.30 2019/11/23 19:40:35 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -292,20 +292,14 @@ hppa_ras(struct lwp *l)
  * or after the current trap/syscall if in system mode.
  */
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
-	bool immed = (flags & RESCHED_IMMED) != 0;
-
-	if (ci->ci_want_resched && !immed)
-		return;
-	ci->ci_want_resched = 1;
-	setsoftast(ci->ci_data.cpu_onproc);
 
+	if ((flags & RESCHED_REMOTE) != 0) {
 #ifdef MULTIPROCESSOR
-	if (ci->ci_curlwp != ci->ci_data.cpu_idlelwp) {
-		if (immed && ci != curcpu()) {
-			/* XXX send IPI */
-		}
-	}
+		/* XXX send IPI */
 #endif
+	} else {
+		setsoftast(l);
+	}
 }

Index: src/sys/arch/ia64/include/cpu.h
diff -u src/sys/arch/ia64/include/cpu.h:1.17 src/sys/arch/ia64/include/cpu.h:1.18
--- src/sys/arch/ia64/include/cpu.h:1.17	Thu Jan 10 17:05:56 2019
+++ src/sys/arch/ia64/include/cpu.h	Sat Nov 23 19:40:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.17 2019/01/10 17:05:56 scole Exp $	*/
+/*	$NetBSD: cpu.h,v 1.18 2019/11/23 19:40:35 ad Exp $	*/
 
 /*-
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -136,7 +136,7 @@ extern struct cpu_info *cpu_info_list;
 
 #define aston(l) ((l)->l_md.md_astpending = 1)
 
-#define	need_resched(ci)            /*XXX: FIXME */
+#define	need_resched(ci,l,f)            /*XXX: FIXME */
 
 struct clockframe {
 	struct trapframe cf_tf;
@@ -165,7 +165,7 @@ struct clockframe {
 #define	cpu_signotify(l)	aston(l)
 
 // void cpu_need_resched(struct cpu_info *ci, int flags)
-#define cpu_need_resched(ci, f) do {	\
+#define cpu_need_resched(ci, l, f) do {	\
 	__USE(ci);			\
 	__USE(f);			\
 } while(/*CONSTCOND*/0)

Index: src/sys/arch/luna68k/include/cpu.h
diff -u src/sys/arch/luna68k/include/cpu.h:1.36 src/sys/arch/luna68k/include/cpu.h:1.37
--- src/sys/arch/luna68k/include/cpu.h:1.36	Mon Feb 18 01:12:23 2019
+++ src/sys/arch/luna68k/include/cpu.h	Sat Nov 23 19:40:35 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.36 2019/02/18 01:12:23 thorpej Exp $ */
+/* $NetBSD: cpu.h,v 1.37 2019/11/23 19:40:35 ad Exp $ */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -80,9 +80,8 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/mac68k/include/cpu.h
diff -u src/sys/arch/mac68k/include/cpu.h:1.101 src/sys/arch/mac68k/include/cpu.h:1.102
--- src/sys/arch/mac68k/include/cpu.h:1.101	Mon Feb 18 01:12:23 2019
+++ src/sys/arch/mac68k/include/cpu.h	Sat Nov 23 19:40:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.101 2019/02/18 01:12:23 thorpej Exp $	*/
+/*	$NetBSD: cpu.h,v 1.102 2019/11/23 19:40:35 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -99,9 +99,8 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/mips/mips/cpu_subr.c
diff -u src/sys/arch/mips/mips/cpu_subr.c:1.35 src/sys/arch/mips/mips/cpu_subr.c:1.36
--- src/sys/arch/mips/mips/cpu_subr.c:1.35	Thu Nov 21 19:57:23 2019
+++ src/sys/arch/mips/mips/cpu_subr.c	Sat Nov 23 19:40:35 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: cpu_subr.c,v 1.35 2019/11/21 19:57:23 ad Exp $	*/
+/*	$NetBSD: cpu_subr.c,v 1.36 2019/11/23 19:40:35 ad Exp $	*/
 
 /*-
- * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.35 2019/11/21 19:57:23 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.36 2019/11/23 19:40:35 ad Exp $");
 
 #include "opt_cputype.h"
 #include "opt_ddb.h"
@@ -481,62 +481,27 @@ cpu_setmcontext(struct lwp *l, const mco
 }
 
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
-	struct lwp * const l = ci->ci_data.cpu_onproc;
-#ifdef MULTIPROCESSOR
-	struct cpu_info * const cur_ci = curcpu();
-#endif
-
 	KASSERT(kpreempt_disabled());
 
-	ci->ci_want_resched |= flags;
-
-	if (__predict_false((l->l_pflag & LP_INTR) != 0)) {
-		/*
-		 * No point doing anything, it will switch soon.
-		 * Also here to prevent an assertion failure in
-		 * kpreempt() due to preemption being set on a
-		 * soft interrupt LWP.
-		 */
-		return;
-	}
-
-	if (__predict_false(l == ci->ci_data.cpu_idlelwp)) {
-#ifdef MULTIPROCESSOR
-		/*
-		 * If the other CPU is idling, it must be waiting for an
-		 * interrupt.  So give it one.
-		 */
-		if (__predict_false(ci != cur_ci))
-			cpu_send_ipi(ci, IPI_NOP);
-#endif
-		return;
-	}
-
-#ifdef MULTIPROCESSOR
-	atomic_or_uint(&ci->ci_want_resched, flags);
-#else
-	ci->ci_want_resched |= flags;
-#endif
-
-	if (flags & RESCHED_KPREEMPT) {
+	if ((flags & RESCHED_KPREEMPT) != 0) {
 #ifdef __HAVE_PREEMPTION
-		atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE);
-		if (ci == cur_ci) {
-			softint_trigger(SOFTINT_KPREEMPT);
-		} else {
+		if ((flags & RESCHED_REMOTE) != 0) {
 			cpu_send_ipi(ci, IPI_KPREEMPT);
+		} else {
+			softint_trigger(SOFTINT_KPREEMPT);
 		}
 #endif
 		return;
 	}
-	l->l_md.md_astpending = 1;		/* force call to ast() */
+	if ((flags & RESSCHED_REMOTE) != 0) {
 #ifdef MULTIPROCESSOR
-	if (ci != cur_ci && (flags & RESCHED_IMMED)) {
 		cpu_send_ipi(ci, IPI_AST);
-	}
 #endif
+	} else {
+		l->l_md.md_astpending = 1;		/* force call to ast() */
+	}
 }
 
 uint32_t
@@ -552,9 +517,14 @@ cpu_signotify(struct lwp *l)
 #ifdef __HAVE_FAST_SOFTINTS
 	KASSERT(lwp_locked(l, NULL));
 #endif
-	KASSERT(l->l_stat == LSONPROC || l->l_stat == LSRUN || l->l_stat == LSSTOP);
 
-	l->l_md.md_astpending = 1; 		/* force call to ast() */
+	if (l->l_cpu != curcpu()) {
+#ifdef MULTIPROCESSOR
+		cpu_send_ipi(l->l_cpu, IPI_AST);
+#endif
+	} else {
+		l->l_md.md_astpending = 1; 	/* force call to ast() */
+	}
 }
 
 void

Index: src/sys/arch/mips/mips/ipifuncs.c
diff -u src/sys/arch/mips/mips/ipifuncs.c:1.11 src/sys/arch/mips/mips/ipifuncs.c:1.12
--- src/sys/arch/mips/mips/ipifuncs.c:1.11	Fri Jun 26 22:29:38 2015
+++ src/sys/arch/mips/mips/ipifuncs.c	Sat Nov 23 19:40:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipifuncs.c,v 1.11 2015/06/26 22:29:38 matt Exp $	*/
+/*	$NetBSD: ipifuncs.c,v 1.12 2019/11/23 19:40:35 ad Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.11 2015/06/26 22:29:38 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.12 2019/11/23 19:40:35 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -74,6 +74,12 @@ ipi_nop(struct cpu_info *ci)
 }
 
 static void
+ipi_ast(struct cpu_info *ci)
+{
+	ci->ci_data.cpu_onproc->l_md.md_astpending = 1;
+}
+
+static void
 ipi_shootdown(struct cpu_info *ci)
 {
 	pmap_tlb_shootdown_process();
@@ -120,7 +126,7 @@ ipi_process(struct cpu_info *ci, uint64_
 	}
 	if (ipi_mask & __BIT(IPI_AST)) {
 		ci->ci_evcnt_per_ipi[IPI_AST].ev_count++;
-		ipi_nop(ci);
+		ipi_ast(ci);
 	}
 	if (ipi_mask & __BIT(IPI_SHOOTDOWN)) {
 		ci->ci_evcnt_per_ipi[IPI_SHOOTDOWN].ev_count++;

Index: src/sys/arch/mvme68k/include/cpu.h
diff -u src/sys/arch/mvme68k/include/cpu.h:1.50 src/sys/arch/mvme68k/include/cpu.h:1.51
--- src/sys/arch/mvme68k/include/cpu.h:1.50	Wed Aug 22 01:05:22 2018
+++ src/sys/arch/mvme68k/include/cpu.h	Sat Nov 23 19:40:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.50 2018/08/22 01:05:22 msaitoh Exp $	*/
+/*	$NetBSD: cpu.h,v 1.51 2019/11/23 19:40:35 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -86,9 +86,8 @@ extern volatile unsigned int interrupt_d
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/news68k/include/cpu.h
diff -u src/sys/arch/news68k/include/cpu.h:1.45 src/sys/arch/news68k/include/cpu.h:1.46
--- src/sys/arch/news68k/include/cpu.h:1.45	Mon Feb 18 01:12:24 2019
+++ src/sys/arch/news68k/include/cpu.h	Sat Nov 23 19:40:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.45 2019/02/18 01:12:24 thorpej Exp $	*/
+/*	$NetBSD: cpu.h,v 1.46 2019/11/23 19:40:35 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -104,9 +104,8 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/next68k/include/cpu.h
diff -u src/sys/arch/next68k/include/cpu.h:1.49 src/sys/arch/next68k/include/cpu.h:1.50
--- src/sys/arch/next68k/include/cpu.h:1.49	Mon Feb 18 01:12:24 2019
+++ src/sys/arch/next68k/include/cpu.h	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.49 2019/02/18 01:12:24 thorpej Exp $	*/
+/*	$NetBSD: cpu.h,v 1.50 2019/11/23 19:40:36 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -90,9 +90,8 @@ extern volatile unsigned int interrupt_d
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/powerpc/booke/e500_intr.c
diff -u src/sys/arch/powerpc/booke/e500_intr.c:1.38 src/sys/arch/powerpc/booke/e500_intr.c:1.39
--- src/sys/arch/powerpc/booke/e500_intr.c:1.38	Sun Sep 16 09:25:47 2018
+++ src/sys/arch/powerpc/booke/e500_intr.c	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: e500_intr.c,v 1.38 2018/09/16 09:25:47 skrll Exp $	*/
+/*	$NetBSD: e500_intr.c,v 1.39 2019/11/23 19:40:36 ad Exp $	*/
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -41,7 +41,7 @@
 #define __INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.38 2018/09/16 09:25:47 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.39 2019/11/23 19:40:36 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -1335,6 +1335,12 @@ e500_ipi_suspend(void)
 #endif	/* MULTIPROCESSOR */
 }
 
+static void
+e500_ipi_ast(void)
+{
+	curcpu()->ci_data.cpu_onproc->l_md.md_astpending = 1;
+}
+
 static const ipifunc_t e500_ipifuncs[] = {
 	[ilog2(IPI_XCALL)] =	xc_ipi_handler,
 	[ilog2(IPI_GENERIC)] =	ipi_cpu_handler,
@@ -1344,6 +1350,7 @@ static const ipifunc_t e500_ipifuncs[] =
 #endif
 	[ilog2(IPI_TLB1SYNC)] =	e500_tlb1_sync,
 	[ilog2(IPI_SUSPEND)] =	e500_ipi_suspend,
+	[ilog2(IPI_AST)] =	e500_ipi_ast,
 };
 
 static int

Index: src/sys/arch/powerpc/include/cpu.h
diff -u src/sys/arch/powerpc/include/cpu.h:1.108 src/sys/arch/powerpc/include/cpu.h:1.109
--- src/sys/arch/powerpc/include/cpu.h:1.108	Wed Aug 22 01:05:23 2018
+++ src/sys/arch/powerpc/include/cpu.h	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.108 2018/08/22 01:05:23 msaitoh Exp $	*/
+/*	$NetBSD: cpu.h,v 1.109 2019/11/23 19:40:36 ad Exp $	*/
 
 /*
  * Copyright (C) 1999 Wolfgang Solfrank.
@@ -434,10 +434,8 @@ vaddr_t	cpu_lwp_pc(struct lwp *);
 void	cpu_ast(struct lwp *, struct cpu_info *);
 void *	cpu_uarea_alloc(bool);
 bool	cpu_uarea_free(void *);
-void	cpu_need_resched(struct cpu_info *, int);
 void	cpu_signotify(struct lwp *);
 void	cpu_need_proftick(struct lwp *);
-#define	cpu_did_resched(l)			((l)->l_md.md_astpending = 0)
 
 void	cpu_fixup_stubs(void);
 

Index: src/sys/arch/powerpc/include/booke/intr.h
diff -u src/sys/arch/powerpc/include/booke/intr.h:1.11 src/sys/arch/powerpc/include/booke/intr.h:1.12
--- src/sys/arch/powerpc/include/booke/intr.h:1.11	Thu Apr 19 21:50:07 2018
+++ src/sys/arch/powerpc/include/booke/intr.h	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.h,v 1.11 2018/04/19 21:50:07 christos Exp $	*/
+/*	$NetBSD: intr.h,v 1.12 2019/11/23 19:40:36 ad Exp $	*/
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -75,6 +75,7 @@
 #define IPI_TLB1SYNC	0x0008
 #define IPI_GENERIC	0x0010
 #define IPI_SUSPEND	0x0020
+#define IPI_AST		0x0040
 
 #define	__HAVE_FAST_SOFTINTS	1
 #define	SOFTINT_KPREEMPT	SOFTINT_COUNT

Index: src/sys/arch/powerpc/powerpc/genassym.cf
diff -u src/sys/arch/powerpc/powerpc/genassym.cf:1.10 src/sys/arch/powerpc/powerpc/genassym.cf:1.11
--- src/sys/arch/powerpc/powerpc/genassym.cf:1.10	Fri Aug 30 21:29:29 2013
+++ src/sys/arch/powerpc/powerpc/genassym.cf	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.10 2013/08/30 21:29:29 matt Exp $
+#	$NetBSD: genassym.cf,v 1.11 2019/11/23 19:40:36 ad Exp $
 
 #-
 # Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
@@ -163,7 +163,6 @@ define	CI_SIZE		sizeof(struct cpu_info)
 define	CI_CURLWP	offsetof(struct cpu_info, ci_curlwp)
 define	CI_CURPCB	offsetof(struct cpu_info, ci_curpcb)
 define	CI_CURPM	offsetof(struct cpu_info, ci_curpm)
-define	CI_WANT_RESCHED	offsetof(struct cpu_info, ci_want_resched)
 define	CI_CPL		offsetof(struct cpu_info, ci_cpl)
 define	CI_IDEPTH	offsetof(struct cpu_info, ci_idepth)
 define	CI_IDLESPIN	offsetof(struct cpu_info, ci_idlespin)

Index: src/sys/arch/powerpc/powerpc/powerpc_machdep.c
diff -u src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.73 src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.74
--- src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.73	Thu Nov 21 19:57:24 2019
+++ src/sys/arch/powerpc/powerpc/powerpc_machdep.c	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: powerpc_machdep.c,v 1.73 2019/11/21 19:57:24 ad Exp $	*/
+/*	$NetBSD: powerpc_machdep.c,v 1.74 2019/11/23 19:40:36 ad Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.73 2019/11/21 19:57:24 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.74 2019/11/23 19:40:36 ad Exp $");
 
 #include "opt_altivec.h"
 #include "opt_ddb.h"
@@ -381,60 +381,27 @@ cpu_ast(struct lwp *l, struct cpu_info *
 }
 
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
-	struct lwp * const l = ci->ci_data.cpu_onproc;
-#if defined(MULTIPROCESSOR)
-	struct cpu_info * const cur_ci = curcpu();
-#endif
-
 	KASSERT(kpreempt_disabled());
 
-#ifdef MULTIPROCESSOR
-	atomic_or_uint(&ci->ci_want_resched, flags);
-#else
-	ci->ci_want_resched |= flags;
-#endif
-
-	if (__predict_false((l->l_pflag & LP_INTR) != 0)) {
-		/*
-		 * No point doing anything, it will switch soon.
-		 * Also here to prevent an assertion failure in
-		 * kpreempt() due to preemption being set on a
-		 * soft interrupt LWP.
-		 */
-		return;
-	}
-
-	if (__predict_false(l == ci->ci_data.cpu_idlelwp)) {
-#if defined(MULTIPROCESSOR)
-		/*
-		 * If the other CPU is idling, it must be waiting for an
-		 * interrupt.  So give it one.
-		 */
-		if (__predict_false(ci != cur_ci))
-			cpu_send_ipi(cpu_index(ci), IPI_NOMESG);
-#endif
-		return;
-	}
-
 #ifdef __HAVE_PREEMPTION
-	if (flags & RESCHED_KPREEMPT) {
-		atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE);
-		if (ci == cur_ci) {
-			softint_trigger(SOFTINT_KPREEMPT);
-		} else {
+	if ((flags & RESCHED_KPREEMPT) != 0) {
+		if ((flags & RESCHED_REMOTE) != 0) {
 			cpu_send_ipi(cpu_index(ci), IPI_KPREEMPT);
+		} else {
+			softint_trigger(SOFTINT_KPREEMPT);
 		}
 		return;
 	}
 #endif
-	l->l_md.md_astpending = 1;		/* force call to ast() */
+	if ((flags & RESCHED_REMOTE) != 0) {
 #if defined(MULTIPROCESSOR)
-	if (ci != cur_ci && (flags & RESCHED_IMMED)) {
-		cpu_send_ipi(cpu_index(ci), IPI_NOMESG);
-	} 
+		cpu_send_ipi(cpu_index(ci), IPI_AST);
 #endif
+	} else {
+		l->l_md.md_astpending = 1;		/* force call to ast() */
+	}
 }
 
 void
@@ -447,7 +414,13 @@ cpu_need_proftick(lwp_t *l)
 void
 cpu_signotify(lwp_t *l)
 {
-	l->l_md.md_astpending = 1;
+	if (l->l_cpu != curcpu()) {
+#if defined(MULTIPROCESSOR)
+		cpu_send_ipi(cpu_index(l->l_cpu), IPI_AST);
+#endif
+	} else {
+		l->l_md.md_astpending = 1;
+	}
 }
 
 vaddr_t

Index: src/sys/arch/riscv/riscv/genassym.cf
diff -u src/sys/arch/riscv/riscv/genassym.cf:1.5 src/sys/arch/riscv/riscv/genassym.cf:1.6
--- src/sys/arch/riscv/riscv/genassym.cf:1.5	Sun Jun 16 07:42:52 2019
+++ src/sys/arch/riscv/riscv/genassym.cf	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.5 2019/06/16 07:42:52 maxv Exp $
+#	$NetBSD: genassym.cf,v 1.6 2019/11/23 19:40:36 ad Exp $
 #-
 # Copyright (c) 2014 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -130,7 +130,6 @@ define	CI_IDLELWP	offsetof(struct cpu_in
 define	CI_MTX_COUNT	offsetof(struct cpu_info, ci_mtx_count)
 define	CI_MTX_OLDSPL	offsetof(struct cpu_info, ci_mtx_oldspl)
 define	CI_SOFTINTS	offsetof(struct cpu_info, ci_softints)
-define	CI_WANT_RESCHED	offsetof(struct cpu_info, ci_want_resched)
 
 define	FB_A0		offsetof(struct faultbuf, fb_reg[FB_A0])
 define	FB_RA		offsetof(struct faultbuf, fb_reg[FB_RA])
Index: src/sys/arch/riscv/riscv/riscv_machdep.c
diff -u src/sys/arch/riscv/riscv/riscv_machdep.c:1.5 src/sys/arch/riscv/riscv/riscv_machdep.c:1.6
--- src/sys/arch/riscv/riscv/riscv_machdep.c:1.5	Thu Nov 21 19:57:24 2019
+++ src/sys/arch/riscv/riscv/riscv_machdep.c	Sat Nov 23 19:40:36 2019
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2014, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -31,7 +31,7 @@
 
 #include "opt_modular.h"
 
-__RCSID("$NetBSD: riscv_machdep.c,v 1.5 2019/11/21 19:57:24 ad Exp $");
+__RCSID("$NetBSD: riscv_machdep.c,v 1.6 2019/11/23 19:40:36 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -243,62 +243,27 @@ cpu_setmcontext(struct lwp *l, const mco
 }
 
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
-	struct lwp * const l = ci->ci_data.cpu_onproc;
-#ifdef MULTIPROCESSOR
-	struct cpu_info * const cur_ci = curcpu();
-#endif
-
 	KASSERT(kpreempt_disabled());
 
-	ci->ci_want_resched |= flags;
-
-	if (__predict_false((l->l_pflag & LP_INTR) != 0)) {
-		/*
-		 * No point doing anything, it will switch soon.
-		 * Also here to prevent an assertion failure in
-		 * kpreempt() due to preemption being set on a
-		 * soft interrupt LWP.
-		 */
-		return;
-	}
-
-	if (__predict_false(l == ci->ci_data.cpu_idlelwp)) {
-#ifdef MULTIPROCESSOR
-		/*
-		 * If the other CPU is idling, it must be waiting for an
-		 * interrupt.  So give it one.
-		 */
-		if (__predict_false(ci != cur_ci))
-			cpu_send_ipi(ci, IPI_NOP);
-#endif
-		return;
-	}
-
-#ifdef MULTIPROCESSOR
-	atomic_or_uint(&ci->ci_want_resched, flags);
-#else
-	ci->ci_want_resched |= flags;
-#endif
-
-	if (flags & RESCHED_KPREEMPT) {
+	if ((flags & RESCHED_KPREEMPT) != 0) {
 #ifdef __HAVE_PREEMPTION
-		atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE);
-		if (ci == cur_ci) {
-			softint_trigger(SOFTINT_KPREEMPT);
-                } else {
+		if ((flags & RESCHED_REMOTE) != 0) {
                         cpu_send_ipi(ci, IPI_KPREEMPT);
+		} else {
+			softint_trigger(SOFTINT_KPREEMPT);
                 }
 #endif
 		return;
 	}
-	l->l_md.md_astpending = 1;		/* force call to ast() */
+	if ((flags & RESCHED_REMOTE) != 0) {
 #ifdef MULTIPROCESSOR
-	if (ci != cur_ci && (flags & RESCHED_IMMED)) {
 		cpu_send_ipi(ci, IPI_AST);
-	} 
 #endif
+	} else {
+		l->l_md.md_astpending = 1;		/* force call to ast() */
+	}
 }
 
 void
@@ -308,9 +273,14 @@ cpu_signotify(struct lwp *l)
 #ifdef __HAVE_FAST_SOFTINTS
 	KASSERT(lwp_locked(l, NULL));
 #endif
-	KASSERT(l->l_stat == LSONPROC || l->l_stat == LSRUN || l->l_stat == LSSTOP);
 
-	l->l_md.md_astpending = 1; 		/* force call to ast() */
+	if (l->l_cpu != curcpu()) {
+#ifdef MULTIPROCESSOR
+		cpu_send_ipi(ci, IPI_AST);
+#endif
+	} else {
+		l->l_md.md_astpending = 1; 	/* force call to ast() */
+	}
 }
 
 void

Index: src/sys/arch/sh3/include/cpu.h
diff -u src/sys/arch/sh3/include/cpu.h:1.57 src/sys/arch/sh3/include/cpu.h:1.58
--- src/sys/arch/sh3/include/cpu.h:1.57	Wed Aug 22 01:05:23 2018
+++ src/sys/arch/sh3/include/cpu.h	Sat Nov 23 19:40:36 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: cpu.h,v 1.57 2018/08/22 01:05:23 msaitoh Exp $	*/
+/*	$NetBSD: cpu.h,v 1.58 2019/11/23 19:40:36 ad Exp $	*/
 
 /*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
+ * Copyright (c) 2002, 2019 The NetBSD Foundation, Inc. All rights reserved.
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
@@ -99,11 +99,9 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci, flags)					\
+#define	cpu_need_resched(ci,l,flags)					\
 do {									\
-	__USE(flags); 							\
-	ci->ci_want_resched = 1;					\
-	if (curlwp != ci->ci_data.cpu_idlelwp)				\
+	if ((flags & RESCHED_IDLE) == 0)				\
 		aston(curlwp);						\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/sparc/include/cpu.h
diff -u src/sys/arch/sparc/include/cpu.h:1.101 src/sys/arch/sparc/include/cpu.h:1.102
--- src/sys/arch/sparc/include/cpu.h:1.101	Wed Aug 22 01:05:23 2018
+++ src/sys/arch/sparc/include/cpu.h	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.101 2018/08/22 01:05:23 msaitoh Exp $ */
+/*	$NetBSD: cpu.h,v 1.102 2019/11/23 19:40:36 ad Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -451,13 +451,12 @@ void	sparc_softintr_init(void);
  * Preempt the current process on the target CPU if in interrupt from
  * user mode, or after the current trap/syscall if in system mode.
  */
-#define cpu_need_resched(ci, flags) do {				\
+#define cpu_need_resched(ci, l, flags) do {				\
 	__USE(flags);							\
-	(ci)->ci_want_resched = 1;					\
 	(ci)->ci_want_ast = 1;						\
 									\
 	/* Just interrupt the target CPU, so it can notice its AST */	\
-	if (((flags) & RESCHED_IMMED) || (ci)->ci_cpuid != cpu_number()) \
+	if ((flags & RESCHED_REMOTE) != 0)				\
 		XCALL0(sparc_noop, 1U << (ci)->ci_cpuid);		\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/sparc64/include/cpu.h
diff -u src/sys/arch/sparc64/include/cpu.h:1.126 src/sys/arch/sparc64/include/cpu.h:1.127
--- src/sys/arch/sparc64/include/cpu.h:1.126	Fri Feb  8 20:14:50 2019
+++ src/sys/arch/sparc64/include/cpu.h	Sat Nov 23 19:40:36 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.126 2019/02/08 20:14:50 palle Exp $ */
+/*	$NetBSD: cpu.h,v 1.127 2019/11/23 19:40:36 ad Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -267,7 +267,6 @@ extern struct pool_cache *fpstate_cache;
 #define curpcb		curcpu()->ci_cpcb
 
 #define want_ast	curcpu()->ci_want_ast
-#define want_resched	curcpu()->ci_want_resched
 
 /*
  * definitions of cpu-dependent requirements

Index: src/sys/arch/sparc64/sparc64/genassym.cf
diff -u src/sys/arch/sparc64/sparc64/genassym.cf:1.81 src/sys/arch/sparc64/sparc64/genassym.cf:1.82
--- src/sys/arch/sparc64/sparc64/genassym.cf:1.81	Fri Feb 10 23:26:23 2017
+++ src/sys/arch/sparc64/sparc64/genassym.cf	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.81 2017/02/10 23:26:23 palle Exp $
+#	$NetBSD: genassym.cf,v 1.82 2019/11/23 19:40:37 ad Exp $
 
 #
 # Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -169,7 +169,6 @@ define	CI_SPINUP	offsetof(struct cpu_inf
 define	CI_PADDR	offsetof(struct cpu_info, ci_paddr)
 define	CI_CPUID	offsetof(struct cpu_info, ci_cpuid)
 define	CI_WANT_AST	offsetof(struct cpu_info, ci_want_ast)
-define	CI_WANT_RESCHED	offsetof(struct cpu_info, ci_want_resched)
 define	CI_EINTSTACK	offsetof(struct cpu_info, ci_eintstack)
 define	CI_IDLELWP	offsetof(struct cpu_info, ci_data.cpu_idlelwp)
 define	CI_NFAULT	offsetof(struct cpu_info, ci_data.cpu_nfault)

Index: src/sys/arch/sparc64/sparc64/machdep.c
diff -u src/sys/arch/sparc64/sparc64/machdep.c:1.292 src/sys/arch/sparc64/sparc64/machdep.c:1.293
--- src/sys/arch/sparc64/sparc64/machdep.c:1.292	Sun Nov 10 21:16:33 2019
+++ src/sys/arch/sparc64/sparc64/machdep.c	Sat Nov 23 19:40:37 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: machdep.c,v 1.292 2019/11/10 21:16:33 chs Exp $ */
+/*	$NetBSD: machdep.c,v 1.293 2019/11/23 19:40:37 ad Exp $ */
 
 /*-
- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996, 1997, 1998, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.292 2019/11/10 21:16:33 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.293 2019/11/23 19:40:37 ad Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -2622,19 +2622,16 @@ cpu_setmcontext(struct lwp *l, const mco
  * or after the current trap/syscall if in system mode.
  */
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
 
-	ci->ci_want_resched = 1;
 	ci->ci_want_ast = 1;
 
 #ifdef MULTIPROCESSOR
-	if (ci == curcpu())
-		return;
-	/* Just interrupt the target CPU, so it can notice its AST */
-	if ((flags & RESCHED_IMMED) != 0 &&
-	    ci->ci_data.cpu_onproc != ci->ci_data.cpu_idlelwp)
+	if ((flags & RESCHED_REMOTE) != 0) {
+		/* Just interrupt the target CPU, so it can notice its AST */
 		sparc64_send_ipi(ci->ci_cpuid, sparc64_ipi_nop, 0, 0);
+	}
 #endif
 }
 
@@ -2648,8 +2645,9 @@ cpu_signotify(struct lwp *l)
 
 	ci->ci_want_ast = 1;
 #ifdef MULTIPROCESSOR
-	if (ci != curcpu())
+	if (ci != curcpu()) {
 		sparc64_send_ipi(ci->ci_cpuid, sparc64_ipi_nop, 0, 0);
+	}
 #endif
 }
 

Index: src/sys/arch/sun68k/include/cpu.h
diff -u src/sys/arch/sun68k/include/cpu.h:1.24 src/sys/arch/sun68k/include/cpu.h:1.25
--- src/sys/arch/sun68k/include/cpu.h:1.24	Thu Aug 23 04:04:34 2018
+++ src/sys/arch/sun68k/include/cpu.h	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.24 2018/08/23 04:04:34 msaitoh Exp $	*/
+/*	$NetBSD: cpu.h,v 1.25 2019/11/23 19:40:37 ad Exp $	*/
 
 /*
  * Copyright (c) 1982, 1990 The Regents of the University of California.
@@ -134,7 +134,6 @@ extern int astpending;	 /* need to trap 
  */
 #define	cpu_need_resched(ci,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/usermode/dev/cpu.c
diff -u src/sys/arch/usermode/dev/cpu.c:1.80 src/sys/arch/usermode/dev/cpu.c:1.81
--- src/sys/arch/usermode/dev/cpu.c:1.80	Fri Jun  1 07:26:15 2018
+++ src/sys/arch/usermode/dev/cpu.c	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.80 2018/06/01 07:26:15 reinoud Exp $ */
+/* $NetBSD: cpu.c,v 1.81 2019/11/23 19:40:37 ad Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca>
@@ -30,7 +30,7 @@
 #include "opt_hz.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.80 2018/06/01 07:26:15 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.81 2019/11/23 19:40:37 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -182,9 +182,8 @@ cpu_reboot(int howto, char *bootstr)
 }
 
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
-	ci->ci_want_resched |= flags;
 	aston(ci);
 }
 

Index: src/sys/arch/usermode/include/cpu.h
diff -u src/sys/arch/usermode/include/cpu.h:1.11 src/sys/arch/usermode/include/cpu.h:1.12
--- src/sys/arch/usermode/include/cpu.h:1.11	Wed Aug  1 09:50:57 2018
+++ src/sys/arch/usermode/include/cpu.h	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.11 2018/08/01 09:50:57 reinoud Exp $ */
+/* $NetBSD: cpu.h,v 1.12 2019/11/23 19:40:37 ad Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca>
@@ -46,7 +46,6 @@ extern void	userret(struct lwp *);
 struct cpu_info;
 extern int	astpending;
 #define aston(ci) (astpending++)
-extern void cpu_need_resched(struct cpu_info *ci, int flags);
 extern void kgdb_port_init(void);
 
 struct cpu_info {

Index: src/sys/arch/vax/include/cpu.h
diff -u src/sys/arch/vax/include/cpu.h:1.102 src/sys/arch/vax/include/cpu.h:1.103
--- src/sys/arch/vax/include/cpu.h:1.102	Wed Aug 22 01:05:23 2018
+++ src/sys/arch/vax/include/cpu.h	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-/*      $NetBSD: cpu.h,v 1.102 2018/08/22 01:05:23 msaitoh Exp $      */
+/*      $NetBSD: cpu.h,v 1.103 2019/11/23 19:40:37 ad Exp $      */
 
 /*
  * Copyright (c) 1994 Ludd, University of Lule}, Sweden
@@ -151,10 +151,9 @@ extern int cpu_printfataltraps;
 #define	curcpu()		(curlwp->l_cpu + 0)
 #define	curlwp			((struct lwp *)mfpr(PR_SSP))
 #define	cpu_number()		(curcpu()->ci_cpuid)
-#define	cpu_need_resched(ci, flags)		\
+#define	cpu_need_resched(ci, l, flags)		\
 	do {					\
 		__USE(flags);			\
-		(ci)->ci_want_resched = 1;	\
 		mtpr(AST_OK,PR_ASTLVL);		\
 	} while (/*CONSTCOND*/ 0)
 #define	cpu_proc_fork(x, y)	do { } while (/*CONSCOND*/0)

Index: src/sys/arch/x68k/include/cpu.h
diff -u src/sys/arch/x68k/include/cpu.h:1.61 src/sys/arch/x68k/include/cpu.h:1.62
--- src/sys/arch/x68k/include/cpu.h:1.61	Mon Feb 18 01:12:24 2019
+++ src/sys/arch/x68k/include/cpu.h	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.61 2019/02/18 01:12:24 thorpej Exp $	*/
+/*	$NetBSD: cpu.h,v 1.62 2019/11/23 19:40:37 ad Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -88,9 +88,8 @@ struct clockframe {
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
  */
-#define	cpu_need_resched(ci,flags)	do {	\
+#define	cpu_need_resched(ci,l,flags)	do {	\
 	__USE(flags); 				\
-	ci->ci_want_resched = 1;		\
 	aston();				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.112 src/sys/arch/x86/include/cpu.h:1.113
--- src/sys/arch/x86/include/cpu.h:1.112	Thu Nov 21 21:48:33 2019
+++ src/sys/arch/x86/include/cpu.h	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.112 2019/11/21 21:48:33 ad Exp $	*/
+/*	$NetBSD: cpu.h,v 1.113 2019/11/23 19:40:37 ad Exp $	*/
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -384,11 +384,7 @@ lwp_t   *x86_curlwp(void);
 
 #define CPU_IS_PRIMARY(ci)	((ci)->ci_flags & CPUF_PRIMARY)
 
-#define	X86_AST_GENERIC		0x01
-#define	X86_AST_PREEMPT		0x02
-
-#define aston(l, why)		((l)->l_md.md_astpending |= (why))
-#define	cpu_did_resched(l)	((l)->l_md.md_astpending &= ~X86_AST_PREEMPT)
+#define aston(l)		((l)->l_md.md_astpending = 1)
 
 void cpu_boot_secondary_processors(void);
 void cpu_init_idle_lwps(void);

Index: src/sys/arch/x86/include/intrdefs.h
diff -u src/sys/arch/x86/include/intrdefs.h:1.22 src/sys/arch/x86/include/intrdefs.h:1.23
--- src/sys/arch/x86/include/intrdefs.h:1.22	Fri Feb 15 08:54:01 2019
+++ src/sys/arch/x86/include/intrdefs.h	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: intrdefs.h,v 1.22 2019/02/15 08:54:01 nonaka Exp $	*/
+/*	$NetBSD: intrdefs.h,v 1.23 2019/11/23 19:40:37 ad Exp $	*/
 
 #ifndef _X86_INTRDEFS_H_
 #define _X86_INTRDEFS_H_
@@ -60,7 +60,7 @@
 #ifndef XENPV
 
 #define X86_IPI_HALT			0x00000001
-#define X86_IPI_MICROSET		0x00000002
+#define X86_IPI_AST			0x00000002
 #define X86_IPI_GENERIC			0x00000004
 #define X86_IPI_SYNCH_FPU		0x00000008
 #define X86_IPI_MTRR			0x00000010
@@ -71,7 +71,7 @@
 
 #define X86_NIPI		9
 
-#define X86_IPI_NAMES { "halt IPI", "timeset IPI", "generic IPI", \
+#define X86_IPI_NAMES { "halt IPI", "AST IPI", "generic IPI", \
 			 "FPU synch IPI", "MTRR update IPI", \
 			 "GDT update IPI", "xcall IPI", \
 			 "ACPI CPU sleep IPI", "kpreempt IPI" }

Index: src/sys/arch/x86/x86/cpu.c
diff -u src/sys/arch/x86/x86/cpu.c:1.175 src/sys/arch/x86/x86/cpu.c:1.176
--- src/sys/arch/x86/x86/cpu.c:1.175	Fri Nov 22 23:36:25 2019
+++ src/sys/arch/x86/x86/cpu.c	Sat Nov 23 19:40:37 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.175 2019/11/22 23:36:25 ad Exp $	*/
+/*	$NetBSD: cpu.c,v 1.176 2019/11/23 19:40:37 ad Exp $	*/
 
 /*
  * Copyright (c) 2000-2012 NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.175 2019/11/22 23:36:25 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.176 2019/11/23 19:40:37 ad Exp $");
 
 #include "opt_ddb.h"
 #include "opt_mpbios.h"		/* for MPDEBUG */
@@ -1348,11 +1348,12 @@ cpu_broadcast_halt(void)
 }
 
 /*
- * Send a dummy ipi to a cpu to force it to run splraise()/spllower()
+ * Send a dummy ipi to a cpu to force it to run splraise()/spllower(),
+ * and trigger an AST on the running LWP.
  */
 
 void
 cpu_kick(struct cpu_info *ci)
 {
-	x86_send_ipi(ci, 0);
+	x86_send_ipi(ci, X86_IPI_AST);
 }

Index: src/sys/arch/x86/x86/ipi.c
diff -u src/sys/arch/x86/x86/ipi.c:1.28 src/sys/arch/x86/x86/ipi.c:1.29
--- src/sys/arch/x86/x86/ipi.c:1.28	Sat Oct 12 06:31:04 2019
+++ src/sys/arch/x86/x86/ipi.c	Sat Nov 23 19:40:37 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: ipi.c,v 1.28 2019/10/12 06:31:04 maxv Exp $	*/
+/*	$NetBSD: ipi.c,v 1.29 2019/11/23 19:40:37 ad Exp $	*/
 
 /*-
- * Copyright (c) 2000, 2008, 2009 The NetBSD Foundation, Inc.
+ * Copyright (c) 2000, 2008, 2009, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.28 2019/10/12 06:31:04 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.29 2019/11/23 19:40:37 ad Exp $");
 
 #include "opt_mtrr.h"
 
@@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.28
 
 #include <x86/fpu.h>
 
+static void	x86_ipi_ast(struct cpu_info *);
 static void	x86_ipi_halt(struct cpu_info *);
 static void	x86_ipi_kpreempt(struct cpu_info *);
 static void	x86_ipi_xcall(struct cpu_info *);
@@ -81,7 +82,7 @@ static void	x86_ipi_synch_fpu(struct cpu
 void (* const ipifunc[X86_NIPI])(struct cpu_info *) =
 {
 	x86_ipi_halt,		/* X86_IPI_HALT */
-	NULL,			/* X86_IPI_MICROSET */
+	x86_ipi_ast,		/* X86_IPI_AST */
 	x86_ipi_generic,	/* X86_IPI_GENERIC */
 	x86_ipi_synch_fpu,	/* X86_IPI_SYNCH_FPU */
 	x86_ipi_reload_mtrr,	/* X86_IPI_MTRR */
@@ -98,20 +99,30 @@ void (* const ipifunc[X86_NIPI])(struct 
 int
 x86_send_ipi(struct cpu_info *ci, int ipimask)
 {
-	int ret;
-
-	atomic_or_32(&ci->ci_ipis, ipimask);
+	uint32_t o, n;
+	int ret = 0;
 
 	/* Don't send IPI to CPU which isn't (yet) running. */
-	if (!(ci->ci_flags & CPUF_RUNNING))
+	if (__predict_false((ci->ci_flags & CPUF_RUNNING) == 0))
 		return ENOENT;
 
-	ret = x86_ipi(LAPIC_IPI_VECTOR, ci->ci_cpuid, LAPIC_DLMODE_FIXED);
-	if (ret != 0) {
-		printf("ipi of %x from %s to %s failed\n",
-		    ipimask,
-		    device_xname(curcpu()->ci_dev),
-		    device_xname(ci->ci_dev));
+	/* Set in new IPI bit, and capture previous state. */
+	for (o = 0;; o = n) {
+		n = atomic_cas_32(&ci->ci_ipis, o, o | ipimask);
+		if (__predict_true(o == n)) {
+			break;
+		}
+	}
+
+	/* If no IPI already pending, send one. */
+	if (o == 0) {
+		ret = x86_ipi(LAPIC_IPI_VECTOR, ci->ci_cpuid, LAPIC_DLMODE_FIXED);
+		if (ret != 0) {
+			printf("ipi of %x from %s to %s failed\n",
+			    ipimask,
+			    device_xname(curcpu()->ci_dev),
+			    device_xname(ci->ci_dev));
+		}
 	}
 
 	return ret;
@@ -201,6 +212,13 @@ x86_ipi_kpreempt(struct cpu_info *ci)
 	softint_trigger(1 << SIR_PREEMPT);
 }
 
+static void
+x86_ipi_ast(struct cpu_info *ci)
+{
+
+	aston(ci->ci_data.cpu_onproc);
+}
+
 /*
  * MD support for xcall(9) interface.
  */

Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.128 src/sys/arch/x86/x86/x86_machdep.c:1.129
--- src/sys/arch/x86/x86/x86_machdep.c:1.128	Thu Oct  3 05:06:29 2019
+++ src/sys/arch/x86/x86/x86_machdep.c	Sat Nov 23 19:40:37 2019
@@ -1,12 +1,12 @@
-/*	$NetBSD: x86_machdep.c,v 1.128 2019/10/03 05:06:29 maxv Exp $	*/
+/*	$NetBSD: x86_machdep.c,v 1.129 2019/11/23 19:40:37 ad Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
- * Copyright (c) 2005, 2008, 2009 The NetBSD Foundation, Inc.
+ * Copyright (c) 2005, 2008, 2009, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Julio M. Merino Vidal.
+ * by Julio M. Merino Vidal, and Andrew Doran.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.128 2019/10/03 05:06:29 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.129 2019/11/23 19:40:37 ad Exp $");
 
 #include "opt_modular.h"
 #include "opt_physmem.h"
@@ -290,53 +290,35 @@ module_init_md(void)
 #endif	/* MODULAR */
 
 void
-cpu_need_resched(struct cpu_info *ci, int flags)
+cpu_need_resched(struct cpu_info *ci, struct lwp *l, int flags)
 {
-	struct cpu_info *cur;
-	lwp_t *l;
 
 	KASSERT(kpreempt_disabled());
-	cur = curcpu();
-	l = ci->ci_data.cpu_onproc;
-	ci->ci_want_resched |= flags;
-
-	if (__predict_false((l->l_pflag & LP_INTR) != 0)) {
-		/*
-		 * No point doing anything, it will switch soon.
-		 * Also here to prevent an assertion failure in
-		 * kpreempt() due to preemption being set on a
-		 * soft interrupt LWP.
-		 */
-		return;
-	}
 
-	if (l == ci->ci_data.cpu_idlelwp) {
-		if (ci == cur)
-			return;
-		if (x86_cpu_idle_ipi != false) {
+	if ((flags & RESCHED_IDLE) != 0) {
+		if ((flags & RESCHED_REMOTE) != 0 &&
+		    x86_cpu_idle_ipi != false) {
 			cpu_kick(ci);
 		}
 		return;
 	}
 
-	if ((flags & RESCHED_KPREEMPT) != 0) {
 #ifdef __HAVE_PREEMPTION
-		atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE);
-		if (ci == cur) {
-			softint_trigger(1 << SIR_PREEMPT);
-		} else {
+	if ((flags & RESCHED_KPREEMPT) != 0) {
+		if ((flags & RESCHED_REMOTE) != 0) {
 			x86_send_ipi(ci, X86_IPI_KPREEMPT);
+		} else {
+			softint_trigger(1 << SIR_PREEMPT);
 		}
 		return;
-#endif
 	}
+#endif
 
-	aston(l, X86_AST_PREEMPT);
-	if (ci == cur) {
-		return;
-	}
-	if ((flags & RESCHED_IMMED) != 0) {
+	KASSERT((flags & RESCHED_UPREEMPT) != 0);
+	if ((flags & RESCHED_REMOTE) != 0) {
 		cpu_kick(ci);
+	} else {
+		aston(l);
 	}
 }
 
@@ -345,9 +327,12 @@ cpu_signotify(struct lwp *l)
 {
 
 	KASSERT(kpreempt_disabled());
-	aston(l, X86_AST_GENERIC);
-	if (l->l_cpu != curcpu())
+
+	if (l->l_cpu != curcpu()) {
 		cpu_kick(l->l_cpu);
+	} else {
+		aston(l);
+	}
 }
 
 void
@@ -358,7 +343,7 @@ cpu_need_proftick(struct lwp *l)
 	KASSERT(l->l_cpu == curcpu());
 
 	l->l_pflag |= LP_OWEUPC;
-	aston(l, X86_AST_GENERIC);
+	aston(l);
 }
 
 bool
@@ -392,7 +377,6 @@ cpu_kpreempt_enter(uintptr_t where, int 
 	 */
 	if (s > IPL_PREEMPT) {
 		softint_trigger(1 << SIR_PREEMPT);
-		aston(l, X86_AST_PREEMPT);	/* paranoid */
 		return false;
 	}
 

Index: src/sys/arch/xen/include/intrdefs.h
diff -u src/sys/arch/xen/include/intrdefs.h:1.13 src/sys/arch/xen/include/intrdefs.h:1.14
--- src/sys/arch/xen/include/intrdefs.h:1.13	Mon Sep 10 05:08:55 2018
+++ src/sys/arch/xen/include/intrdefs.h	Sat Nov 23 19:40:38 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: intrdefs.h,v 1.13 2018/09/10 05:08:55 cherry Exp $ */
+/* $NetBSD: intrdefs.h,v 1.14 2019/11/23 19:40:38 ad Exp $ */
 
 /* This file co-exists, and is included via machine/intrdefs.h */
 
@@ -13,9 +13,10 @@
 #define XEN_IPI_XCALL		0x00000008
 #define XEN_IPI_HVCB		0x00000010
 #define XEN_IPI_GENERIC		0x00000020
+#define XEN_IPI_AST		0x00000040
 
 /* Note: IPI_KICK does not have a handler. */
-#define XEN_NIPIS		6
+#define XEN_NIPIS		7
 
 /* The number of 'irqs' that XEN understands */
 #define NUM_XEN_IRQS 		256

Index: src/sys/arch/xen/x86/cpu.c
diff -u src/sys/arch/xen/x86/cpu.c:1.130 src/sys/arch/xen/x86/cpu.c:1.131
--- src/sys/arch/xen/x86/cpu.c:1.130	Sat Oct 12 06:31:04 2019
+++ src/sys/arch/xen/x86/cpu.c	Sat Nov 23 19:40:38 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.130 2019/10/12 06:31:04 maxv Exp $	*/
+/*	$NetBSD: cpu.c,v 1.131 2019/11/23 19:40:38 ad Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.130 2019/10/12 06:31:04 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.131 2019/11/23 19:40:38 ad Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -1271,11 +1271,11 @@ cpu_broadcast_halt(void)
 }
 
 /*
- * Send a dummy ipi to a cpu.
+ * Send a dummy ipi to a cpu, and raise an AST on the running LWP.
  */
 
 void
 cpu_kick(struct cpu_info *ci)
 {
-	(void)xen_send_ipi(ci, XEN_IPI_KICK);
+	(void)xen_send_ipi(ci, XEN_IPI_AST);
 }

Index: src/sys/arch/xen/x86/xen_ipi.c
diff -u src/sys/arch/xen/x86/xen_ipi.c:1.33 src/sys/arch/xen/x86/xen_ipi.c:1.34
--- src/sys/arch/xen/x86/xen_ipi.c:1.33	Sat Oct 12 06:31:04 2019
+++ src/sys/arch/xen/x86/xen_ipi.c	Sat Nov 23 19:40:38 2019
@@ -1,7 +1,7 @@
-/* $NetBSD: xen_ipi.c,v 1.33 2019/10/12 06:31:04 maxv Exp $ */
+/* $NetBSD: xen_ipi.c,v 1.34 2019/11/23 19:40:38 ad Exp $ */
 
 /*-
- * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * Copyright (c) 2011, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -33,10 +33,10 @@
 
 /* 
  * Based on: x86/ipi.c
- * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.33 2019/10/12 06:31:04 maxv Exp $");
+ * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.34 2019/11/23 19:40:38 ad Exp $");
  */
 
-__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.33 2019/10/12 06:31:04 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.34 2019/11/23 19:40:38 ad Exp $");
 
 #include "opt_ddb.h"
 
@@ -71,6 +71,7 @@ static void xen_ipi_synch_fpu(struct cpu
 static void xen_ipi_xcall(struct cpu_info *, struct intrframe *);
 static void xen_ipi_hvcb(struct cpu_info *, struct intrframe *);
 static void xen_ipi_generic(struct cpu_info *, struct intrframe *);
+static void xen_ipi_ast(struct cpu_info *, struct intrframe *);
 
 static void (*ipifunc[XEN_NIPIS])(struct cpu_info *, struct intrframe *) =
 {	/* In order of priority (see: xen/include/intrdefs.h */
@@ -84,6 +85,7 @@ static void (*ipifunc[XEN_NIPIS])(struct
 	xen_ipi_xcall,
 	xen_ipi_hvcb,
 	xen_ipi_generic,
+	xen_ipi_ast
 };
 
 static int
@@ -152,7 +154,7 @@ valid_ipimask(uint32_t ipimask)
 {
 	uint32_t masks = XEN_IPI_GENERIC | XEN_IPI_HVCB | XEN_IPI_XCALL |
 		 XEN_IPI_DDB | XEN_IPI_SYNCH_FPU |
-		 XEN_IPI_HALT | XEN_IPI_KICK;
+		 XEN_IPI_HALT | XEN_IPI_KICK | XEN_IPI_AST;
 
 	if (ipimask & ~masks) {
 		return false;
@@ -283,6 +285,15 @@ xen_ipi_xcall(struct cpu_info *ci, struc
 	xc_ipi_handler();
 }
 
+static void
+xen_ipi_ast(struct cpu_info *ci, struct intrframe *intrf)
+{
+	KASSERT(ci != NULL);
+	KASSERT(intrf != NULL);
+
+	aston(ci->ci_data.cpu_onproc);
+}
+
 void
 xc_send_ipi(struct cpu_info *ci)
 {

Reply via email to