From 63ee67c2726c9eaaf5e4eab0f5227a14c6354683 Mon Sep 17 00:00:00 2001 From: np Date: Tue, 5 May 2015 15:13:59 +0000 Subject: 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. --- sys/dev/cxgbe/adapter.h | 6 +++++- sys/dev/cxgbe/t4_main.c | 46 +++++++++++++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 93905e5..fc914fe 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -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 */ diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index fd82f02..ee5379c 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -386,6 +386,7 @@ static int t4_free_irq(struct adapter *, struct irq *); 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 t4_regdump *regs, uint8_t *buf) } 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); } -- cgit v1.1