Switch lagg(4) statistics to counter(9).
The lagg(4) is often used to bond high speed links, so basic per-packet += on statistics cause cache misses and statistics loss. Perfect solution would be to convert ifnet(9) to counters(9), but this requires much more work, and unfortunately ABI change, so temporarily patch lagg(4) manually. We store counters in the softc, and once per second push their values to legacy ifnet counters. Sponsored by: Nginx, Inc.
This commit is contained in:
parent
aa76317cfc
commit
b64478a137
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=249506
@ -153,6 +153,8 @@ static struct mbuf *lagg_lacp_input(struct lagg_softc *, struct lagg_port *,
|
||||
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, caddr_t params)
|
||||
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, caddr_t params)
|
||||
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, caddr_t params)
|
||||
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_port *lp, struct mbuf *m)
|
||||
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);
|
||||
}
|
||||
|
@ -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 */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user