Page MenuHomeFreeBSD

D781.id1689.diff
No OneTemporary

D781.id1689.diff

Index: sys/net/if_lagg.h
===================================================================
--- sys/net/if_lagg.h
+++ sys/net/if_lagg.h
@@ -136,8 +136,6 @@
#ifdef _KERNEL
-#include <sys/counter.h>
-
/*
* Internal kernel part
*/
@@ -186,10 +184,13 @@
SLIST_ENTRY(lagg_llq) llq_entries;
};
+struct lagg_counters {
+ uint64_t val[IFCOUNTER_LAST];
+};
+
struct lagg_softc {
struct ifnet *sc_ifp; /* virtual interface */
struct rmlock sc_mtx;
- struct mtx sc_call_mtx;
int sc_proto; /* lagg protocol */
u_int sc_count; /* number of ports */
u_int sc_active; /* active port count */
@@ -201,11 +202,6 @@
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;
@@ -233,6 +229,8 @@
struct sysctl_oid *sc_oid; /* sysctl tree oid */
int use_flowid; /* use M_FLOWID */
int flowid_shift; /* shift the flowid */
+ struct lagg_counters proto_counters; /* ifp counters copy */
+ struct lagg_counters agg_counters; /* summary counters */
};
struct lagg_port {
@@ -254,6 +252,7 @@
int (*lp_ioctl)(struct ifnet *, u_long, caddr_t);
int (*lp_output)(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *);
+ struct lagg_counters port_counters; /* ifp counters copy */
SLIST_ENTRY(lagg_port) lp_entries;
};
@@ -267,11 +266,6 @@
#define LAGG_RLOCK_ASSERT(_sc) rm_assert(&(_sc)->sc_mtx, RA_RLOCKED)
#define LAGG_WLOCK_ASSERT(_sc) rm_assert(&(_sc)->sc_mtx, RA_WLOCKED)
-#define LAGG_CALLOUT_LOCK_INIT(_sc) \
- mtx_init(&(_sc)->sc_call_mtx, "if_lagg callout mutex", NULL,\
- MTX_DEF)
-#define LAGG_CALLOUT_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_call_mtx)
-
extern struct mbuf *(*lagg_input_p)(struct ifnet *, struct mbuf *);
extern void (*lagg_linkstate_p)(struct ifnet *, int );
Index: sys/net/if_lagg.c
===================================================================
--- sys/net/if_lagg.c
+++ sys/net/if_lagg.c
@@ -114,6 +114,7 @@
static int lagg_setflag(struct lagg_port *, int, int,
int (*func)(struct ifnet *, int));
static int lagg_setflags(struct lagg_port *, int status);
+static uint64_t lagg_get_counter(struct ifnet *ifp, ifnet_counter cnt);
static int lagg_transmit(struct ifnet *, struct mbuf *);
static void lagg_qflush(struct ifnet *);
static int lagg_media_change(struct ifnet *);
@@ -155,8 +156,6 @@
struct mbuf *);
static void lagg_lacp_lladdr(struct lagg_softc *);
-static void lagg_callout(void *);
-
/* lagg protocol table */
static const struct {
int ti_proto;
@@ -287,11 +286,6 @@
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;
@@ -331,16 +325,9 @@
}
}
LAGG_LOCK_INIT(sc);
- LAGG_CALLOUT_LOCK_INIT(sc);
SLIST_INIT(&sc->sc_ports);
TASK_INIT(&sc->sc_lladdr_task, 0, lagg_port_setlladdr, sc);
- /*
- * This uses the callout lock rather than the rmlock; one can't
- * hold said rmlock during SWI.
- */
- callout_init_mtx(&sc->sc_callout, &sc->sc_call_mtx, 0);
-
/* Initialise pseudo media types */
ifmedia_init(&sc->sc_media, 0, lagg_media_change,
lagg_media_status);
@@ -353,6 +340,7 @@
ifp->if_qflush = lagg_qflush;
ifp->if_init = lagg_init;
ifp->if_ioctl = lagg_ioctl;
+ ifp->if_get_counter = lagg_get_counter;
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
ifp->if_capenable = ifp->if_capabilities = IFCAP_HWSTATS;
@@ -372,8 +360,6 @@
SLIST_INSERT_HEAD(&lagg_list, sc, sc_entries);
mtx_unlock(&lagg_list_mtx);
- callout_reset(&sc->sc_callout, hz, lagg_callout, sc);
-
return (0);
}
@@ -405,22 +391,12 @@
ether_ifdetach(ifp);
if_free(ifp);
- /* This grabs sc_callout_mtx, serialising it correctly */
- callout_drain(&sc->sc_callout);
-
- /* At this point it's drained; we can free this */
- 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);
taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task);
LAGG_LOCK_DESTROY(sc);
- LAGG_CALLOUT_LOCK_DESTROY(sc);
free(sc, M_DEVBUF);
}
@@ -563,6 +539,8 @@
{
struct lagg_softc *sc_ptr;
struct lagg_port *lp;
+ uint64_t *pval;
+ int i;
int error = 0;
LAGG_WLOCK_ASSERT(sc);
@@ -677,6 +655,10 @@
lagg_capabilities(sc);
lagg_linkstate(sc);
+ /* Read port counters */
+ pval = lp->port_counters.val;
+ for (i = IFCOUNTER_IPACKETS; i <= IFCOUNTER_NOPROTO; i++, pval++)
+ *pval = ifp->if_get_counter(ifp, i);
/* Add multicast addresses and interface flags to this port */
lagg_ether_cmdmulti(lp, 1);
lagg_setflags(lp, 1);
@@ -854,6 +836,57 @@
return (EINVAL);
}
+static uint64_t
+lagg_get_counter(struct ifnet *ifp, ifnet_counter cnt)
+{
+ struct lagg_softc *sc;
+ struct lagg_port *lp;
+ struct ifnet *lpifp;
+ struct rm_priotracker tracker;
+ uint64_t newval, *pval, vdiff, vsum;
+ off_t off;
+
+ if (cnt <= 0 || cnt > IFCOUNTER_LAST)
+ return (if_get_counter_compat(ifp, cnt));
+ off = cnt - 1;
+
+ sc = (struct lagg_softc *)ifp->if_softc;
+ LAGG_RLOCK(sc, &tracker);
+
+ vsum = 0;
+ SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
+ /* Saved old value */
+ pval = &lp->port_counters.val[off];
+ /* New value */
+ lpifp = lp->lp_ifp;
+ newval = lpifp->if_get_counter(lpifp, cnt);
+ /* Calculate diff and save new */
+ vdiff = newval - *pval;
+ *pval = newval;
+ vsum += vdiff;
+ }
+
+ /*
+ * Add counter data which might be added by upper
+ * layer protocols operating on logical interface.
+ */
+ pval = &sc->proto_counters.val[off];
+ /* Read new value via "legacy" interface */
+ newval = if_get_counter_compat(ifp, cnt);
+ vdiff = newval - *pval;
+ *pval = newval;
+ vsum += vdiff;
+
+ /* Update aggregate value */
+ pval = &sc->agg_counters.val[off];
+ *pval += vsum;
+ vsum = *pval;
+
+ LAGG_RUNLOCK(sc, &tracker);
+
+ return (vsum);
+}
+
/*
* For direct output to child ports.
*/
@@ -1332,11 +1365,7 @@
error = (*sc->sc_start)(sc, m);
LAGG_RUNLOCK(sc, &tracker);
- if (error == 0) {
- counter_u64_add(sc->sc_opackets, 1);
- counter_u64_add(sc->sc_obytes, len);
- ifp->if_omcasts += mcast;
- } else
+ if (error != 0)
ifp->if_oerrors++;
return (error);
@@ -1372,9 +1401,6 @@
m = (*sc->sc_input)(sc, lp, m);
if (m != NULL) {
- 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);
m = NULL;
@@ -2006,16 +2032,3 @@
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: sys/net/if_var.h
===================================================================
--- sys/net/if_var.h
+++ sys/net/if_var.h
@@ -109,6 +109,7 @@
IFCOUNTER_OQDROPS,
IFCOUNTER_NOPROTO,
} ifnet_counter;
+#define IFCOUNTER_LAST IFCOUNTER_NOPROTO
typedef struct ifnet * if_t;

File Metadata

Mime Type
text/plain
Expires
Sun, Jun 14, 12:07 PM (6 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33951259
Default Alt Text
D781.id1689.diff (7 KB)

Event Timeline