Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Defer bpf_mtap in Rx interrupt context to softint
details: https://anonhg.NetBSD.org/src/rev/b6ea48eea404
branches: trunk
changeset: 350836:b6ea48eea404
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Tue Jan 24 09:05:27 2017 +0000
description:
Defer bpf_mtap in Rx interrupt context to softint
bpf_mtap of some drivers is still called in hardware interrupt context.
We want to run them in softint as well as bpf_mtap of most drivers
(see if_percpuq_softint and if_input).
To this end, bpf_mtap_softint mechanism is implemented; it defers
bpf_mtap processing to a dedicated softint for a target driver.
By using the machanism, we can move bpf_mtap processing to softint
without changing target drivers much while it adds some overhead
on CPU and memory. Once target drivers are changed to softint-based,
we should return to normal bpf_mtap.
Proposed on tech-kern and tech-net
diffstat:
doc/TODO.smpnet | 28 +++++++++++
sys/dev/ic/hd64570.c | 7 +-
sys/dev/ic/midway.c | 7 +-
sys/dev/pci/if_lmc.c | 8 +-
sys/dev/pci/if_lmc.h | 10 ++-
sys/net/bpf.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++-
sys/net/bpf.h | 5 +-
sys/net/bpfdesc.h | 5 +-
sys/netisdn/i4b_ipr.c | 7 +-
9 files changed, 184 insertions(+), 20 deletions(-)
diffs (truncated from 427 to 300 lines):
diff -r 41e454209f2f -r b6ea48eea404 doc/TODO.smpnet
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/TODO.smpnet Tue Jan 24 09:05:27 2017 +0000
@@ -0,0 +1,28 @@
+$NetBSD: TODO.smpnet,v 1.1 2017/01/24 09:05:27 ozaki-r Exp $
+
+Non MP-safe components
+======================
+
+ - bpf
+ - To be listed more...
+
+bpf
+===
+
+MP-ification of bpf requires all of bpf_mtap* are called in normal LWP context
+or softint context, i.e., not in hardware interrupt context. For Tx, all
+bpf_mtap satisfy the requrement. For Rx, most of bpf_mtap are called in softint.
+Unfortunately some bpf_mtap on Rx are still called in hardware interrupt context.
+
+This is the list of the functions that have such bpf_mtap:
+
+ - sca_frame_process() @ sys/dev/ic/hd64570.c
+ - en_intr() @ sys/dev/ic/midway.c
+ - rxintr_cleanup() and txintr_cleanup() @ sys/dev/pci/if_lmc.c
+ - ipr_rx_data_rdy() @ sys/netisdn/i4b_ipr.c
+
+Ideally we should make the functions run in softint somehow, but we don't have
+actual devices, no time (or interest/love) to work on the task, so instead we
+provide a deferred bpf_mtap mechanism that forcibly runs bpf_mtap in softint
+context. It's a workaround and once the functions run in softint, we should use
+the original bpf_mtap again.
diff -r 41e454209f2f -r b6ea48eea404 sys/dev/ic/hd64570.c
--- a/sys/dev/ic/hd64570.c Tue Jan 24 07:58:58 2017 +0000
+++ b/sys/dev/ic/hd64570.c Tue Jan 24 09:05:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hd64570.c,v 1.51 2016/12/15 09:35:24 ozaki-r Exp $ */
+/* $NetBSD: hd64570.c,v 1.52 2017/01/24 09:05:28 ozaki-r Exp $ */
/*
* Copyright (c) 1999 Christian E. Hopps
@@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hd64570.c,v 1.51 2016/12/15 09:35:24 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hd64570.c,v 1.52 2017/01/24 09:05:28 ozaki-r Exp $");
#include "opt_inet.h"
@@ -457,6 +457,7 @@
if_attach(ifp);
if_alloc_sadl(ifp);
bpf_attach(ifp, DLT_HDLC, HDLC_HDRLEN);
+ bpf_mtap_softint_init(ifp);
if (sc->sc_parent == NULL)
printf("%s: port %d\n", ifp->if_xname, port);
@@ -1574,7 +1575,7 @@
return;
}
- bpf_mtap(&scp->sp_if, m); /* XXX not in softint */
+ bpf_mtap_softint(&scp->sp_if, m);
scp->sp_if.if_ipackets++;
diff -r 41e454209f2f -r b6ea48eea404 sys/dev/ic/midway.c
--- a/sys/dev/ic/midway.c Tue Jan 24 07:58:58 2017 +0000
+++ b/sys/dev/ic/midway.c Tue Jan 24 09:05:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: midway.c,v 1.98 2016/12/15 09:35:24 ozaki-r Exp $ */
+/* $NetBSD: midway.c,v 1.99 2017/01/24 09:05:28 ozaki-r Exp $ */
/* (sync'd to midway.c 1.68) */
/*
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: midway.c,v 1.98 2016/12/15 09:35:24 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: midway.c,v 1.99 2017/01/24 09:05:28 ozaki-r Exp $");
#include "opt_natm.h"
@@ -2766,7 +2766,7 @@
ifp->if_ipackets++;
#endif
- bpf_mtap(ifp, m); /* XXX not in softint */
+ bpf_mtap_softint(ifp, m);
atm_input(ifp, &ah, m, sc->rxslot[slot].rxhand);
}
@@ -3623,6 +3623,7 @@
LIST_INSERT_HEAD(&sc->sif_list, (struct pvcsif *)pvc_ifp, sif_links);
if_attach(pvc_ifp);
atm_ifattach(pvc_ifp);
+ bpf_mtap_softint_init(pvc_ifp);
#ifdef ATM_PVCEXT
rrp_add(sc, pvc_ifp);
diff -r 41e454209f2f -r b6ea48eea404 sys/dev/pci/if_lmc.c
--- a/sys/dev/pci/if_lmc.c Tue Jan 24 07:58:58 2017 +0000
+++ b/sys/dev/pci/if_lmc.c Tue Jan 24 09:05:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_lmc.c,v 1.62 2016/12/15 09:35:24 ozaki-r Exp $ */
+/* $NetBSD: if_lmc.c,v 1.63 2017/01/24 09:05:28 ozaki-r Exp $ */
/*-
* Copyright (c) 2002-2006 David Boggs. <boggs%boggs.palo-alto.ca.us@localhost>
@@ -74,7 +74,7 @@
*/
# include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_lmc.c,v 1.62 2016/12/15 09:35:24 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_lmc.c,v 1.63 2017/01/24 09:05:28 ozaki-r Exp $");
# include <sys/param.h> /* OS version */
# include "opt_inet.h" /* INET6, INET */
# include "opt_altq_enabled.h" /* ALTQ */
@@ -4294,7 +4294,7 @@
sc->status.cntrs.ipackets++;
/* Berkeley Packet Filter */
- LMC_BPF_MTAP(sc, first_mbuf); /* XXX not in softint */
+ LMC_BPF_MTAP(sc, first_mbuf);
/* Give this good packet to the network stacks. */
sc->quota--;
@@ -4446,7 +4446,7 @@
sc->status.cntrs.opackets++;
/* Berkeley Packet Filter */
- LMC_BPF_MTAP(sc, m); /* XXX not in softint */
+ LMC_BPF_MTAP(sc, m);
}
m_freem(m);
diff -r 41e454209f2f -r b6ea48eea404 sys/dev/pci/if_lmc.h
--- a/sys/dev/pci/if_lmc.h Tue Jan 24 07:58:58 2017 +0000
+++ b/sys/dev/pci/if_lmc.h Tue Jan 24 09:05:27 2017 +0000
@@ -1,5 +1,5 @@
/*-
- * $NetBSD: if_lmc.h,v 1.23 2016/04/28 00:16:56 ozaki-r Exp $
+ * $NetBSD: if_lmc.h,v 1.24 2017/01/24 09:05:28 ozaki-r Exp $
*
* Copyright (c) 2002-2006 David Boggs. (boggs%boggs.palo-alto.ca.us@localhost)
* All rights reserved.
@@ -984,8 +984,12 @@
# define SLEEP(usecs) tsleep(sc, PZERO, DEVICE_NAME, 1+(usecs/tick))
# define DMA_SYNC(map, size, flags) bus_dmamap_sync(ring->tag, map, 0, size, flags)
# define DMA_LOAD(map, addr, size) bus_dmamap_load(ring->tag, map, addr, size, 0, BUS_DMA_NOWAIT)
-# define LMC_BPF_MTAP(sc, mbuf) bpf_mtap((sc)->ifp, mbuf)
-# define LMC_BPF_ATTACH(sc, dlt, len) bpf_attach((sc)->ifp, dlt, len)
+# define LMC_BPF_MTAP(sc, mbuf) bpf_mtap_softint((sc)->ifp, mbuf)
+# define LMC_BPF_ATTACH(sc, dlt, len) \
+ do { \
+ bpf_attach((sc)->ifp, dlt, len); \
+ bpf_mtap_softint_init((sc)->ifp); \
+ } while (0)
# define LMC_BPF_DETACH(sc) bpf_detach((sc)->ifp)
static int driver_announced = 0; /* print driver info once only */
diff -r 41e454209f2f -r b6ea48eea404 sys/net/bpf.c
--- a/sys/net/bpf.c Tue Jan 24 07:58:58 2017 +0000
+++ b/sys/net/bpf.c Tue Jan 24 09:05:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf.c,v 1.204 2017/01/23 10:17:36 ozaki-r Exp $ */
+/* $NetBSD: bpf.c,v 1.205 2017/01/24 09:05:28 ozaki-r Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@@ -39,12 +39,13 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.204 2017/01/23 10:17:36 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.205 2017/01/24 09:05:28 ozaki-r Exp $");
#if defined(_KERNEL_OPT)
#include "opt_bpf.h"
#include "sl.h"
#include "strip.h"
+#include "opt_net_mpsafe.h"
#endif
#include <sys/param.h>
@@ -60,6 +61,7 @@
#include <sys/stat.h>
#include <sys/module.h>
#include <sys/atomic.h>
+#include <sys/cpu.h>
#include <sys/file.h>
#include <sys/filedesc.h>
@@ -73,6 +75,7 @@
#include <sys/poll.h>
#include <sys/sysctl.h>
#include <sys/kauth.h>
+#include <sys/syslog.h>
#include <net/if.h>
#include <net/slip.h>
@@ -1594,6 +1597,92 @@
m_freem(m);
}
+static struct mbuf *
+bpf_mbuf_enqueue(struct bpf_if *bp, struct mbuf *m)
+{
+ struct mbuf *dup;
+
+ dup = m_dup(m, 0, M_COPYALL, M_NOWAIT);
+ if (dup == NULL)
+ return NULL;
+
+ if (bp->bif_mbuf_tail != NULL) {
+ bp->bif_mbuf_tail->m_nextpkt = dup;
+ } else {
+ bp->bif_mbuf_head = dup;
+ }
+ bp->bif_mbuf_tail = dup;
+#ifdef BPF_MTAP_SOFTINT_DEBUG
+ log(LOG_DEBUG, "%s: enqueued mbuf=%p to %s\n",
+ __func__, dup, bp->bif_ifp->if_xname);
+#endif
+
+ return dup;
+}
+
+static struct mbuf *
+bpf_mbuf_dequeue(struct bpf_if *bp)
+{
+ struct mbuf *m;
+ int s;
+
+ s = splnet();
+ m = bp->bif_mbuf_head;
+ if (m != NULL) {
+ bp->bif_mbuf_head = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+
+ if (bp->bif_mbuf_head == NULL)
+ bp->bif_mbuf_tail = NULL;
+#ifdef BPF_MTAP_SOFTINT_DEBUG
+ log(LOG_DEBUG, "%s: dequeued mbuf=%p from %s\n",
+ __func__, m, bp->bif_ifp->if_xname);
+#endif
+ }
+ splx(s);
+
+ return m;
+}
+
+static void
+bpf_mtap_si(void *arg)
+{
+ struct bpf_if *bp = arg;
+ struct mbuf *m;
+
+ while ((m = bpf_mbuf_dequeue(bp)) != NULL) {
+#ifdef BPF_MTAP_SOFTINT_DEBUG
+ log(LOG_DEBUG, "%s: tapping mbuf=%p on %s\n",
+ __func__, m, bp->bif_ifp->if_xname);
+#endif
+#ifndef NET_MPSAFE
+ KERNEL_LOCK(1, NULL);
+#endif
+ bpf_ops->bpf_mtap(bp, m);
+#ifndef NET_MPSAFE
+ KERNEL_UNLOCK_ONE(NULL);
+#endif
+ m_freem(m);
+ }
+}
+
+void
+bpf_mtap_softint(struct ifnet *ifp, struct mbuf *m)
+{
+ struct bpf_if *bp = ifp->if_bpf;
+ struct mbuf *dup;
+
+ KASSERT(cpu_intr_p());
+
+ if (bp == NULL || bp->bif_dlist == NULL)
+ return;
+ KASSERT(bp->bif_si != NULL);
+
+ dup = bpf_mbuf_enqueue(bp, m);
+ if (dup != NULL)
+ softint_schedule(bp->bif_si);
+}
+
static int
bpf_hdrlen(struct bpf_d *d)
{
@@ -1790,6 +1879,7 @@
bp->bif_driverp = driverp;
bp->bif_ifp = ifp;
bp->bif_dlt = dlt;
Home |
Main Index |
Thread Index |
Old Index