Re: Moving away from softnet interrupts
On Mon, May 02, 2016 at 11:27:36AM +0200, Martin Pieuchot wrote: > On 18/04/16(Mon) 10:50, Martin Pieuchot wrote: > > The current goal of the Network SMP effort is to have a single CPU > > process the IP forwarding path in a process context without holding > > the KERNEL_LOCK(). To achieve this goal we're progressively moving > > code from the softnet interrupt context to the if_input_task. In > > the end we'll completely get rid of this soft-interrupt. > > > > So now would be a good time to know if moving all the code currently > > run in a soft-interrupt context to a task uncovers any bug. I'm > > happily running the diff below on amd64 and macppc, it even gives me > > a small performance boost. > > > > I'd appreciate more tests especially on exotic archs. > > So far this has been tested on amd64, i386, powerpc, mips64 and sparc. > > So I'm looking for oks. OK bluhm@ > > > Index: net/if.c > > === > > RCS file: /cvs/src/sys/net/if.c,v > > retrieving revision 1.429 > > diff -u -p -r1.429 if.c > > --- net/if.c16 Mar 2016 12:08:09 - 1.429 > > +++ net/if.c18 Apr 2016 08:00:08 - > > @@ -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 > > #include > > @@ -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 *); > > intnet_livelocked(void); > > intifq_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, > > _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 mbu > > return (0); > > } > > > > -struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); > > -struct task if_input_task = TASK_INITIALIZER(if_input_process, > > _input_queue); > > - > > void > > if_input(struct ifnet *ifp, struct mbuf_list *ml) > > { > > @@ -803,6 +806,50 @@ if_input_process(void *xmq) > > if_put(ifp); > > } > > splx(s); > > +} > > + > > +void > > +if_netisr(void *unused) > > +{ > > + int n, t = 0; > > + int s; > > + > > + KERNEL_LOCK(); > > + s = splsoftnet(); > > + > > + while ((n = netisr) != 0) { > > + sched_pause(); > > + > > + atomic_clearbits_int(, 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 > > Index: net/netisr.c > > === > > RCS file: net/netisr.c > > diff -N net/netisr.c > > --- net/netisr.c8 Jan 2016 13:53:24 - 1.10 > > +++ /dev/null 1 Jan 1970 00:00:00 - > > @@ -1,74 +0,0 @@ > > -/* > > - * Copyright (c) 2010 Owain G. Ainsworth> > - * > > - * 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
Re: Moving away from softnet interrupts
> Date: Mon, 2 May 2016 11:27:36 +0200 > From: Martin Pieuchot> > On 18/04/16(Mon) 10:50, Martin Pieuchot wrote: > > The current goal of the Network SMP effort is to have a single CPU > > process the IP forwarding path in a process context without holding > > the KERNEL_LOCK(). To achieve this goal we're progressively moving > > code from the softnet interrupt context to the if_input_task. In > > the end we'll completely get rid of this soft-interrupt. > > > > So now would be a good time to know if moving all the code currently > > run in a soft-interrupt context to a task uncovers any bug. I'm > > happily running the diff below on amd64 and macppc, it even gives me > > a small performance boost. > > > > I'd appreciate more tests especially on exotic archs. > > So far this has been tested on amd64, i386, powerpc, mips64 and sparc. And sparc64 (with em, vnet and bridge). No real performance testing done, but I noticed no issues. > So I'm looking for oks. ok kettenis@ > > Index: net/if.c > > === > > RCS file: /cvs/src/sys/net/if.c,v > > retrieving revision 1.429 > > diff -u -p -r1.429 if.c > > --- net/if.c16 Mar 2016 12:08:09 - 1.429 > > +++ net/if.c18 Apr 2016 08:00:08 - > > @@ -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 > > #include > > @@ -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 *); > > intnet_livelocked(void); > > intifq_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, > > _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 mbu > > return (0); > > } > > > > -struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); > > -struct task if_input_task = TASK_INITIALIZER(if_input_process, > > _input_queue); > > - > > void > > if_input(struct ifnet *ifp, struct mbuf_list *ml) > > { > > @@ -803,6 +806,50 @@ if_input_process(void *xmq) > > if_put(ifp); > > } > > splx(s); > > +} > > + > > +void > > +if_netisr(void *unused) > > +{ > > + int n, t = 0; > > + int s; > > + > > + KERNEL_LOCK(); > > + s = splsoftnet(); > > + > > + while ((n = netisr) != 0) { > > + sched_pause(); > > + > > + atomic_clearbits_int(, 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 > > Index: net/netisr.c > > === > > RCS file: net/netisr.c > > diff -N net/netisr.c > > --- net/netisr.c8 Jan 2016 13:53:24 - 1.10 > > +++ /dev/null 1 Jan 1970 00:00:00 - > > @@ -1,74 +0,0 @@ > > -/* > > - * Copyright (c) 2010 Owain G. Ainsworth > > - * > > - * 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
Re: Moving away from softnet interrupts
On 18/04/16(Mon) 10:50, Martin Pieuchot wrote: > The current goal of the Network SMP effort is to have a single CPU > process the IP forwarding path in a process context without holding > the KERNEL_LOCK(). To achieve this goal we're progressively moving > code from the softnet interrupt context to the if_input_task. In > the end we'll completely get rid of this soft-interrupt. > > So now would be a good time to know if moving all the code currently > run in a soft-interrupt context to a task uncovers any bug. I'm > happily running the diff below on amd64 and macppc, it even gives me > a small performance boost. > > I'd appreciate more tests especially on exotic archs. So far this has been tested on amd64, i386, powerpc, mips64 and sparc. So I'm looking for oks. > Index: net/if.c > === > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.429 > diff -u -p -r1.429 if.c > --- net/if.c 16 Mar 2016 12:08:09 - 1.429 > +++ net/if.c 18 Apr 2016 08:00:08 - > @@ -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 > #include > @@ -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 @@ voidnet_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, > _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 mbu > return (0); > } > > -struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); > -struct task if_input_task = TASK_INITIALIZER(if_input_process, > _input_queue); > - > void > if_input(struct ifnet *ifp, struct mbuf_list *ml) > { > @@ -803,6 +806,50 @@ if_input_process(void *xmq) > if_put(ifp); > } > splx(s); > +} > + > +void > +if_netisr(void *unused) > +{ > + int n, t = 0; > + int s; > + > + KERNEL_LOCK(); > + s = splsoftnet(); > + > + while ((n = netisr) != 0) { > + sched_pause(); > + > + atomic_clearbits_int(, 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 > Index: net/netisr.c > === > RCS file: net/netisr.c > diff -N net/netisr.c > --- net/netisr.c 8 Jan 2016 13:53:24 - 1.10 > +++ /dev/null 1 Jan 1970 00:00:00 - > @@ -1,74 +0,0 @@ > -/* > - * Copyright (c) 2010 Owain G. Ainsworth> - * > - * 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 > -#include > - > -#include > - > -#include > - > -#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(, n);
Re: Moving away from softnet interrupts
2016-04-25 9:59 GMT+02:00 Martin Pieuchot: > > > The current goal of the Network SMP effort is to have a single CPU > > > process the IP forwarding path in a process context without holding > > > the KERNEL_LOCK(). To achieve this goal we're progressively moving > > > code from the softnet interrupt context to the if_input_task. In > > > the end we'll completely get rid of this soft-interrupt. > > > > > > So now would be a good time to know if moving all the code currently > > > run in a soft-interrupt context to a task uncovers any bug. I'm > > > happily running the diff below on amd64 and macppc, it even gives me > > > a small performance boost. > > > > > > I'd appreciate more tests especially on exotic archs. > > > I'm still looking for reports on different architectures. > > I ran this overnight on my edgerouter lite, it has survived a few cvs-up's and building a kernel over NFS. So octeon doesn't seem to mind the patch. -- May the most significant bit of your life be positive.
Re: Moving away from softnet interrupts
On 20/04/16(Wed) 09:33, Dimitris Papastamos wrote: > On Mon, Apr 18, 2016 at 10:50:46AM +0200, Martin Pieuchot wrote: > > The current goal of the Network SMP effort is to have a single CPU > > process the IP forwarding path in a process context without holding > > the KERNEL_LOCK(). To achieve this goal we're progressively moving > > code from the softnet interrupt context to the if_input_task. In > > the end we'll completely get rid of this soft-interrupt. > > > > So now would be a good time to know if moving all the code currently > > run in a soft-interrupt context to a task uncovers any bug. I'm > > happily running the diff below on amd64 and macppc, it even gives me > > a small performance boost. > > > > I'd appreciate more tests especially on exotic archs. > > I've been running with this diff since you posted it on my home router. > I have not encountered any issues. Thanks for testing. I'm still looking for reports on different architectures.
Re: Moving away from softnet interrupts
On Mon, Apr 18, 2016 at 10:50:46AM +0200, Martin Pieuchot wrote: > The current goal of the Network SMP effort is to have a single CPU > process the IP forwarding path in a process context without holding > the KERNEL_LOCK(). To achieve this goal we're progressively moving > code from the softnet interrupt context to the if_input_task. In > the end we'll completely get rid of this soft-interrupt. > > So now would be a good time to know if moving all the code currently > run in a soft-interrupt context to a task uncovers any bug. I'm > happily running the diff below on amd64 and macppc, it even gives me > a small performance boost. > > I'd appreciate more tests especially on exotic archs. I've been running with this diff since you posted it on my home router. I have not encountered any issues. See ifconfig/route show/sysctl.conf/dmesg output below. ifconfig: lo0: flags=8049mtu 32768 priority: 0 groups: lo inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 inet 127.0.0.1 netmask 0xff00 re0: flags=18843 mtu 1500 lladdr 90:e6:ba:74:0e:38 description: WAN priority: 0 groups: egress media: Ethernet autoselect (1000baseT full-duplex,rxpause,txpause) status: active inet 82.13.64.4 netmask 0xf000 broadcast 82.13.79.255 re1: flags=18b43 mtu 1500 lladdr 80:ee:73:9f:1d:3d description: Main subnet priority: 0 media: Ethernet autoselect (1000baseT full-duplex,master,rxpause,txpause) status: active inet 10.0.0.1 netmask 0xff00 broadcast 10.0.0.255 inet6 fe80::82ee:73ff:fe9f:1d3d%re1 prefixlen 64 scopeid 0x2 inet6 2001:470:1f15:b42::1 prefixlen 64 inet6 fdfc::1 prefixlen 64 enc0: flags=0<> priority: 0 groups: enc status: active axe0: flags=8843 mtu 1500 lladdr d8:eb:97:bd:8a:77 description: VoIP subnet priority: 0 media: Ethernet autoselect (100baseTX full-duplex) status: active inet 10.0.1.1 netmask 0xff00 broadcast 10.0.1.255 tun0: flags=8043 mtu 1500 description: tinc VPN priority: 0 groups: tun status: active inet 172.17.0.2 netmask 0xff00 broadcast 172.17.0.255 tun1: flags=8051 mtu 1304 description: cjdns priority: 0 groups: tun status: active inet6 fe80::92e6:baff:fe74:e38%tun1 -> prefixlen 64 scopeid 0x7 inet6 fcac:2580:3f14:3393:f405:d913:98af:ec5f -> prefixlen 8 tun2: flags=8051 mtu 1500 description: stun priority: 0 groups: tun status: down inet 10.10.0.2 --> 10.10.0.1 netmask 0x gif0: flags=8051 mtu 1480 description: Hurricane Electric 6in4 link priority: 0 groups: gif egress tunnel: inet 82.13.64.4 -> 216.66.84.46 inet6 fe80::92e6:baff:fe74:e38%gif0 -> prefixlen 64 scopeid 0x9 inet6 2001:470:1f14:b42::2 -> 2001:470:1f14:b42::1 prefixlen 128 bridge0: flags=41 description: Dedi bridge groups: bridge priority 32768 hellotime 2 fwddelay 15 maxage 20 holdcnt 6 proto rstp re1 flags=3 port 2 ifpriority 0 ifcost 0 tap0 flags=3 port 13 ifpriority 0 ifcost 0 pflow0: flags=41 mtu 1492 priority: 0 pflow: sender: 10.0.0.1 receiver: 10.0.0.7:3001 version: 5 groups: pflow pflog0: flags=141 mtu 33144 priority: 0 groups: pflog tap0: flags=8943 mtu 1500 lladdr fe:e1:ba:d0:b8:5e priority: 0 groups: tap status: active inet 10.0.0.14 netmask 0xff00 broadcast 10.0.0.255 route show: Routing tables Internet: DestinationGatewayFlags Refs Use Mtu Prio Iface defaultcpc92320-cmbg19-2- UGS 13 36158691 - 8 re0 BASE-ADDRESS.MCAST localhost URS028680 32768 8 lo0 10.0.0/24 sunUCP410431 - 4 re1 10.0.0/24 10.0.0.14 UCP00 - 4 tap0 sun80:ee:73:9f:1d:3d UHLl 024952 - 1 re1 jupiter34:64:a9:9a:5f:1c UHLc 3 14403576 - 4 re1 callisto 04:18:d6:f0:47:cd UHLc 016453 - 4 re1 pluto-mgmt e4:8d:8c:19:38:af UHLc 010449 - 4 re1 10.0.0.14 fe:e1:ba:d0:b8:5e UHLl 0 125 - 1 tap0
Re: Moving away from softnet interrupts
On 18.4.2016. 15:31, Hrvoje Popovski wrote: > On 18.4.2016. 10:50, Martin Pieuchot wrote: >> The current goal of the Network SMP effort is to have a single CPU >> process the IP forwarding path in a process context without holding >> the KERNEL_LOCK(). To achieve this goal we're progressively moving >> code from the softnet interrupt context to the if_input_task. In >> the end we'll completely get rid of this soft-interrupt. >> >> So now would be a good time to know if moving all the code currently >> run in a soft-interrupt context to a task uncovers any bug. I'm >> happily running the diff below on amd64 and macppc, it even gives me >> a small performance boost. >> >> I'd appreciate more tests especially on exotic archs. > > Hi, > > i have tested this patch over ix interfaces on box with 12 cores > Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, 2400.39 MHz > dmesg is below results .. > > > pf=NO > ddb.console=1 > kern.pool_debug=0 > kern.maxclusters=32768 > net.inet.ip.forwarding=1 > net.inet.ip.ifq.maxlen=8192 > > while sending traffic i was shutting down physical interfaces and bridge > and box survived this ... > > routing over ix > > send receive > 400kpps 400kpps > 500kpps 500kpps > 600kpps 600kpps - after cca 5 min drops down to 490kpps > 650kpps 650kpps > 700kpps 640kpps > 800kpps 640kpps > 1.4Mpps 600kpps > 14Mpps600kpps > > > bridge over ix > > send receive > 400kpps 400kpps > 500kpps 500kpps - after cca 1min drops down to 450kpps > 600kpps 600kpps > 650kpps 640kpps > 700kpps 610kpps > 800kpps 560kpps > 1.4Mpps 370kpps > 14Mpps370kpps > routing over vlan sendreceive 400kpps 400kpps 480kpps 480kpps 500kpps 450kpps 600kpps 450kpps 800kpps 450kpps 1.4Mpps 310kpps 14Mpps 310kpps # ifconfig vlan vlan111: flags=18843mtu 1500 lladdr a0:36:9f:2e:96:a0 index 14 priority 0 vlan: 111 parent interface: ix0 vnetid: 111 parent: ix0 groups: vlan status: active inet 10.113.0.1 netmask 0x broadcast 10.113.255.255 vlan112: flags=18843 mtu 1500 lladdr a0:36:9f:2e:96:a1 index 15 priority 0 vlan: 112 parent interface: ix1 vnetid: 112 parent: ix1 groups: vlan status: active inet 10.114.0.1 netmask 0x broadcast 10.114.255.255
Re: Moving away from softnet interrupts
On 18.4.2016. 10:50, Martin Pieuchot wrote: > The current goal of the Network SMP effort is to have a single CPU > process the IP forwarding path in a process context without holding > the KERNEL_LOCK(). To achieve this goal we're progressively moving > code from the softnet interrupt context to the if_input_task. In > the end we'll completely get rid of this soft-interrupt. > > So now would be a good time to know if moving all the code currently > run in a soft-interrupt context to a task uncovers any bug. I'm > happily running the diff below on amd64 and macppc, it even gives me > a small performance boost. > > I'd appreciate more tests especially on exotic archs. Hi, i have tested this patch over ix interfaces on box with 12 cores Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, 2400.39 MHz dmesg is below results .. pf=NO ddb.console=1 kern.pool_debug=0 kern.maxclusters=32768 net.inet.ip.forwarding=1 net.inet.ip.ifq.maxlen=8192 while sending traffic i was shutting down physical interfaces and bridge and box survived this ... routing over ix sendreceive 400kpps 400kpps 500kpps 500kpps 600kpps 600kpps - after cca 5 min drops down to 490kpps 650kpps 650kpps 700kpps 640kpps 800kpps 640kpps 1.4Mpps 600kpps 14Mpps 600kpps bridge over ix sendreceive 400kpps 400kpps 500kpps 500kpps - after cca 1min drops down to 450kpps 600kpps 600kpps 650kpps 640kpps 700kpps 610kpps 800kpps 560kpps 1.4Mpps 370kpps 14Mpps 370kpps # ifconfig ix ix0: flags=18b43mtu 1500 lladdr a0:36:9f:2e:96:a0 description: connected to test1.srce.hr (p2p1) index 3 priority 0 media: Ethernet autoselect (10GSFP+Cu full-duplex) status: active ix1: flags=18b43 mtu 1500 lladdr a0:36:9f:2e:96:a1 index 4 priority 0 media: Ethernet autoselect (10GSFP+Cu full-duplex) status: active # ifconfig bridge0 bridge0: flags=41 index 14 groups: bridge priority 32768 hellotime 2 fwddelay 15 maxage 20 holdcnt 6 proto rstp designated: id 00:00:00:00:00:00 priority 0 ix0 flags=3 port 3 ifpriority 0 ifcost 0 ix1 flags=3 port 4 ifpriority 0 ifcost 0 Addresses (max cache: 100, timeout: 240): 90:e2:ba:33:af:ed ix1 1 flags=0<> 90:e2:ba:33:af:ec ix0 1 flags=0<> OpenBSD 5.9-current (GENERIC.MP) #0: Mon Apr 18 11:15:43 CEST 2016 r...@x3550m4.my.domain:/usr/src/sys/arch/amd64/compile/GENERIC.MP RTC BIOS diagnostic error 80 real mem = 34315018240 (32725MB) avail mem = 33270788096 (31729MB) mpath0 at root scsibus0 at mpath0: 256 targets mainbus0 at root bios0 at mainbus0: SMBIOS rev. 2.7 @ 0x7e67c000 (84 entries) bios0: vendor IBM version "-[D7E146CUS-1.82]-" date 04/09/2015 bios0: IBM IBM System x3550 M4 Server -[7914T91]- acpi0 at bios0: rev 2 acpi0: sleep states S0 S5 acpi0: tables DSDT FACP TCPA ERST HEST HPET APIC MCFG OEM0 OEM1 SLIT SRAT SLIC SSDT SSDT SSDT SSDT SSDT SSDT DMAR acpi0: wakeup devices MRP1(S4) DCC0(S4) MRP3(S4) MRP5(S4) EHC2(S5) PEX0(S5) PEX7(S5) EHC1(S5) IP2P(S3) MRPB(S4) MRPC(S4) MRPD(S4) MRPF(S4) MRPG(S4) MRPH(S4) MRPI(S4) [...] acpitimer0 at acpi0: 3579545 Hz, 24 bits acpihpet0 at acpi0: 14318179 Hz acpimadt0 at acpi0 addr 0xfee0: PC-AT compat cpu0 at mainbus0: apid 0 (boot processor) cpu0: Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, 2400.35 MHz cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,DCA,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,LONG,LAHF,PERF,ITSC,FSGSBASE,SMEP,ERMS,SENSOR,ARAT cpu0: 256KB 64b/line 8-way L2 cache cpu0: smt 0, core 0, package 0 mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges cpu0: apic clock running at 100MHz cpu0: mwait min=64, max=64, C-substates=0.2.1.1, IBE cpu1 at mainbus0: apid 2 (application processor) cpu1: Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, 2400.00 MHz cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,DCA,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,LONG,LAHF,PERF,ITSC,FSGSBASE,SMEP,ERMS,SENSOR,ARAT cpu1: 256KB 64b/line 8-way L2 cache cpu1: smt 0, core 1, package 0 cpu2 at mainbus0: apid 4 (application processor) cpu2: Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, 2400.00 MHz cpu2:
Re: Moving away from softnet interrupts
On 18/04/16(Mon) 11:33, Mark Kettenis wrote: > [...] > However, this diff uses the same taskq for both the "unlocked" and > "locked" parts. My experience with crypto code was that frequently > grabbing and releasing the kernel lock did affect latency in a bad > way. Some time ago dlg@ had a somewhat similar diff that had a > separate taskq for the "locked" bits. That would avoid blocking of > the "unlocked" bits when the "locked" code is grabbing the kernel > lock. Of course such an approach would probably introduce additional > context switches. Did you consider such an approach? I don't think this diff will increase the latency because currently softnet interrupts are processed right after dropping the SPL level at the end of the if_input_task loop. I also strongly believe that moving the "locked" bits to another task should be done in a separate step, if at all. The reason is that we did some of the work to make the incoming path run in parallel of the rest of the kernel, not in parallel of itself. So I'd rather wait to not expose too many bugs at once.
Re: Moving away from softnet interrupts
> Date: Mon, 18 Apr 2016 10:50:46 +0200 > From: Martin Pieuchot> > The current goal of the Network SMP effort is to have a single CPU > process the IP forwarding path in a process context without holding > the KERNEL_LOCK(). To achieve this goal we're progressively moving > code from the softnet interrupt context to the if_input_task. In > the end we'll completely get rid of this soft-interrupt. > > So now would be a good time to know if moving all the code currently > run in a soft-interrupt context to a task uncovers any bug. I'm > happily running the diff below on amd64 and macppc, it even gives me > a small performance boost. > > I'd appreciate more tests especially on exotic archs. Yes, please test this. And report back how this changes the results of your favourite benchmark. However, this diff uses the same taskq for both the "unlocked" and "locked" parts. My experience with crypto code was that frequently grabbing and releasing the kernel lock did affect latency in a bad way. Some time ago dlg@ had a somewhat similar diff that had a separate taskq for the "locked" bits. That would avoid blocking of the "unlocked" bits when the "locked" code is grabbing the kernel lock. Of course such an approach would probably introduce additional context switches. Did you consider such an approach? > Index: net/if.c > === > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.429 > diff -u -p -r1.429 if.c > --- net/if.c 16 Mar 2016 12:08:09 - 1.429 > +++ net/if.c 18 Apr 2016 08:00:08 - > @@ -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 > #include > @@ -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 @@ voidnet_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, > _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 mbu > return (0); > } > > -struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); > -struct task if_input_task = TASK_INITIALIZER(if_input_process, > _input_queue); > - > void > if_input(struct ifnet *ifp, struct mbuf_list *ml) > { > @@ -803,6 +806,50 @@ if_input_process(void *xmq) > if_put(ifp); > } > splx(s); > +} > + > +void > +if_netisr(void *unused) > +{ > + int n, t = 0; > + int s; > + > + KERNEL_LOCK(); > + s = splsoftnet(); > + > + while ((n = netisr) != 0) { > + sched_pause(); > + > + atomic_clearbits_int(, 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 > Index: net/netisr.c > === > RCS file: net/netisr.c > diff -N net/netisr.c > --- net/netisr.c 8 Jan 2016 13:53:24 - 1.10 > +++ /dev/null 1 Jan 1970 00:00:00 - > @@ -1,74 +0,0 @@ > -/* > - * Copyright (c) 2010 Owain G. Ainsworth > - * > - * 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
Moving away from softnet interrupts
The current goal of the Network SMP effort is to have a single CPU process the IP forwarding path in a process context without holding the KERNEL_LOCK(). To achieve this goal we're progressively moving code from the softnet interrupt context to the if_input_task. In the end we'll completely get rid of this soft-interrupt. So now would be a good time to know if moving all the code currently run in a soft-interrupt context to a task uncovers any bug. I'm happily running the diff below on amd64 and macppc, it even gives me a small performance boost. I'd appreciate more tests especially on exotic archs. Index: net/if.c === RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.429 diff -u -p -r1.429 if.c --- net/if.c16 Mar 2016 12:08:09 - 1.429 +++ net/if.c18 Apr 2016 08:00:08 - @@ -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 #include @@ -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 *); intnet_livelocked(void); intifq_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, _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 mbu return (0); } -struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); -struct task if_input_task = TASK_INITIALIZER(if_input_process, _input_queue); - void if_input(struct ifnet *ifp, struct mbuf_list *ml) { @@ -803,6 +806,50 @@ if_input_process(void *xmq) if_put(ifp); } splx(s); +} + +void +if_netisr(void *unused) +{ + int n, t = 0; + int s; + + KERNEL_LOCK(); + s = splsoftnet(); + + while ((n = netisr) != 0) { + sched_pause(); + + atomic_clearbits_int(, 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 Index: net/netisr.c === RCS file: net/netisr.c diff -N net/netisr.c --- net/netisr.c8 Jan 2016 13:53:24 - 1.10 +++ /dev/null 1 Jan 1970 00:00:00 - @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2010 Owain G. Ainsworth- * - * 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 -#include - -#include - -#include - -#include "ppp.h" -#include "bridge.h" -#include "pppoe.h" -#include "pfsync.h" - -voidnetintr(void *); - -int netisr; -void *netisr_intr; - -void -netintr(void *unused) -{ - int n, t = 0; - - while ((n = netisr) != 0) { - atomic_clearbits_int(, 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