Page MenuHomeFreeBSD

D781.1776786740.diff
No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None

D781.1776786740.diff

Index: sys/net/if_lagg.h
===================================================================
--- sys/net/if_lagg.h
+++ sys/net/if_lagg.h
@@ -140,8 +140,6 @@
#ifdef _KERNEL
-#include <sys/counter.h>
-
/*
* Internal kernel part
*/
@@ -187,10 +185,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 */
@@ -202,11 +203,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;
@@ -220,6 +216,7 @@
struct sysctl_oid *sc_oid; /* sysctl tree oid */
int use_flowid; /* use M_FLOWID */
int flowid_shift; /* shift the flowid */
+ struct lagg_counters detached_counters; /* detached ports sum */
};
struct lagg_port {
@@ -241,6 +238,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;
};
@@ -254,11 +252,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
@@ -115,6 +115,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, ift_counter cnt);
static int lagg_transmit(struct ifnet *, struct mbuf *);
static void lagg_qflush(struct ifnet *);
static int lagg_media_change(struct ifnet *);
@@ -158,8 +159,6 @@
struct mbuf *);
static void lagg_lacp_lladdr(struct lagg_softc *);
-static void lagg_callout(void *);
-
/* lagg protocol table */
static const struct lagg_proto {
lagg_proto pr_num;
@@ -456,11 +455,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;
@@ -490,16 +484,9 @@
lagg_proto_attach(sc, LAGG_PROTO_DEFAULT);
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);
@@ -512,6 +499,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;
@@ -531,8 +519,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);
}
@@ -561,22 +547,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);
}
@@ -712,7 +688,8 @@
{
struct lagg_softc *sc_ptr;
struct lagg_port *lp, *tlp;
- int error;
+ int error, i;
+ uint64_t *pval;
LAGG_WLOCK_ASSERT(sc);
@@ -836,6 +813,10 @@
lagg_capabilities(sc);
lagg_linkstate(sc);
+ /* Read port counters */
+ pval = lp->port_counters.val;
+ for (i = IFCOUNTER_IPACKETS; i <= IFCOUNTER_LAST; 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);
@@ -877,6 +858,8 @@
struct lagg_port *lp_ptr;
struct lagg_llq *llq;
struct ifnet *ifp = lp->lp_ifp;
+ uint64_t *pval, vdiff;
+ int i;
LAGG_WLOCK_ASSERT(sc);
@@ -899,6 +882,14 @@
ifp->if_output = lp->lp_output;
ifp->if_lagg = NULL;
+ /* Update detached port counters */
+ pval = lp->port_counters.val;
+ vdiff = 0;
+ for (i = IFCOUNTER_IPACKETS; i <= IFCOUNTER_LAST; i++, pval++) {
+ vdiff = ifp->if_get_counter(ifp, i) - *pval;
+ sc->detached_counters.val[i] += vdiff;
+ }
+
/* Finally, remove the port from the lagg */
SLIST_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entries);
sc->sc_count--;
@@ -1011,6 +1002,50 @@
return (EINVAL);
}
+static uint64_t
+lagg_get_counter(struct ifnet *ifp, ift_counter cnt)
+{
+ struct lagg_softc *sc;
+ struct lagg_port *lp;
+ struct ifnet *lpifp;
+ struct rm_priotracker tracker;
+ uint64_t newval, oldval, vsum;
+ off_t off;
+
+ if (cnt <= 0 || cnt > IFCOUNTER_LAST)
+ return (if_get_counter_default(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 attached value */
+ oldval = lp->port_counters.val[off];
+ /* current value */
+ lpifp = lp->lp_ifp;
+ newval = lpifp->if_get_counter(lpifp, cnt);
+ /* Calculate diff and save new */
+ vsum += newval - oldval;
+ }
+
+ /*
+ * Add counter data which might be added by upper
+ * layer protocols operating on logical interface.
+ */
+ vsum += if_get_counter_default(ifp, cnt);
+
+ /*
+ * Add counter data from detached ports counters
+ */
+ vsum += sc->detached_counters.val[off];
+
+ LAGG_RUNLOCK(sc, &tracker);
+
+ return (vsum);
+}
+
/*
* For direct output to child ports.
*/
@@ -1449,11 +1484,7 @@
error = lagg_proto_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);
@@ -1489,9 +1520,6 @@
m = lagg_proto_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;
@@ -2124,16 +2152,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);
-}

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 21, 3:52 PM (7 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28399539
Default Alt Text
D781.1776786740.diff (7 KB)

Event Timeline