Author: glebius
Date: Sun Sep 28 08:57:07 2014
New Revision: 272244
URL: http://svnweb.freebsd.org/changeset/base/272244

Log:
  Finally, convert counters in struct ifnet to counter(9).
  
  Sponsored by: Netflix
  Sponsored by: Nginx, Inc.

Modified:
  head/sys/net/if.c
  head/sys/net/if_lagg.c
  head/sys/net/if_lagg.h
  head/sys/net/if_var.h
  head/sys/net/ifq.h

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c   Sun Sep 28 08:23:26 2014        (r272243)
+++ head/sys/net/if.c   Sun Sep 28 08:57:07 2014        (r272244)
@@ -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 *ar
 }
 
 /*
- * 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 m
        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);

Modified: head/sys/net/if_lagg.c
==============================================================================
--- head/sys/net/if_lagg.c      Sun Sep 28 08:23:26 2014        (r272243)
+++ head/sys/net/if_lagg.c      Sun Sep 28 08:57:07 2014        (r272244)
@@ -815,7 +815,7 @@ lagg_port_create(struct lagg_softc *sc, 
 
        /* 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, 
 
        /* 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_
        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_
        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_
        /*
         * Add counter data from detached ports counters
         */
-       vsum += sc->detached_counters.val[cnt - 1];
+       vsum += sc->detached_counters.val[cnt];
 
        LAGG_RUNLOCK(sc, &tracker);
 

Modified: head/sys/net/if_lagg.h
==============================================================================
--- head/sys/net/if_lagg.h      Sun Sep 28 08:23:26 2014        (r272243)
+++ head/sys/net/if_lagg.h      Sun Sep 28 08:57:07 2014        (r272244)
@@ -186,7 +186,7 @@ struct lagg_llq {
 };
 
 struct lagg_counters {
-       uint64_t        val[IFCOUNTER_LAST];
+       uint64_t        val[IFCOUNTERS];
 };
 
 struct lagg_softc {

Modified: head/sys/net/if_var.h
==============================================================================
--- head/sys/net/if_var.h       Sun Sep 28 08:23:26 2014        (r272243)
+++ head/sys/net/if_var.h       Sun Sep 28 08:57:07 2014        (r272244)
@@ -96,7 +96,7 @@ VNET_DECLARE(struct pfil_head, link_pfil
 #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 */

Modified: head/sys/net/ifq.h
==============================================================================
--- head/sys/net/ifq.h  Sun Sep 28 08:23:26 2014        (r272243)
+++ head/sys/net/ifq.h  Sun Sep 28 08:57:07 2014        (r272244)
@@ -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 b
        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
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to