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().
This commit is contained in:
ad 2019-11-23 19:40:34 +00:00
parent a44072499c
commit 115c1bc097
43 changed files with 264 additions and 433 deletions

View File

@ -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

View File

@ -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 mcontext_t *mcp, unsigned int flags)
* 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) */
}
}

View File

@ -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)

View File

@ -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) {
setsoftast(ci);
return;
}
ipi = IPI_AST;
send_ipi:
intr_ipi_send(ci->ci_kcpuset, ipi);
#else
setsoftast(ci);
intr_ipi_send(ci->ci_kcpuset, IPI_AST);
#endif /* MULTIPROCESSOR */
} else {
setsoftast(ci);
}
}
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)
{

View File

@ -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_info, ci_arm_cpuid)
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])

View File

@ -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)

View File

@ -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)

View File

@ -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_depth;
* 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

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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 mcontext_t *mcp, unsigned int flags)
}
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

View File

@ -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>
@ -73,6 +73,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)
{
@ -120,7 +126,7 @@ ipi_process(struct cpu_info *ci, uint64_t ipi_mask)
}
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++;

View File

@ -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_depth;
* 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)

View File

@ -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)

View File

@ -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_depth;
* 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)

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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 *ci)
}
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

View File

@ -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_info, ci_data.cpu_idlelwp)
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])

View File

@ -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 mcontext_t *mcp, unsigned int flags)
}
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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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_info, ci_spinup)
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)

View File

@ -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 mcontext_t *mcp, unsigned int flags)
* 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
}

View File

@ -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 before returning to user mode */
*/
#define cpu_need_resched(ci,flags) do { \
__USE(flags); \
ci->ci_want_resched = 1; \
aston(); \
} while (/*CONSTCOND*/0)

View File

@ -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 <jmcneill@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);
}

View File

@ -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 <jmcneill@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 {

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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" }

View File

@ -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);
}

View File

@ -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 2019/10/12 06:31:04 maxv Exp $");
#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_info *);
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 cpu_info *) =
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.
*/

View File

@ -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
}
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 s)
*/
if (s > IPL_PREEMPT) {
softint_trigger(1 << SIR_PREEMPT);
aston(l, X86_AST_PREEMPT); /* paranoid */
return false;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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_info *, struct intrframe *);
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 cpu_info *, struct intrframe *) =
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, struct intrframe *intrf)
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)
{