Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-8]: src Pull up following revision(s) (requested by ozaki-r in ti...
details: https://anonhg.NetBSD.org/src/rev/7475244c1a29
branches: netbsd-8
changeset: 434647:7475244c1a29
user: snj <snj%NetBSD.org@localhost>
date: Mon Feb 19 18:33:38 2018 +0000
description:
Pull up following revision(s) (requested by ozaki-r in ticket #556):
sys/sys/xcall.h: 1.6
share/man/man9/xcall.9: 1.11-1.12
sys/kern/subr_xcall.c: 1.21-1.25
Refer softint(9)
--
Support arbitrary softint IPLs in high priority xcall
The high priority xcall supported only a softint of IPL_SOFTSERIAL. It meant
that it didn't work for xcall callbacks depending on lower IPLs than
IPL_SOFTSERIAL.
The change makes xcall have multiple softints of IPLs and allow users to specify
arbitrary IPLs. Users can specify an IPL by XC_HIGHPRI_IPL passed to the 1st
argument of xc_broadcast or xc_unicast.
Note that xcall still serves requests one by one (i.e., doesn't run them
concurrently) even if requests have different IPLs.
Proposed on tech-kern@
--
Use high priority xcall with a softint of an IPL the same as psref class's one
This mitigates undesired delay of psref_target_destroy under load such as heavy
netowrk traffic that loads softint.
--
Try to fix the build: avoid duplicate case labels when IPL_SOFT* are
all the same.
--
Fix build of kernels that some (or all) IPL_SOFT* share a value (e.g., mips)
--
Avoid allocating unused softints that share a value of IPL between another
Sort XC_IPL_* in order of priority (NFC)
diffstat:
share/man/man9/xcall.9 | 19 ++++++-
sys/kern/subr_psref.c | 9 ++-
sys/kern/subr_xcall.c | 112 +++++++++++++++++++++++++++++++++++++++++++-----
sys/sys/xcall.h | 7 ++-
4 files changed, 125 insertions(+), 22 deletions(-)
diffs (truncated from 338 to 300 lines):
diff -r 3839b6260638 -r 7475244c1a29 share/man/man9/xcall.9
--- a/share/man/man9/xcall.9 Mon Feb 19 18:26:44 2018 +0000
+++ b/share/man/man9/xcall.9 Mon Feb 19 18:33:38 2018 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: xcall.9,v 1.10 2013/11/26 20:48:25 rmind Exp $
+.\" $NetBSD: xcall.9,v 1.10.18.1 2018/02/19 18:33:38 snj Exp $
.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd November 26, 2013
+.Dd February 1, 2018
.Dt XCALL 9
.Os
.Sh NAME
@@ -87,7 +87,6 @@
.Dq "high priority"
cross calls.
The function to be executed runs on the remote CPU within a
-.Dv IPL_SOFTSERIAL
software interrupt context, possibly interrupting other lower-priority
code running on the CPU.
.Sh NOTES
@@ -112,7 +111,18 @@
.Fa flags
should be
.Dv XC_HIGHPRI
+or
+.Fo XC_HIGHPRI_IPL
+.Fa ipl
+.Fc
for a "high priority" call, and 0 for a "low priority" call.
+.Dv XC_HIGHPRI
+uses an
+.Dv IPL_SOFTSERIAL
+software interrupt while
+.Fn XC_HIGHPRI_IPL
+uses a software interrupt with an IPL specified by
+.Fa ipl .
.Fn xc_broadcast
should not be called from interrupt context.
.It Fn xc_unicast "flags" "func" "arg1" "arg2" "ci"
@@ -144,7 +154,8 @@
.\" .Sh EXAMPLES
.Sh SEE ALSO
.Xr kpreempt 9 ,
-.Xr percpu 9
+.Xr percpu 9 ,
+.Xr softint 9
.Sh HISTORY
The
.Nm
diff -r 3839b6260638 -r 7475244c1a29 sys/kern/subr_psref.c
--- a/sys/kern/subr_psref.c Mon Feb 19 18:26:44 2018 +0000
+++ b/sys/kern/subr_psref.c Mon Feb 19 18:33:38 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_psref.c,v 1.7.2.2 2018/01/22 12:30:20 martin Exp $ */
+/* $NetBSD: subr_psref.c,v 1.7.2.3 2018/02/19 18:33:38 snj Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_psref.c,v 1.7.2.2 2018/01/22 12:30:20 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_psref.c,v 1.7.2.3 2018/02/19 18:33:38 snj Exp $");
#include <sys/types.h>
#include <sys/condvar.h>
@@ -94,6 +94,7 @@
kcondvar_t prc_cv;
struct percpu *prc_percpu; /* struct psref_cpu */
ipl_cookie_t prc_iplcookie;
+ unsigned int prc_xc_flags;
};
/*
@@ -124,6 +125,7 @@
mutex_init(&class->prc_lock, MUTEX_DEFAULT, ipl);
cv_init(&class->prc_cv, name);
class->prc_iplcookie = makeiplcookie(ipl);
+ class->prc_xc_flags = XC_HIGHPRI_IPL(ipl);
return class;
}
@@ -434,7 +436,8 @@
* Ask all CPUs to say whether they hold a psref to the
* target.
*/
- xc_wait(xc_broadcast(0, &psreffed_p_xc, &P, NULL));
+ xc_wait(xc_broadcast(class->prc_xc_flags, &psreffed_p_xc, &P,
+ NULL));
} else
psreffed_p_xc(&P, NULL);
diff -r 3839b6260638 -r 7475244c1a29 sys/kern/subr_xcall.c
--- a/sys/kern/subr_xcall.c Mon Feb 19 18:26:44 2018 +0000
+++ b/sys/kern/subr_xcall.c Mon Feb 19 18:33:38 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_xcall.c,v 1.19 2016/11/21 00:54:21 ozaki-r Exp $ */
+/* $NetBSD: subr_xcall.c,v 1.19.8.1 2018/02/19 18:33:38 snj Exp $ */
/*-
* Copyright (c) 2007-2010 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_xcall.c,v 1.19 2016/11/21 00:54:21 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_xcall.c,v 1.19.8.1 2018/02/19 18:33:38 snj Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -98,6 +98,7 @@
void * xc_arg2;
uint64_t xc_headp;
uint64_t xc_donep;
+ unsigned int xc_ipl;
} xc_state_t;
/* Bit indicating high (1) or low (0) priority. */
@@ -108,7 +109,7 @@
/* High priority xcall structures. */
static xc_state_t xc_high_pri __cacheline_aligned;
-static void * xc_sih __cacheline_aligned;
+static void * xc_sihs[4] __cacheline_aligned;
/* Event counters. */
static struct evcnt xc_unicast_ev __cacheline_aligned;
@@ -117,9 +118,24 @@
static void xc_init(void);
static void xc_thread(void *);
-static inline uint64_t xc_highpri(xcfunc_t, void *, void *, struct cpu_info *);
+static inline uint64_t xc_highpri(xcfunc_t, void *, void *, struct cpu_info *,
+ unsigned int);
static inline uint64_t xc_lowpri(xcfunc_t, void *, void *, struct cpu_info *);
+/* The internal form of IPL */
+#define XC_IPL_MASK 0xff00
+/*
+ * Assign 0 to XC_IPL_SOFTSERIAL to treat IPL_SOFTSERIAL as the default value
+ * (just XC_HIGHPRI).
+ */
+#define XC_IPL_SOFTSERIAL 0
+#define XC_IPL_SOFTNET 1
+#define XC_IPL_SOFTBIO 2
+#define XC_IPL_SOFTCLOCK 3
+#define XC_IPL_MAX XC_IPL_SOFTCLOCK
+
+CTASSERT(XC_IPL_MAX <= __arraycount(xc_sihs));
+
/*
* xc_init:
*
@@ -137,9 +153,31 @@
memset(xchi, 0, sizeof(xc_state_t));
mutex_init(&xchi->xc_lock, MUTEX_DEFAULT, IPL_SOFTSERIAL);
cv_init(&xchi->xc_busy, "xchicv");
- xc_sih = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE,
- xc__highpri_intr, NULL);
- KASSERT(xc_sih != NULL);
+
+ /* Set up a softint for each IPL_SOFT*. */
+#define SETUP_SOFTINT(xipl, sipl) do { \
+ xc_sihs[(xipl)] = softint_establish( (sipl) | SOFTINT_MPSAFE,\
+ xc__highpri_intr, NULL); \
+ KASSERT(xc_sihs[(xipl)] != NULL); \
+ } while (0)
+
+ SETUP_SOFTINT(XC_IPL_SOFTSERIAL, SOFTINT_SERIAL);
+ /*
+ * If a IPL_SOFTXXX have the same value of the previous, we don't use
+ * the IPL (see xc_encode_ipl). So we don't need to allocate a softint
+ * for it.
+ */
+#if IPL_SOFTNET != IPL_SOFTSERIAL
+ SETUP_SOFTINT(XC_IPL_SOFTNET, SOFTINT_NET);
+#endif
+#if IPL_SOFTBIO != IPL_SOFTNET
+ SETUP_SOFTINT(XC_IPL_SOFTBIO, SOFTINT_BIO);
+#endif
+#if IPL_SOFTCLOCK != IPL_SOFTBIO
+ SETUP_SOFTINT(XC_IPL_SOFTCLOCK, SOFTINT_CLOCK);
+#endif
+
+#undef SETUP_SOFTINT
evcnt_attach_dynamic(&xc_unicast_ev, EVCNT_TYPE_MISC, NULL,
"crosscall", "unicast");
@@ -148,6 +186,45 @@
}
/*
+ * Encode an IPL to a form that can be embedded into flags of xc_broadcast
+ * or xc_unicast.
+ */
+unsigned int
+xc_encode_ipl(int ipl)
+{
+
+ switch (ipl) {
+ case IPL_SOFTSERIAL:
+ return __SHIFTIN(XC_IPL_SOFTSERIAL, XC_IPL_MASK);
+ /* IPL_SOFT* can be the same value (e.g., on sparc or mips). */
+#if IPL_SOFTNET != IPL_SOFTSERIAL
+ case IPL_SOFTNET:
+ return __SHIFTIN(XC_IPL_SOFTNET, XC_IPL_MASK);
+#endif
+#if IPL_SOFTBIO != IPL_SOFTNET
+ case IPL_SOFTBIO:
+ return __SHIFTIN(XC_IPL_SOFTBIO, XC_IPL_MASK);
+#endif
+#if IPL_SOFTCLOCK != IPL_SOFTBIO
+ case IPL_SOFTCLOCK:
+ return __SHIFTIN(XC_IPL_SOFTCLOCK, XC_IPL_MASK);
+#endif
+ }
+
+ panic("Invalid IPL: %d", ipl);
+}
+
+/*
+ * Extract an XC_IPL from flags of xc_broadcast or xc_unicast.
+ */
+static inline unsigned int
+xc_extract_ipl(unsigned int flags)
+{
+
+ return __SHIFTOUT(flags, XC_IPL_MASK);
+}
+
+/*
* xc_init_cpu:
*
* Initialize the cross-call subsystem. Called once for each CPU
@@ -176,13 +253,14 @@
* Trigger a call on all CPUs in the system.
*/
uint64_t
-xc_broadcast(u_int flags, xcfunc_t func, void *arg1, void *arg2)
+xc_broadcast(unsigned int flags, xcfunc_t func, void *arg1, void *arg2)
{
KASSERT(!cpu_intr_p() && !cpu_softintr_p());
if ((flags & XC_HIGHPRI) != 0) {
- return xc_highpri(func, arg1, arg2, NULL);
+ int ipl = xc_extract_ipl(flags);
+ return xc_highpri(func, arg1, arg2, NULL, ipl);
} else {
return xc_lowpri(func, arg1, arg2, NULL);
}
@@ -194,7 +272,7 @@
* Trigger a call on one CPU.
*/
uint64_t
-xc_unicast(u_int flags, xcfunc_t func, void *arg1, void *arg2,
+xc_unicast(unsigned int flags, xcfunc_t func, void *arg1, void *arg2,
struct cpu_info *ci)
{
@@ -202,7 +280,8 @@
KASSERT(!cpu_intr_p() && !cpu_softintr_p());
if ((flags & XC_HIGHPRI) != 0) {
- return xc_highpri(func, arg1, arg2, ci);
+ int ipl = xc_extract_ipl(flags);
+ return xc_highpri(func, arg1, arg2, ci, ipl);
} else {
return xc_lowpri(func, arg1, arg2, ci);
}
@@ -329,8 +408,13 @@
void
xc_ipi_handler(void)
{
+ xc_state_t *xc = & xc_high_pri;
+
+ KASSERT(xc->xc_ipl < __arraycount(xc_sihs));
+ KASSERT(xc_sihs[xc->xc_ipl] != NULL);
+
/* Executes xc__highpri_intr() via software interrupt. */
- softint_schedule(xc_sih);
+ softint_schedule(xc_sihs[xc->xc_ipl]);
}
/*
@@ -375,7 +459,8 @@
* Trigger a high priority call on one or more CPUs.
*/
static inline uint64_t
-xc_highpri(xcfunc_t func, void *arg1, void *arg2, struct cpu_info *ci)
+xc_highpri(xcfunc_t func, void *arg1, void *arg2, struct cpu_info *ci,
+ unsigned int ipl)
{
Home |
Main Index |
Thread Index |
Old Index