Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 May 2015 15:14:00 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r282486 - stable/10/sys/dev/cxgbe
Message-ID:  <201505051514.t45FE0cD037452@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505051514.t45FE0cD037452>