Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144874850
D781.1776786740.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D781.1776786740.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D781: Switch if_lagg(4) to use counters from underlying interfaces instead of per-packet accounting.
Attached
Detach File
Event Timeline
Log In to Comment