Date: Sat, 27 Sep 2014 05:50:31 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r272200 - head/sys/dev/cxgbe Message-ID: <201409270550.s8R5oV9e036364@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Sat Sep 27 05:50:31 2014 New Revision: 272200 URL: http://svnweb.freebsd.org/changeset/base/272200 Log: cxgbe(4): implement if_get_counter. Modified: head/sys/dev/cxgbe/adapter.h head/sys/dev/cxgbe/t4_main.c Modified: head/sys/dev/cxgbe/adapter.h ============================================================================== --- head/sys/dev/cxgbe/adapter.h Sat Sep 27 05:14:02 2014 (r272199) +++ head/sys/dev/cxgbe/adapter.h Sat Sep 27 05:50:31 2014 (r272200) @@ -268,7 +268,10 @@ struct port_info { int linkdnrc; struct link_config link_cfg; - struct port_stats stats; + + struct timeval last_refreshed; + struct port_stats stats; + u_int tnl_cong_drops; eventhandler_tag vlan_c; @@ -790,6 +793,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: head/sys/dev/cxgbe/t4_main.c ============================================================================== --- head/sys/dev/cxgbe/t4_main.c Sat Sep 27 05:14:02 2014 (r272199) +++ head/sys/dev/cxgbe/t4_main.c Sat Sep 27 05:50:31 2014 (r272200) @@ -151,6 +151,7 @@ static void cxgbe_init(void *); static int cxgbe_ioctl(struct ifnet *, unsigned long, caddr_t); static int cxgbe_transmit(struct ifnet *, struct mbuf *); static void cxgbe_qflush(struct ifnet *); +static uint64_t cxgbe_get_counter(struct ifnet *, ift_counter); static int cxgbe_media_change(struct ifnet *); static void cxgbe_media_status(struct ifnet *, struct ifmediareq *); @@ -386,6 +387,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 *, @@ -609,6 +611,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 */ @@ -1024,6 +1028,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)); @@ -1073,6 +1079,7 @@ cxgbe_attach(device_t dev) ifp->if_ioctl = cxgbe_ioctl; ifp->if_transmit = cxgbe_transmit; ifp->if_qflush = cxgbe_qflush; + ifp->if_get_counter = cxgbe_get_counter; ifp->if_capabilities = T4_CAP; #ifdef TCP_OFFLOAD @@ -1504,6 +1511,67 @@ cxgbe_qflush(struct ifnet *ifp) if_qflush(ifp); } +static uint64_t +cxgbe_get_counter(struct ifnet *ifp, ift_counter c) +{ + struct port_info *pi = ifp->if_softc; + struct adapter *sc = pi->adapter; + struct port_stats *s = &pi->stats; + + cxgbe_refresh_stats(sc, pi); + + switch (c) { + case IFCOUNTER_IPACKETS: + return (s->rx_frames - s->rx_pause); + + case IFCOUNTER_IERRORS: + return (s->rx_jabber + s->rx_runt + s->rx_too_long + + s->rx_fcs_err + s->rx_len_err); + + case IFCOUNTER_OPACKETS: + return (s->tx_frames - s->tx_pause); + + case IFCOUNTER_OERRORS: + return (s->tx_error_frames); + + case IFCOUNTER_IBYTES: + return (s->rx_octets - s->rx_pause * 64); + + case IFCOUNTER_OBYTES: + return (s->tx_octets - s->tx_pause * 64); + + case IFCOUNTER_IMCASTS: + return (s->rx_mcast_frames - s->rx_pause); + + case IFCOUNTER_OMCASTS: + return (s->tx_mcast_frames - s->tx_pause); + + case IFCOUNTER_IQDROPS: + return (s->rx_ovflow0 + s->rx_ovflow1 + s->rx_ovflow2 + + s->rx_ovflow3 + s->rx_trunc0 + s->rx_trunc1 + s->rx_trunc2 + + s->rx_trunc3 + pi->tnl_cong_drops); + + case IFCOUNTER_OQDROPS: { + uint64_t drops; + + drops = s->tx_drop; + if (pi->flags & PORT_INIT_DONE) { + int i; + struct sge_txq *txq; + + for_each_txq(pi, i, txq) + drops += txq->br->br_drops; + } + + return (drops); + + } + + default: + return (if_get_counter_default(ifp, c)); + } +} + static int cxgbe_media_change(struct ifnet *ifp) { @@ -4277,14 +4345,39 @@ t4_get_regs(struct adapter *sc, struct t } static void +cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi) +{ + int i; + u_int v, tnl_cong_drops; + struct timeval tv; + const struct timeval interval = {0, 250000}; /* 250ms */ + + getmicrotime(&tv); + timevalsub(&tv, &interval); + if (timevalcmp(&tv, &pi->last_refreshed, <)) + return; + + tnl_cong_drops = 0; + t4_get_port_stats(sc, pi->tx_chan, &pi->stats); + for (i = 0; i < NCHAN; i++) { + if (pi->rx_chan_map & (1 << i)) { + 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); + tnl_cong_drops += v; + } + } + pi->tnl_cong_drops = tnl_cong_drops; + 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; - struct sge_txq *txq; - int i, drops; - struct port_stats *s = &pi->stats; PORT_LOCK(pi); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { @@ -4292,39 +4385,7 @@ cxgbe_tick(void *arg) return; /* without scheduling another callout */ } - t4_get_port_stats(sc, pi->tx_chan, s); - - ifp->if_opackets = s->tx_frames - s->tx_pause; - ifp->if_ipackets = s->rx_frames - s->rx_pause; - ifp->if_obytes = s->tx_octets - s->tx_pause * 64; - ifp->if_ibytes = s->rx_octets - s->rx_pause * 64; - ifp->if_omcasts = s->tx_mcast_frames - s->tx_pause; - ifp->if_imcasts = s->rx_mcast_frames - s->rx_pause; - 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++) { - if (pi->rx_chan_map & (1 << i)) { - uint32_t v; - - /* - * XXX: indirect reads from the same ADDR/DATA pair can - * race with each other. - */ - t4_read_indirect(sc, A_TP_MIB_INDEX, A_TP_MIB_DATA, &v, - 1, A_TP_MIB_TNL_CNG_DROP_0 + i); - ifp->if_iqdrops += v; - } - } - - drops = s->tx_drop; - for_each_txq(pi, i, txq) - drops += txq->br->br_drops; - ifp->if_oqdrops = drops; - - ifp->if_oerrors = s->tx_error_frames; - ifp->if_ierrors = s->rx_jabber + s->rx_runt + s->rx_too_long + - s->rx_fcs_err + s->rx_len_err; + 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?201409270550.s8R5oV9e036364>