Author: np
Date: Tue May  5 15:13:59 2015
New Revision: 282486
URL: https://svnweb.freebsd.org/changeset/base/282486

Log:
  Backport some parts of r272200.
  - a lock to protect indirect register access
  - put code that deals with stats in a separate cxgbe_refresh_stats.
  
  This is a direct commit to stable/10.

Modified:
  stable/10/sys/dev/cxgbe/adapter.h
  stable/10/sys/dev/cxgbe/t4_main.c

Modified: stable/10/sys/dev/cxgbe/adapter.h
==============================================================================
--- stable/10/sys/dev/cxgbe/adapter.h   Tue May  5 14:52:33 2015        
(r282485)
+++ stable/10/sys/dev/cxgbe/adapter.h   Tue May  5 15:13:59 2015        
(r282486)
@@ -263,7 +263,9 @@ struct port_info {
 
        int linkdnrc;
        struct link_config link_cfg;
-       struct port_stats stats;
+
+       struct timeval last_refreshed;
+       struct port_stats stats;
 
        eventhandler_tag vlan_c;
 
@@ -786,6 +788,8 @@ struct adapter {
        TAILQ_HEAD(, sge_fl) sfl;
        struct callout sfl_callout;
 
+       struct mtx regwin_lock; /* for indirect reads and memory windows */
+
        an_handler_t an_handler __aligned(CACHE_LINE_SIZE);
        fw_msg_handler_t fw_msg_handler[5];     /* NUM_FW6_TYPES */
        cpl_handler_t cpl_handler[0xef];        /* NUM_CPL_CMDS */

Modified: stable/10/sys/dev/cxgbe/t4_main.c
==============================================================================
--- stable/10/sys/dev/cxgbe/t4_main.c   Tue May  5 14:52:33 2015        
(r282485)
+++ stable/10/sys/dev/cxgbe/t4_main.c   Tue May  5 15:13:59 2015        
(r282486)
@@ -386,6 +386,7 @@ static int t4_free_irq(struct adapter *,
 static void reg_block_dump(struct adapter *, uint8_t *, unsigned int,
     unsigned int);
 static void t4_get_regs(struct adapter *, struct t4_regdump *, uint8_t *);
+static void cxgbe_refresh_stats(struct adapter *, struct port_info *);
 static void cxgbe_tick(void *);
 static void cxgbe_vlan_config(void *, struct ifnet *, uint16_t);
 static int cpl_not_handled(struct sge_iq *, const struct rss_header *,
@@ -611,6 +612,8 @@ t4_attach(device_t dev)
        TAILQ_INIT(&sc->sfl);
        callout_init(&sc->sfl_callout, CALLOUT_MPSAFE);
 
+       mtx_init(&sc->regwin_lock, "register and memory window", 0, MTX_DEF);
+
        rc = map_bars_0_and_4(sc);
        if (rc != 0)
                goto done; /* error message displayed already */
@@ -1011,6 +1014,8 @@ t4_detach(device_t dev)
                mtx_destroy(&sc->sfl_lock);
        if (mtx_initialized(&sc->ifp_lock))
                mtx_destroy(&sc->ifp_lock);
+       if (mtx_initialized(&sc->regwin_lock))
+               mtx_destroy(&sc->regwin_lock);
 
        bzero(sc, sizeof(*sc));
 
@@ -4243,20 +4248,19 @@ t4_get_regs(struct adapter *sc, struct t
 }
 
 static void
-cxgbe_tick(void *arg)
+cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi)
 {
-       struct port_info *pi = arg;
-       struct adapter *sc = pi->adapter;
        struct ifnet *ifp = pi->ifp;
        struct sge_txq *txq;
        int i, drops;
        struct port_stats *s = &pi->stats;
+       struct timeval tv;
+       const struct timeval interval = {0, 250000};    /* 250ms */
 
-       PORT_LOCK(pi);
-       if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-               PORT_UNLOCK(pi);
-               return; /* without scheduling another callout */
-       }
+       getmicrotime(&tv);
+       timevalsub(&tv, &interval);
+       if (timevalcmp(&tv, &pi->last_refreshed, <))
+               return;
 
        t4_get_port_stats(sc, pi->tx_chan, s);
 
@@ -4269,16 +4273,14 @@ cxgbe_tick(void *arg)
        ifp->if_iqdrops = s->rx_ovflow0 + s->rx_ovflow1 + s->rx_ovflow2 +
            s->rx_ovflow3 + s->rx_trunc0 + s->rx_trunc1 + s->rx_trunc2 +
            s->rx_trunc3;
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < NCHAN; i++) {
                if (pi->rx_chan_map & (1 << i)) {
                        uint32_t v;
 
-                       /*
-                        * XXX: indirect reads from the same ADDR/DATA pair can
-                        * race with each other.
-                        */
+                       mtx_lock(&sc->regwin_lock);
                        t4_read_indirect(sc, A_TP_MIB_INDEX, A_TP_MIB_DATA, &v,
                            1, A_TP_MIB_TNL_CNG_DROP_0 + i);
+                       mtx_unlock(&sc->regwin_lock);
                        ifp->if_iqdrops += v;
                }
        }
@@ -4292,6 +4294,24 @@ cxgbe_tick(void *arg)
        ifp->if_ierrors = s->rx_jabber + s->rx_runt + s->rx_too_long +
            s->rx_fcs_err + s->rx_len_err;
 
+       getmicrotime(&pi->last_refreshed);
+}
+
+static void
+cxgbe_tick(void *arg)
+{
+       struct port_info *pi = arg;
+       struct adapter *sc = pi->adapter;
+       struct ifnet *ifp = pi->ifp;
+
+       PORT_LOCK(pi);
+       if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+               PORT_UNLOCK(pi);
+               return; /* without scheduling another callout */
+       }
+
+       cxgbe_refresh_stats(sc, pi);
+
        callout_schedule(&pi->tick, hz);
        PORT_UNLOCK(pi);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to