aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2014-09-28 08:57:07 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2014-09-28 08:57:07 +0000
commit112f50ffb22dbaaee6e9f52587e7836f6349f9b6 (patch)
treeb339956faa188fb824c0a2cabdd5adfaf89887ad /sys/net
parent3754eb026e6a0e7bfe7cda0897f78f218d510d16 (diff)
downloadsrc-112f50ffb22dbaaee6e9f52587e7836f6349f9b6.tar.gz
src-112f50ffb22dbaaee6e9f52587e7836f6349f9b6.zip
Notes
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c89
-rw-r--r--sys/net/if_lagg.c14
-rw-r--r--sys/net/if_lagg.h2
-rw-r--r--sys/net/if_var.h23
-rw-r--r--sys/net/ifq.h13
5 files changed, 40 insertions, 101 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 831dc3f390b0..a7fb2a95feec 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -468,6 +468,10 @@ if_alloc(u_char type)
refcount_init(&ifp->if_refcount, 1); /* Index reference. */
ifnet_setbyindex(ifp->if_index, ifp);
+
+ for (int i = 0; i < IFCOUNTERS; i++)
+ ifp->if_counters[i] = counter_u64_alloc(M_WAITOK);
+
return (ifp);
}
@@ -495,6 +499,10 @@ if_free_internal(struct ifnet *ifp)
IF_AFDATA_DESTROY(ifp);
IF_ADDR_LOCK_DESTROY(ifp);
ifq_delete(&ifp->if_snd);
+
+ for (int i = 0; i < IFCOUNTERS; i++)
+ counter_u64_free(ifp->if_counters[i]);
+
free(ifp, M_IFNET);
}
@@ -1460,39 +1468,15 @@ if_rtdel(struct radix_node *rn, void *arg)
}
/*
- * Return counter values from old racy non-pcpu counters.
+ * Return counter values from counter(9)s stored in ifnet.
*/
uint64_t
if_get_counter_default(struct ifnet *ifp, ift_counter cnt)
{
- switch (cnt) {
- case IFCOUNTER_IPACKETS:
- return (ifp->if_ipackets);
- case IFCOUNTER_IERRORS:
- return (ifp->if_ierrors);
- case IFCOUNTER_OPACKETS:
- return (ifp->if_opackets);
- case IFCOUNTER_OERRORS:
- return (ifp->if_oerrors);
- case IFCOUNTER_COLLISIONS:
- return (ifp->if_collisions);
- case IFCOUNTER_IBYTES:
- return (ifp->if_ibytes);
- case IFCOUNTER_OBYTES:
- return (ifp->if_obytes);
- case IFCOUNTER_IMCASTS:
- return (ifp->if_imcasts);
- case IFCOUNTER_OMCASTS:
- return (ifp->if_omcasts);
- case IFCOUNTER_IQDROPS:
- return (ifp->if_iqdrops);
- case IFCOUNTER_OQDROPS:
- return (ifp->if_oqdrops);
- case IFCOUNTER_NOPROTO:
- return (ifp->if_noproto);
- }
- panic("%s: unknown counter %d", __func__, cnt);
+ KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
+
+ return (counter_u64_fetch(ifp->if_counters[cnt]));
}
/*
@@ -1503,46 +1487,9 @@ void
if_inc_counter(struct ifnet *ifp, ift_counter cnt, int64_t inc)
{
- switch (cnt) {
- case IFCOUNTER_IPACKETS:
- ifp->if_ipackets += inc;
- break;
- case IFCOUNTER_IERRORS:
- ifp->if_ierrors += inc;
- break;
- case IFCOUNTER_OPACKETS:
- ifp->if_opackets += inc;
- break;
- case IFCOUNTER_OERRORS:
- ifp->if_oerrors += inc;
- break;
- case IFCOUNTER_COLLISIONS:
- ifp->if_collisions += inc;
- break;
- case IFCOUNTER_IBYTES:
- ifp->if_ibytes += inc;
- break;
- case IFCOUNTER_OBYTES:
- ifp->if_obytes += inc;
- break;
- case IFCOUNTER_IMCASTS:
- ifp->if_imcasts += inc;
- break;
- case IFCOUNTER_OMCASTS:
- ifp->if_omcasts += inc;
- break;
- case IFCOUNTER_IQDROPS:
- ifp->if_iqdrops += inc;
- break;
- case IFCOUNTER_OQDROPS:
- ifp->if_oqdrops += inc;
- break;
- case IFCOUNTER_NOPROTO:
- ifp->if_noproto += inc;
- break;
- default:
- panic("%s: unknown counter %d", __func__, cnt);
- }
+ KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
+
+ counter_u64_add(ifp->if_counters[cnt], inc);
}
/*
@@ -3596,14 +3543,14 @@ if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
IF_LOCK(ifq);
if (_IF_QFULL(ifq)) {
IF_UNLOCK(ifq);
- ifp->if_oqdrops++;
+ if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
m_freem(m);
return (0);
}
if (ifp != NULL) {
- ifp->if_obytes += m->m_pkthdr.len + adjust;
+ if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len + adjust);
if (m->m_flags & (M_BCAST|M_MCAST))
- ifp->if_omcasts++;
+ if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
active = ifp->if_drv_flags & IFF_DRV_OACTIVE;
}
_IF_ENQUEUE(ifq, m);
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index d58fb3916ad7..571284b380d0 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -815,7 +815,7 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
/* Read port counters */
pval = lp->port_counters.val;
- for (i = IFCOUNTER_IPACKETS; i <= IFCOUNTER_LAST; i++, pval++)
+ for (i = 0; i < IFCOUNTERS; i++, pval++)
*pval = ifp->if_get_counter(ifp, i);
/* Add multicast addresses and interface flags to this port */
lagg_ether_cmdmulti(lp, 1);
@@ -884,9 +884,9 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport)
/* Update detached port counters */
pval = lp->port_counters.val;
- for (i = IFCOUNTER_IPACKETS; i <= IFCOUNTER_LAST; i++, pval++) {
+ for (i = 0; i <= IFCOUNTERS; i++, pval++) {
vdiff = ifp->if_get_counter(ifp, i) - *pval;
- sc->detached_counters.val[i - 1] += vdiff;
+ sc->detached_counters.val[i] += vdiff;
}
/* Finally, remove the port from the lagg */
@@ -1023,8 +1023,8 @@ lagg_get_counter(struct ifnet *ifp, ift_counter cnt)
struct rm_priotracker tracker;
uint64_t newval, oldval, vsum;
- if (cnt <= 0 || cnt > IFCOUNTER_LAST)
- return (if_get_counter_default(ifp, cnt));
+ /* Revise this when we've got non-generic counters. */
+ KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
sc = (struct lagg_softc *)ifp->if_softc;
LAGG_RLOCK(sc, &tracker);
@@ -1032,7 +1032,7 @@ lagg_get_counter(struct ifnet *ifp, ift_counter cnt)
vsum = 0;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
/* Saved attached value */
- oldval = lp->port_counters.val[cnt - 1];
+ oldval = lp->port_counters.val[cnt];
/* current value */
lpifp = lp->lp_ifp;
newval = lpifp->if_get_counter(lpifp, cnt);
@@ -1049,7 +1049,7 @@ lagg_get_counter(struct ifnet *ifp, ift_counter cnt)
/*
* Add counter data from detached ports counters
*/
- vsum += sc->detached_counters.val[cnt - 1];
+ vsum += sc->detached_counters.val[cnt];
LAGG_RUNLOCK(sc, &tracker);
diff --git a/sys/net/if_lagg.h b/sys/net/if_lagg.h
index 658d8b49e618..5aeae571da77 100644
--- a/sys/net/if_lagg.h
+++ b/sys/net/if_lagg.h
@@ -186,7 +186,7 @@ struct lagg_llq {
};
struct lagg_counters {
- uint64_t val[IFCOUNTER_LAST];
+ uint64_t val[IFCOUNTERS];
};
struct lagg_softc {
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index ebaa0f697a54..46398dd33c69 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -96,7 +96,7 @@ VNET_DECLARE(struct pfil_head, link_pfil_hook); /* packet filter hooks */
#endif /* _KERNEL */
typedef enum {
- IFCOUNTER_IPACKETS = 1,
+ IFCOUNTER_IPACKETS = 0,
IFCOUNTER_IERRORS,
IFCOUNTER_OPACKETS,
IFCOUNTER_OERRORS,
@@ -108,8 +108,8 @@ typedef enum {
IFCOUNTER_IQDROPS,
IFCOUNTER_OQDROPS,
IFCOUNTER_NOPROTO,
+ IFCOUNTERS /* Array size. */
} ift_counter;
-#define IFCOUNTER_LAST IFCOUNTER_NOPROTO
typedef struct ifnet * if_t;
@@ -228,28 +228,15 @@ struct ifnet {
(struct ifnet *, struct vnet *, char *);
if_get_counter_t if_get_counter; /* get counter values */
+ /* Statistics. */
+ counter_u64_t if_counters[IFCOUNTERS];
+
/* Stuff that's only temporary and doesn't belong here. */
u_int if_hw_tsomax; /* TSO total burst length
* limit in bytes. A value of
* zero means no limit. Have
* to find a better place for
* it eventually. */
- /*
- * Old, racy and expensive statistics, should not be used in
- * new drivers.
- */
- uint64_t if_ipackets; /* packets received on interface */
- uint64_t if_ierrors; /* input errors on interface */
- uint64_t if_opackets; /* packets sent on interface */
- uint64_t if_oerrors; /* output errors on interface */
- uint64_t if_collisions; /* collisions on csma interfaces */
- uint64_t if_ibytes; /* total number of octets received */
- uint64_t if_obytes; /* total number of octets sent */
- uint64_t if_imcasts; /* packets received via multicast */
- uint64_t if_omcasts; /* packets sent via multicast */
- uint64_t if_iqdrops; /* dropped on input */
- uint64_t if_oqdrops; /* dropped on output */
- uint64_t if_noproto; /* destined for unsupported protocol */
/* TSO fields for segment limits. If a field is zero below, there is no limit. */
u_int if_hw_tsomaxsegcount; /* TSO maximum segment count */
diff --git a/sys/net/ifq.h b/sys/net/ifq.h
index b787ea1cfa81..14ef8b25033a 100644
--- a/sys/net/ifq.h
+++ b/sys/net/ifq.h
@@ -41,7 +41,12 @@
#include <sys/lock.h> /* XXX */
#include <sys/mutex.h> /* struct ifqueue */
+/*
+ * Couple of ugly extra definitions that are required since ifq.h
+ * is splitted from if_var.h.
+ */
#define IF_DUNIT_NONE -1
+void if_inc_counter(struct ifnet *, ift_counter, int64_t inc);
#include <altq/if_altq.h>
@@ -245,13 +250,13 @@ do { \
mflags = (m)->m_flags; \
IFQ_ENQUEUE(&(ifp)->if_snd, m, err); \
if ((err) == 0) { \
- (ifp)->if_obytes += len + (adj); \
+ if_inc_counter((ifp), IFCOUNTER_OBYTES, len + (adj)); \
if (mflags & M_MCAST) \
- (ifp)->if_omcasts++; \
+ if_inc_counter((ifp), IFCOUNTER_OMCASTS, 1); \
if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0) \
if_start(ifp); \
} else \
- ifp->if_oqdrops++; \
+ if_inc_counter((ifp), IFCOUNTER_OQDROPS, 1); \
} while (0)
#define IFQ_HANDOFF(ifp, m, err) \
@@ -318,7 +323,7 @@ drbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
IFQ_ENQUEUE(&ifp->if_snd, m, error);
if (error)
- ifp->if_oqdrops++;
+ if_inc_counter((ifp), IFCOUNTER_OQDROPS, 1);
return (error);
}
#endif