Index: sys/dev/cxgbe/adapter.h =================================================================== --- sys/dev/cxgbe/adapter.h +++ sys/dev/cxgbe/adapter.h @@ -237,8 +237,9 @@ struct timeval last_refreshed; struct fw_vi_stats_vf stats; - + struct mtx tick_mtx; struct callout tick; + struct sysctl_ctx_list ctx; /* from ifconfig up to driver detach */ uint8_t hw_addr[ETHER_ADDR_LEN]; /* factory MAC address, won't change */ @@ -316,8 +317,6 @@ u_int tx_parse_error; int fcs_reg; uint64_t fcs_base; - - struct callout tick; }; #define IS_MAIN_VI(vi) ((vi) == &((vi)->pi->vi[0])) Index: sys/dev/cxgbe/t4_main.c =================================================================== --- sys/dev/cxgbe/t4_main.c +++ sys/dev/cxgbe/t4_main.c @@ -1797,7 +1797,8 @@ struct adapter *sc = vi->adapter; vi->xact_addr_filt = -1; - callout_init(&vi->tick, 1); + mtx_init(&vi->tick_mtx, "vi tick", NULL, MTX_DEF); + callout_init_mtx(&vi->tick, &vi->tick_mtx, 0); if (sc->flags & IS_VF || t4_tx_vm_wr != 0) vi->flags |= TX_USES_VM_WR; @@ -1921,8 +1922,6 @@ struct vi_info *vi; int i, rc; - callout_init_mtx(&pi->tick, &pi->pi_lock, 0); - rc = cxgbe_vi_attach(dev, &pi->vi[0]); if (rc) return (rc); @@ -1991,7 +1990,6 @@ } cxgbe_vi_detach(&pi->vi[0]); - callout_drain(&pi->tick); ifmedia_removeall(&pi->media); end_synchronized_op(sc, 0); @@ -5583,14 +5581,16 @@ /* all ok */ pi->up_vis++; ifp->if_drv_flags |= IFF_DRV_RUNNING; + if (pi->link_cfg.link_ok) + t4_os_link_changed(pi); + PORT_UNLOCK(pi); + mtx_lock(&vi->tick_mtx); if (pi->nvi > 1 || sc->flags & IS_VF) callout_reset(&vi->tick, hz, vi_tick, vi); else - callout_reset(&pi->tick, hz, cxgbe_tick, pi); - if (pi->link_cfg.link_ok) - t4_os_link_changed(pi); - PORT_UNLOCK(pi); + callout_reset(&vi->tick, hz, cxgbe_tick, vi); + mtx_unlock(&vi->tick_mtx); done: if (rc != 0) cxgbe_uninit_synchronized(vi); @@ -5642,11 +5642,11 @@ TXQ_UNLOCK(txq); } + mtx_lock(&vi->tick_mtx); + callout_stop(&vi->tick); + mtx_unlock(&vi->tick_mtx); + PORT_LOCK(pi); - if (pi->nvi > 1 || sc->flags & IS_VF) - callout_stop(&vi->tick); - else - callout_stop(&pi->tick); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { PORT_UNLOCK(pi); return (0); @@ -6277,15 +6277,16 @@ { u32 stats[2]; - mtx_assert(&sc->reg_lock, MA_OWNED); if (sc->flags & IS_VF) { stats[0] = t4_read_reg(sc, VF_MPS_REG(reg)); stats[1] = t4_read_reg(sc, VF_MPS_REG(reg + 4)); } else { + mtx_lock(&sc->reg_lock); t4_write_reg(sc, A_PL_INDIR_CMD, V_PL_AUTOINC(1) | V_PL_VFID(vin) | V_PL_ADDR(VF_MPS_REG(reg))); stats[0] = t4_read_reg(sc, A_PL_INDIR_DATA); stats[1] = t4_read_reg(sc, A_PL_INDIR_DATA); + mtx_unlock(&sc->reg_lock); } return (((uint64_t)stats[1]) << 32 | stats[0]); } @@ -6343,10 +6344,8 @@ if (timevalcmp(&tv, &vi->last_refreshed, <)) return; - mtx_lock(&sc->reg_lock); t4_get_vi_stats(sc, vi->vin, &vi->stats); getmicrotime(&vi->last_refreshed); - mtx_unlock(&sc->reg_lock); } static void @@ -6380,13 +6379,14 @@ static void cxgbe_tick(void *arg) { - struct port_info *pi = arg; - struct adapter *sc = pi->adapter; + struct vi_info *vi = arg; + struct adapter *sc = vi->adapter; - PORT_LOCK_ASSERT_OWNED(pi); - cxgbe_refresh_stats(sc, pi); + MPASS(IS_MAIN_VI(vi)); + mtx_assert(&vi->tick_mtx, MA_OWNED); - callout_schedule(&pi->tick, hz); + cxgbe_refresh_stats(sc, vi->pi); + callout_schedule(&vi->tick, hz); } void @@ -6395,8 +6395,9 @@ struct vi_info *vi = arg; struct adapter *sc = vi->adapter; - vi_refresh_stats(sc, vi); + mtx_assert(&vi->tick_mtx, MA_OWNED); + vi_refresh_stats(sc, vi); callout_schedule(&vi->tick, hz); }