From 0bf97ae271ef54efd04d20668ed657d3b380c6d0 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 22 Feb 2012 22:01:30 +0000 Subject: [PATCH] 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 Submitted by: Eugene Grosbein MFC after: 1 week --- sys/net/ieee8023ad_lacp.c | 2 +- sys/net/if_lagg.c | 14 +++++++++++++- sys/net/if_lagg.h | 4 ++++ 3 files changed, 18 insertions(+), 2 deletions(-) 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 730047fa0733..488dca3e257f 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -262,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); @@ -270,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 = 1; + 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) { @@ -349,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(ifp); @@ -1676,7 +1688,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 + /* * 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 {