summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2016-05-03 14:52:39 +0000
committermpi <mpi@openbsd.org>2016-05-03 14:52:39 +0000
commit72cad57c530700bc0ee61bd93860a3d2f898f8b0 (patch)
tree934dc9d745ddad6a604f0777250238c45937bcce
parentsupport doas (diff)
downloadwireguard-openbsd-72cad57c530700bc0ee61bd93860a3d2f898f8b0.tar.xz
wireguard-openbsd-72cad57c530700bc0ee61bd93860a3d2f898f8b0.zip
Stop using a soft-interrupt context to process incoming network packets.
Use a new task that runs holding the KERNEL_LOCK to execute mp-unsafe code. Our current goal is to progressively move input functions to the unlocked task. This gives a small performance boost confirmed by Hrvoje Popovski's IPv4 forwarding measurement: before: after: send receive send receive 400kpps 400kpps 400kpps 400kpps 500kpps 500kpps 500kpps 500kpps 600kpps 600kpps 600kpps 600kpps 650kpps 650kpps 650kpps 640kpps 700kpps 700kpps 700kpps 700kpps 720kpps 640kpps 720kpps 710kpps 800kpps 640kpps 800kpps 650kpps 1.4Mpps 570kpps 1.4Mpps 590kpps 14Mpps 570kpps 14Mpps 590kpps ok kettenis@, bluhm@, dlg@
-rw-r--r--sys/conf/files3
-rw-r--r--sys/kern/init_main.c3
-rw-r--r--sys/net/if.c65
-rw-r--r--sys/net/netisr.c74
-rw-r--r--sys/net/netisr.h14
5 files changed, 65 insertions, 94 deletions
diff --git a/sys/conf/files b/sys/conf/files
index d22604bc13b..a061c7f0a0e 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.618 2016/04/25 20:09:14 tedu Exp $
+# $OpenBSD: files,v 1.619 2016/05/03 14:52:39 mpi Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -763,7 +763,6 @@ file net/if_spppsubr.c sppp
file net/if_loop.c loop
file net/if_media.c ifmedia
file net/if_ppp.c ppp needs-count
-file net/netisr.c
file net/ppp_tty.c ppp
file net/bsd-comp.c ppp_bsdcomp
file net/ppp-deflate.c ppp_deflate
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 312bd87e1ea..61110b51abb 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.249 2016/03/19 12:04:15 natano Exp $ */
+/* $OpenBSD: init_main.c,v 1.250 2016/05/03 14:52:39 mpi Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -394,7 +394,6 @@ main(void *framep)
* until everything is ready.
*/
s = splnet();
- netisr_init();
domaininit();
splx(s);
diff --git a/sys/net/if.c b/sys/net/if.c
index fbe239d38a0..55cbda3382e 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.429 2016/03/16 12:08:09 dlg Exp $ */
+/* $OpenBSD: if.c,v 1.430 2016/05/03 14:52:39 mpi Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -64,9 +64,12 @@
#include "bpfilter.h"
#include "bridge.h"
#include "carp.h"
+#include "ether.h"
#include "pf.h"
+#include "pfsync.h"
+#include "ppp.h"
+#include "pppoe.h"
#include "trunk.h"
-#include "ether.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -148,6 +151,7 @@ int if_group_egress_build(void);
void if_watchdog_task(void *);
void if_input_process(void *);
+void if_netisr(void *);
#ifdef DDB
void ifa_print_all(void);
@@ -216,13 +220,15 @@ void net_tick(void *);
int net_livelocked(void);
int ifq_congestion;
-struct taskq *softnettq;
+int netisr;
+struct taskq *softnettq;
+
+struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET);
+struct task if_input_task = TASK_INITIALIZER(if_input_process, &if_input_queue);
+struct task if_input_task_locked = TASK_INITIALIZER(if_netisr, NULL);
/*
* Network interface utility routines.
- *
- * Routines with ifa_ifwith* names take sockaddr *'s as
- * parameters.
*/
void
ifinit(void)
@@ -590,9 +596,6 @@ if_enqueue(struct ifnet *ifp, struct mbuf *m)
return (0);
}
-struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET);
-struct task if_input_task = TASK_INITIALIZER(if_input_process, &if_input_queue);
-
void
if_input(struct ifnet *ifp, struct mbuf_list *ml)
{
@@ -806,6 +809,50 @@ if_input_process(void *xmq)
}
void
+if_netisr(void *unused)
+{
+ int n, t = 0;
+ int s;
+
+ KERNEL_LOCK();
+ s = splsoftnet();
+
+ while ((n = netisr) != 0) {
+ sched_pause();
+
+ atomic_clearbits_int(&netisr, n);
+
+ if (n & (1 << NETISR_IP))
+ ipintr();
+#ifdef INET6
+ if (n & (1 << NETISR_IPV6))
+ ip6intr();
+#endif
+#if NPPP > 0
+ if (n & (1 << NETISR_PPP))
+ pppintr();
+#endif
+#if NBRIDGE > 0
+ if (n & (1 << NETISR_BRIDGE))
+ bridgeintr();
+#endif
+#if NPPPOE > 0
+ if (n & (1 << NETISR_PPPOE))
+ pppoeintr();
+#endif
+ t |= n;
+ }
+
+#if NPFSYNC > 0
+ if (t & (1 << NETISR_PFSYNC))
+ pfsyncintr();
+#endif
+
+ splx(s);
+ KERNEL_UNLOCK();
+}
+
+void
if_deactivate(struct ifnet *ifp)
{
int s;
diff --git a/sys/net/netisr.c b/sys/net/netisr.c
deleted file mode 100644
index 7b6475be1b8..00000000000
--- a/sys/net/netisr.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2010 Owain G. Ainsworth <oga@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <net/netisr.h>
-
-#include <machine/intr.h>
-
-#include "ppp.h"
-#include "bridge.h"
-#include "pppoe.h"
-#include "pfsync.h"
-
-void netintr(void *);
-
-int netisr;
-void *netisr_intr;
-
-void
-netintr(void *unused)
-{
- int n, t = 0;
-
- while ((n = netisr) != 0) {
- atomic_clearbits_int(&netisr, n);
-
- if (n & (1 << NETISR_IP))
- ipintr();
-#ifdef INET6
- if (n & (1 << NETISR_IPV6))
- ip6intr();
-#endif
-#if NPPP > 0
- if (n & (1 << NETISR_PPP))
- pppintr();
-#endif
-#if NBRIDGE > 0
- if (n & (1 << NETISR_BRIDGE))
- bridgeintr();
-#endif
-#if NPPPOE > 0
- if (n & (1 << NETISR_PPPOE))
- pppoeintr();
-#endif
- t |= n;
- }
-
-#if NPFSYNC > 0
- if (t & (1 << NETISR_PFSYNC))
- pfsyncintr();
-#endif
-}
-
-void
-netisr_init(void)
-{
- netisr_intr = softintr_establish(IPL_SOFTNET, netintr, NULL);
- if (netisr_intr == NULL)
- panic("can't establish softnet handler");
-}
diff --git a/sys/net/netisr.h b/sys/net/netisr.h
index 482c7c8ce00..5c709f5b76d 100644
--- a/sys/net/netisr.h
+++ b/sys/net/netisr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: netisr.h,v 1.44 2016/01/08 13:53:24 mpi Exp $ */
+/* $OpenBSD: netisr.h,v 1.45 2016/05/03 14:52:39 mpi Exp $ */
/* $NetBSD: netisr.h,v 1.12 1995/08/12 23:59:24 mycroft Exp $ */
/*
@@ -61,7 +61,12 @@
#ifndef _LOCORE
#ifdef _KERNEL
+
+#include <sys/task.h>
+#include <sys/atomic.h>
+
extern int netisr; /* scheduling bits for network */
+extern struct task if_input_task_locked;
void ipintr(void);
void ip6intr(void);
@@ -70,17 +75,12 @@ void bridgeintr(void);
void pppoeintr(void);
void pfsyncintr(void);
-#include <machine/atomic.h>
-
-extern void *netisr_intr;
#define schednetisr(anisr) \
do { \
atomic_setbits_int(&netisr, (1 << (anisr))); \
- softintr_schedule(netisr_intr); \
+ task_add(softnettq, &if_input_task_locked); \
} while (/* CONSTCOND */0)
-void netisr_init(void);
-
#endif /* _KERNEL */
#endif /*_LOCORE */