Date: Fri, 12 Apr 2013 15:22:34 +0400 From: Gleb Smirnoff <glebius@FreeBSD.org> To: current@FreeBSD.org Subject: counter(9) for lagg(4) Message-ID: <20130412112234.GQ76816@glebius.int.ru>
next in thread | raw e-mail | index | archive | help
--5EqXjnbnoPR4rQBx
Content-Type: text/plain; charset=koi8-r
Content-Disposition: inline
Hello,
the patch removes memory contention and data loss on packets/bytes
statistics in lagg(4) driver, utilizing counter(9).
Any benchmarking reports with trunk built upon 10Gbit interfaces
would be much appreciated.
Sorry, but patch isn't tested except compiling. I don't have a
lab to build a LACP trunk.
--
Totus tuus, Glebius.
--5EqXjnbnoPR4rQBx
Content-Type: text/x-diff; charset=koi8-r
Content-Disposition: attachment; filename="lagg.counters.diff"
Index: if_lagg.c
===================================================================
--- if_lagg.c (revision 249398)
+++ if_lagg.c (working copy)
@@ -153,6 +153,8 @@ static struct mbuf *lagg_lacp_input(struct lagg_so
struct mbuf *);
static void lagg_lacp_lladdr(struct lagg_softc *);
+static void lagg_callout(void *);
+
/* lagg protocol table */
static const struct {
int ti_proto;
@@ -278,6 +280,11 @@ lagg_clone_create(struct if_clone *ifc, int unit,
return (ENOSPC);
}
+ sc->sc_ipackets = counter_u64_alloc(M_WAITOK);
+ sc->sc_opackets = counter_u64_alloc(M_WAITOK);
+ sc->sc_ibytes = counter_u64_alloc(M_WAITOK);
+ sc->sc_obytes = counter_u64_alloc(M_WAITOK);
+
sysctl_ctx_init(&sc->ctx);
snprintf(num, sizeof(num), "%u", unit);
sc->use_flowid = def_use_flowid;
@@ -307,6 +314,7 @@ lagg_clone_create(struct if_clone *ifc, int unit,
LAGG_LOCK_INIT(sc);
SLIST_INIT(&sc->sc_ports);
TASK_INIT(&sc->sc_lladdr_task, 0, lagg_port_setlladdr, sc);
+ callout_init_rw(&sc->sc_callout, &sc->sc_mtx, CALLOUT_SHAREDLOCK);
/* Initialise pseudo media types */
ifmedia_init(&sc->sc_media, 0, lagg_media_change,
@@ -338,6 +346,8 @@ lagg_clone_create(struct if_clone *ifc, int unit,
SLIST_INSERT_HEAD(&lagg_list, sc, sc_entries);
mtx_unlock(&lagg_list_mtx);
+ callout_reset(&sc->sc_callout, hz, lagg_callout, sc);
+
return (0);
}
@@ -369,6 +379,12 @@ lagg_clone_destroy(struct ifnet *ifp)
ether_ifdetach(ifp);
if_free(ifp);
+ callout_drain(&sc->sc_callout);
+ counter_u64_free(sc->sc_ipackets);
+ counter_u64_free(sc->sc_opackets);
+ counter_u64_free(sc->sc_ibytes);
+ counter_u64_free(sc->sc_obytes);
+
mtx_lock(&lagg_list_mtx);
SLIST_REMOVE(&lagg_list, sc, lagg_softc, sc_entries);
mtx_unlock(&lagg_list_mtx);
@@ -1243,9 +1259,9 @@ lagg_transmit(struct ifnet *ifp, struct mbuf *m)
LAGG_RUNLOCK(sc);
if (error == 0) {
- ifp->if_opackets++;
+ counter_u64_add(sc->sc_opackets, 1);
+ counter_u64_add(sc->sc_obytes, len);
ifp->if_omcasts += mcast;
- ifp->if_obytes += len;
} else
ifp->if_oerrors++;
@@ -1281,8 +1297,8 @@ lagg_input(struct ifnet *ifp, struct mbuf *m)
m = (*sc->sc_input)(sc, lp, m);
if (m != NULL) {
- scifp->if_ipackets++;
- scifp->if_ibytes += m->m_pkthdr.len;
+ counter_u64_add(sc->sc_ipackets, 1);
+ counter_u64_add(sc->sc_ibytes, m->m_pkthdr.len);
if (scifp->if_flags & IFF_MONITOR) {
m_freem(m);
@@ -1892,3 +1908,17 @@ lagg_lacp_input(struct lagg_softc *sc, struct lagg
m->m_pkthdr.rcvif = ifp;
return (m);
}
+
+static void
+lagg_callout(void *arg)
+{
+ struct lagg_softc *sc = (struct lagg_softc *)arg;
+ struct ifnet *ifp = sc->sc_ifp;
+
+ ifp->if_ipackets = counter_u64_fetch(sc->sc_ipackets);
+ ifp->if_opackets = counter_u64_fetch(sc->sc_opackets);
+ ifp->if_ibytes = counter_u64_fetch(sc->sc_ibytes);
+ ifp->if_obytes = counter_u64_fetch(sc->sc_obytes);
+
+ callout_reset(&sc->sc_callout, hz, lagg_callout, sc);
+}
Index: if_lagg.h
===================================================================
--- if_lagg.h (revision 249398)
+++ if_lagg.h (working copy)
@@ -21,8 +21,6 @@
#ifndef _NET_LAGG_H
#define _NET_LAGG_H
-#include <sys/sysctl.h>
-
/*
* Global definitions
*/
@@ -137,6 +135,9 @@ struct lagg_reqflags {
#define SIOCSLAGGHASH _IOW('i', 146, struct lagg_reqflags)
#ifdef _KERNEL
+
+#include <sys/counter.h>
+
/*
* Internal kernel part
*/
@@ -195,6 +196,11 @@ struct lagg_softc {
uint32_t sc_seq; /* sequence counter */
uint32_t sc_flags;
+ counter_u64_t sc_ipackets;
+ counter_u64_t sc_opackets;
+ counter_u64_t sc_ibytes;
+ counter_u64_t sc_obytes;
+
SLIST_HEAD(__tplhd, lagg_port) sc_ports; /* list of interfaces */
SLIST_ENTRY(lagg_softc) sc_entries;
@@ -217,6 +223,7 @@ struct lagg_softc {
void (*sc_portreq)(struct lagg_port *, caddr_t);
eventhandler_tag vlan_attach;
eventhandler_tag vlan_detach;
+ struct callout sc_callout;
struct sysctl_ctx_list ctx; /* sysctl variables */
int use_flowid; /* use M_FLOWID */
};
--5EqXjnbnoPR4rQBx--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130412112234.GQ76816>
