summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2019-08-06 22:57:56 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2019-08-06 22:57:56 +0000
commitaad45c0f10ec64419d3151b47b7af09a8315095d (patch)
treea66ab93987b7884ee5a3a25cadca0628f4c2dd15 /sys
parent98ed4dd55b3d196f66ea58c1f27e38d6b47526a9 (diff)
When we needed the kernel lock for local IP packet delivery, mpi@
introduced a queue to grab the lock for multiple packets. Now we have only netlock for both IP and protocol input. So the queue is not necessary anymore. It just switches CPU and decreases performance. So remove the inet and inet6 ip queue for local packets. To get TCP running on loopback, we have to queue once between TCP input and output of the two sockets. So use the loopback queue in looutput() unconditionally. OK visa@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c8
-rw-r--r--sys/net/if_loop.c10
-rw-r--r--sys/net/netisr.h4
-rw-r--r--sys/netinet/ip_input.c47
-rw-r--r--sys/netinet6/ip6_input.c47
5 files changed, 13 insertions, 103 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index d97506bc0ef..053fef352ff 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.586 2019/06/30 23:02:28 dlg Exp $ */
+/* $OpenBSD: if.c,v 1.587 2019/08/06 22:57:54 bluhm Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -997,12 +997,6 @@ if_netisr(void *unused)
KERNEL_UNLOCK();
}
#endif
- if (n & (1 << NETISR_IP))
- ipintr();
-#ifdef INET6
- if (n & (1 << NETISR_IPV6))
- ip6intr();
-#endif
#if NPPP > 0
if (n & (1 << NETISR_PPP)) {
KERNEL_LOCK();
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 7d8c06cf04e..1295387fe9c 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_loop.c,v 1.88 2018/09/09 10:11:41 henning Exp $ */
+/* $OpenBSD: if_loop.c,v 1.89 2019/08/06 22:57:54 bluhm Exp $ */
/* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $ */
/*
@@ -252,10 +252,10 @@ looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
}
- /* Use the quick path only once to avoid stack overflow. */
- if ((m->m_flags & M_LOOP) == 0)
- return (if_input_local(ifp, m, dst->sa_family));
-
+ /*
+ * Do not call if_input_local() directly. Queue the packet to avoid
+ * stack overflow and make TCP handshake over loopback work.
+ */
return (if_output_local(ifp, m, dst->sa_family));
}
diff --git a/sys/net/netisr.h b/sys/net/netisr.h
index 60c02e99f88..f5746af9243 100644
--- a/sys/net/netisr.h
+++ b/sys/net/netisr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: netisr.h,v 1.50 2017/10/31 22:05:12 sashan Exp $ */
+/* $OpenBSD: netisr.h,v 1.51 2019/08/06 22:57:54 bluhm Exp $ */
/* $NetBSD: netisr.h,v 1.12 1995/08/12 23:59:24 mycroft Exp $ */
/*
@@ -63,8 +63,6 @@ extern int netisr; /* scheduling bits for network */
extern struct task if_input_task_locked;
void arpintr(void);
-void ipintr(void);
-void ip6intr(void);
void pppintr(void);
void bridgeintr(void);
void pppoeintr(void);
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index d4d4c5b72cd..4aa2f13e566 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.343 2019/06/10 23:48:21 dlg Exp $ */
+/* $OpenBSD: ip_input.c,v 1.344 2019/08/06 22:57:54 bluhm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -109,8 +109,6 @@ int ip_frags = 0;
int *ipctl_vars[IPCTL_MAXID] = IPCTL_VARS;
-struct niqueue ipintrq = NIQUEUE_INITIALIZER(IPQ_MAXLEN, NETISR_IP);
-
struct pool ipqent_pool;
struct pool ipq_pool;
@@ -123,7 +121,6 @@ static struct mbuf_queue ipsend_mq;
extern struct niqueue arpinq;
int ip_ours(struct mbuf **, int *, int, int);
-int ip_local(struct mbuf **, int *, int, int);
int ip_dooptions(struct mbuf *, struct ifnet *);
int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **);
@@ -205,43 +202,6 @@ ip_init(void)
}
/*
- * Enqueue packet for local delivery. Queuing is used as a boundary
- * between the network layer (input/forward path) running without
- * KERNEL_LOCK() and the transport layer still needing it.
- */
-int
-ip_ours(struct mbuf **mp, int *offp, int nxt, int af)
-{
- /* We are already in a IPv4/IPv6 local deliver loop. */
- if (af != AF_UNSPEC)
- return ip_local(mp, offp, nxt, af);
-
- niq_enqueue(&ipintrq, *mp);
- *mp = NULL;
- return IPPROTO_DONE;
-}
-
-/*
- * Dequeue and process locally delivered packets.
- */
-void
-ipintr(void)
-{
- struct mbuf *m;
- int off, nxt;
-
- while ((m = niq_dequeue(&ipintrq)) != NULL) {
-#ifdef DIAGNOSTIC
- if ((m->m_flags & M_PKTHDR) == 0)
- panic("ipintr no HDR");
-#endif
- off = 0;
- nxt = ip_local(&m, &off, IPPROTO_IPV4, AF_UNSPEC);
- KASSERT(nxt == IPPROTO_DONE);
- }
-}
-
-/*
* IPv4 input routine.
*
* Checksum and byte swap header. Process options. Forward or deliver.
@@ -497,7 +457,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
* If fragmented try to reassemble. Pass to next level.
*/
int
-ip_local(struct mbuf **mp, int *offp, int nxt, int af)
+ip_ours(struct mbuf **mp, int *offp, int nxt, int af)
{
struct mbuf *m = *mp;
struct ip *ip = mtod(m, struct ip *);
@@ -1640,8 +1600,7 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
newlen));
#endif
case IPCTL_IFQUEUE:
- return (sysctl_niq(name + 1, namelen - 1,
- oldp, oldlenp, newp, newlen, &ipintrq));
+ return (EOPNOTSUPP);
case IPCTL_ARPQUEUE:
return (sysctl_niq(name + 1, namelen - 1,
oldp, oldlenp, newp, newlen, &arpinq));
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index d9c4b356a73..d57c71ab719 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.217 2019/06/10 23:48:22 dlg Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.218 2019/08/06 22:57:55 bluhm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -115,14 +115,11 @@
#include <netinet/ip_carp.h>
#endif
-struct niqueue ip6intrq = NIQUEUE_INITIALIZER(IPQ_MAXLEN, NETISR_IPV6);
-
struct cpumem *ip6counters;
uint8_t ip6_soiikey[IP6_SOIIKEY_LEN];
int ip6_ours(struct mbuf **, int *, int, int);
-int ip6_local(struct mbuf **, int *, int, int);
int ip6_check_rh0hdr(struct mbuf *, int *);
int ip6_hbhchcheck(struct mbuf *, int *, int *, int *);
int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
@@ -165,43 +162,6 @@ ip6_init(void)
ip6counters = counters_alloc(ip6s_ncounters);
}
-/*
- * Enqueue packet for local delivery. Queuing is used as a boundary
- * between the network layer (input/forward path) running without
- * KERNEL_LOCK() and the transport layer still needing it.
- */
-int
-ip6_ours(struct mbuf **mp, int *offp, int nxt, int af)
-{
- /* We are already in a IPv4/IPv6 local deliver loop. */
- if (af != AF_UNSPEC)
- return ip6_local(mp, offp, nxt, af);
-
- niq_enqueue(&ip6intrq, *mp);
- *mp = NULL;
- return IPPROTO_DONE;
-}
-
-/*
- * Dequeue and process locally delivered packets.
- */
-void
-ip6intr(void)
-{
- struct mbuf *m;
- int off, nxt;
-
- while ((m = niq_dequeue(&ip6intrq)) != NULL) {
-#ifdef DIAGNOSTIC
- if ((m->m_flags & M_PKTHDR) == 0)
- panic("ip6intr no HDR");
-#endif
- off = 0;
- nxt = ip6_local(&m, &off, IPPROTO_IPV6, AF_UNSPEC);
- KASSERT(nxt == IPPROTO_DONE);
- }
-}
-
void
ipv6_input(struct ifnet *ifp, struct mbuf *m)
{
@@ -548,7 +508,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
}
int
-ip6_local(struct mbuf **mp, int *offp, int nxt, int af)
+ip6_ours(struct mbuf **mp, int *offp, int nxt, int af)
{
if (ip6_hbhchcheck(*mp, offp, &nxt, NULL))
return IPPROTO_DONE;
@@ -1459,8 +1419,7 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
NET_UNLOCK();
return (error);
case IPV6CTL_IFQUEUE:
- return (sysctl_niq(name + 1, namelen - 1,
- oldp, oldlenp, newp, newlen, &ip6intrq));
+ return (EOPNOTSUPP);
case IPV6CTL_SOIIKEY:
return (ip6_sysctl_soiikey(oldp, oldlenp, newp, newlen));
default: