aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Thompson <thompsa@FreeBSD.org>2012-02-29 20:22:45 +0000
committerAndrew Thompson <thompsa@FreeBSD.org>2012-02-29 20:22:45 +0000
commit3d6e82d782e78e9def5b91a8bcf2b6ece79e4c7e (patch)
tree88bcb7fd1f115bbc657157026bbea4c74d571164
parent9742429eb0498c120a916f1b10e2c9b3d46a49ab (diff)
downloadsrc-3d6e82d782e78e9def5b91a8bcf2b6ece79e4c7e.tar.gz
src-3d6e82d782e78e9def5b91a8bcf2b6ece79e4c7e.zip
MFC r232008,232010,232080,232089
Using the flowid in the mbuf assumes the network card is giving a good hash for the traffic flow, this may not be the case giving poor traffic distribution. Add a sysctl which allows us to fall back to our own flow hash code. PR: kern/164901 Approved by: re (bz)
Notes
Notes: svn path=/stable/8/; revision=232314
-rw-r--r--share/man/man4/lagg.417
-rw-r--r--sys/net/ieee8023ad_lacp.c2
-rw-r--r--sys/net/if_lagg.c19
-rw-r--r--sys/net/if_lagg.h4
4 files changed, 39 insertions, 3 deletions
diff --git a/share/man/man4/lagg.4 b/share/man/man4/lagg.4
index 1dd514219e54..c49534ba1fab 100644
--- a/share/man/man4/lagg.4
+++ b/share/man/man4/lagg.4
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 18, 2010
+.Dd February 23, 2012
.Dt LAGG 4
.Os
.Sh NAME
@@ -133,6 +133,21 @@ variable in
.Pp
The MTU of the first interface to be added is used as the lagg MTU.
All additional interfaces are required to have exactly the same value.
+.Pp
+The
+.Ic loadbalance
+and
+.Ic lacp
+modes will use the RSS hash from the network card if available to avoid
+computing one, this may give poor traffic distribution if the hash is invalid
+or uses less of the protocol header information.
+Local hash computation can be forced per interface by setting the
+.Va net.link.lagg.X.use_flowid
+.Xr sysctl 8
+variable to zero where X is the interface number.
+The default for new interfaces is set via the
+.Va net.link.lagg.default_use_flowid
+.Xr sysctl 8 .
.Sh EXAMPLES
Create a 802.3ad link aggregation using LACP with two
.Xr bge 4
diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c
index 2284ce2486e6..ea838669e863 100644
--- a/sys/net/ieee8023ad_lacp.c
+++ b/sys/net/ieee8023ad_lacp.c
@@ -812,7 +812,7 @@ lacp_select_tx_port(struct lagg_softc *sc, struct mbuf *m)
return (NULL);
}
- if (m->m_flags & M_FLOWID)
+ if (sc->use_flowid && (m->m_flags & M_FLOWID))
hash = m->m_pkthdr.flowid;
else
hash = lagg_hashmbuf(m, lsc->lsc_hashkey);
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index 7e73992bb9dc..436c8c423063 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -167,6 +167,11 @@ static int lagg_failover_rx_all = 0; /* Allow input on any failover links */
SYSCTL_INT(_net_link_lagg, OID_AUTO, failover_rx_all, CTLFLAG_RW,
&lagg_failover_rx_all, 0,
"Accept input from any interface in a failover lagg");
+static int def_use_flowid = 1; /* Default value for using M_FLOWID */
+TUNABLE_INT("net.link.lagg.default_use_flowid", &def_use_flowid);
+SYSCTL_INT(_net_link_lagg, OID_AUTO, default_use_flowid, CTLFLAG_RW,
+ &def_use_flowid, 0,
+ "Default setting for using flow id for load sharing");
static int
lagg_modevent(module_t mod, int type, void *data)
@@ -257,6 +262,8 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
struct ifnet *ifp;
int i, error = 0;
static const u_char eaddr[6]; /* 00:00:00:00:00:00 */
+ struct sysctl_oid *oid;
+ char num[14]; /* sufficient for 32 bits */
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
@@ -265,6 +272,15 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
return (ENOSPC);
}
+ sysctl_ctx_init(&sc->ctx);
+ snprintf(num, sizeof(num), "%u", unit);
+ sc->use_flowid = def_use_flowid;
+ oid = SYSCTL_ADD_NODE(&sc->ctx, &SYSCTL_NODE_CHILDREN(_net_link, lagg),
+ OID_AUTO, num, CTLFLAG_RD, NULL, "");
+ SYSCTL_ADD_INT(&sc->ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "use_flowid", CTLTYPE_INT|CTLFLAG_RW, &sc->use_flowid, sc->use_flowid,
+ "Use flow id for load sharing");
+
sc->sc_proto = LAGG_PROTO_NONE;
for (i = 0; lagg_protos[i].ti_proto != LAGG_PROTO_NONE; i++) {
if (lagg_protos[i].ti_proto == LAGG_PROTO_DEFAULT) {
@@ -344,6 +360,7 @@ lagg_clone_destroy(struct ifnet *ifp)
LAGG_WUNLOCK(sc);
+ sysctl_ctx_free(&sc->ctx);
ifmedia_removeall(&sc->sc_media);
ether_ifdetach(ifp);
if_free_type(ifp, IFT_ETHER);
@@ -1668,7 +1685,7 @@ lagg_lb_start(struct lagg_softc *sc, struct mbuf *m)
struct lagg_port *lp = NULL;
uint32_t p = 0;
- if (m->m_flags & M_FLOWID)
+ if (sc->use_flowid && (m->m_flags & M_FLOWID))
p = m->m_pkthdr.flowid;
else
p = lagg_hashmbuf(m, lb->lb_key);
diff --git a/sys/net/if_lagg.h b/sys/net/if_lagg.h
index 0034c61799b1..823176449645 100644
--- a/sys/net/if_lagg.h
+++ b/sys/net/if_lagg.h
@@ -21,6 +21,8 @@
#ifndef _NET_LAGG_H
#define _NET_LAGG_H
+#include <sys/sysctl.h>
+
/*
* Global definitions
*/
@@ -202,6 +204,8 @@ struct lagg_softc {
eventhandler_tag vlan_attach;
eventhandler_tag vlan_detach;
#endif
+ struct sysctl_ctx_list ctx; /* sysctl variables */
+ int use_flowid; /* use M_FLOWID */
};
struct lagg_port {