svn commit: r325487 - head/sys/net
Stephen Hurd
shurd at FreeBSD.org
Mon Nov 6 16:23:22 UTC 2017
Author: shurd
Date: Mon Nov 6 16:23:21 2017
New Revision: 325487
URL: https://svnweb.freebsd.org/changeset/base/325487
Log:
Only chain non-LRO mbufs when LRO is not possible
Preserve packet order between tcp_lro_rx() and if_input() to avoid
creating extra corner cases. If no packets can be LROed, combine them
into one chain for submission via if_input(). If any packet can
potentially be LROed however, retain old behaviour and call if_input()
for each packet.
This should keep the 12% improvement for small packet forwarding intact,
but mostly avoids impacting the LRO case.
Reviewed by: cem, sbruno
Approved by: sbruno (mentor)
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D12876
Modified:
head/sys/net/iflib.c
Modified: head/sys/net/iflib.c
==============================================================================
--- head/sys/net/iflib.c Mon Nov 6 15:29:33 2017 (r325486)
+++ head/sys/net/iflib.c Mon Nov 6 16:23:21 2017 (r325487)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h>
#include <net/ethernet.h>
#include <net/mp_ring.h>
+#include <net/vnet.h>
#include <netinet/in.h>
#include <netinet/in_pcb.h>
@@ -68,6 +69,8 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
+#include <netinet/ip_var.h>
+#include <netinet6/ip6_var.h>
#include <machine/bus.h>
#include <machine/in_cksum.h>
@@ -2463,7 +2466,48 @@ iflib_rxd_pkt_get(iflib_rxq_t rxq, if_rxd_info_t ri)
return (m);
}
+#if defined(INET6) || defined(INET)
+/*
+ * Returns true if it's possible this packet could be LROed.
+ * if it returns false, it is guaranteed that tcp_lro_rx()
+ * would not return zero.
+ */
static bool
+iflib_check_lro_possible(struct lro_ctrl *lc, struct mbuf *m)
+{
+ struct ether_header *eh;
+ uint16_t eh_type;
+
+ eh = mtod(m, struct ether_header *);
+ eh_type = ntohs(eh->ether_type);
+ switch (eh_type) {
+ case ETHERTYPE_IPV6:
+ {
+ CURVNET_SET(lc->ifp->if_vnet);
+ if (VNET(ip6_forwarding) == 0) {
+ CURVNET_RESTORE();
+ return true;
+ }
+ CURVNET_RESTORE();
+ break;
+ }
+ case ETHERTYPE_IP:
+ {
+ CURVNET_SET(lc->ifp->if_vnet);
+ if (VNET(ipforwarding) == 0) {
+ CURVNET_RESTORE();
+ return true;
+ }
+ CURVNET_RESTORE();
+ break;
+ }
+ }
+
+ return false;
+}
+#endif
+
+static bool
iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
{
if_ctx_t ctx = rxq->ifr_ctx;
@@ -2476,6 +2520,7 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
iflib_fl_t fl;
struct ifnet *ifp;
int lro_enabled;
+ bool lro_possible = false;
/*
* XXX early demux data packets so that if_input processing only handles
@@ -2555,8 +2600,6 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
mt = mf = NULL;
while (mh != NULL) {
m = mh;
- if (mf == NULL)
- mf = m;
mh = mh->m_nextpkt;
m->m_nextpkt = NULL;
#ifndef __NO_STRICT_ALIGNMENT
@@ -2566,12 +2609,27 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
rx_bytes += m->m_pkthdr.len;
rx_pkts++;
#if defined(INET6) || defined(INET)
- if (lro_enabled && tcp_lro_rx(&rxq->ifr_lc, m, 0) == 0) {
- if (mf == m)
- mf = NULL;
- continue;
+ if (lro_enabled) {
+ if (!lro_possible) {
+ lro_possible = iflib_check_lro_possible(&rxq->ifr_lc, m);
+ if (lro_possible && mf != NULL) {
+ ifp->if_input(ifp, mf);
+ DBG_COUNTER_INC(rx_if_input);
+ mt = mf = NULL;
+ }
+ }
+ if (lro_possible && tcp_lro_rx(&rxq->ifr_lc, m, 0) == 0)
+ continue;
}
#endif
+ if (lro_possible) {
+ ifp->if_input(ifp, m);
+ DBG_COUNTER_INC(rx_if_input);
+ continue;
+ }
+
+ if (mf == NULL)
+ mf = m;
if (mt != NULL)
mt->m_nextpkt = m;
mt = m;
More information about the svn-src-all
mailing list