From 16a1029878a81ae9948300a9d5c00118e7e5c565 Mon Sep 17 00:00:00 2001 From: jmatthew Date: Thu, 23 Aug 2018 00:22:53 +0000 Subject: [PATCH] set interrupt aggregation parameters so we get around 10000 interrupts per second, which makes a pretty sizable improvement to rx performance. --- sys/dev/pci/if_bnxt.c | 109 ++++++++---------------------------------- 1 file changed, 21 insertions(+), 88 deletions(-) diff --git a/sys/dev/pci/if_bnxt.c b/sys/dev/pci/if_bnxt.c index 202582488bf..3920c8b23fa 100644 --- a/sys/dev/pci/if_bnxt.c +++ b/sys/dev/pci/if_bnxt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bnxt.c,v 1.4 2018/07/11 06:48:58 jmatthew Exp $ */ +/* $OpenBSD: if_bnxt.c,v 1.5 2018/08/23 00:22:53 jmatthew Exp $ */ /*- * Broadcom NetXtreme-C/E network driver. * @@ -386,7 +386,6 @@ int bnxt_hwrm_fw_set_time(struct bnxt_softc *softc, uint16_t year, uint16_t bnxt_hwrm_get_wol_fltrs(struct bnxt_softc *softc, uint16_t handle); int bnxt_hwrm_alloc_wol_fltr(struct bnxt_softc *softc); int bnxt_hwrm_free_wol_fltr(struct bnxt_softc *softc); -int bnxt_hwrm_set_coal(struct bnxt_softc *softc); #endif @@ -460,6 +459,7 @@ void bnxt_attach(struct device *parent, struct device *self, void *aux) { struct bnxt_softc *sc = (struct bnxt_softc *)self; + struct hwrm_ring_cmpl_ring_cfg_aggint_params_input aggint; struct ifnet *ifp = &sc->sc_ac.ac_if; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; @@ -585,6 +585,25 @@ bnxt_attach(struct device *parent, struct device *self, void *aux) } bnxt_write_cp_doorbell(sc, &sc->sc_cp_ring.ring, 1); + /* + * set interrupt aggregation parameters for around 10k interrupts + * per second. the timers are in units of 80usec, and the counters + * are based on the minimum rx ring size of 32. + */ + memset(&aggint, 0, sizeof(aggint)); + bnxt_hwrm_cmd_hdr_init(sc, &aggint, + HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS); + aggint.ring_id = htole16(sc->sc_cp_ring.ring.phys_id); + aggint.num_cmpl_dma_aggr = htole16(32); + aggint.num_cmpl_dma_aggr_during_int = aggint.num_cmpl_dma_aggr; + aggint.cmpl_aggr_dma_tmr = htole16((1000000000 / 20000) / 80); + aggint.cmpl_aggr_dma_tmr_during_int = aggint.cmpl_aggr_dma_tmr; + aggint.int_lat_tmr_min = htole16((1000000000 / 20000) / 80); + aggint.int_lat_tmr_max = htole16((1000000000 / 10000) / 80); + aggint.num_cmpl_aggr_int = htole16(16); + if (hwrm_send_message(sc, &aggint, sizeof(aggint))) + goto free_cp_mem; + strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX; @@ -3345,92 +3364,6 @@ bnxt_hwrm_free_wol_fltr(struct bnxt_softc *softc) return hwrm_send_message(softc, &req, sizeof(req)); } -static void bnxt_hwrm_set_coal_params(struct bnxt_softc *softc, uint32_t max_frames, - uint32_t buf_tmrs, uint16_t flags, - struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req) -{ - req->flags = htole16(flags); - req->num_cmpl_dma_aggr = htole16((uint16_t)max_frames); - req->num_cmpl_dma_aggr_during_int = htole16(max_frames >> 16); - req->cmpl_aggr_dma_tmr = htole16((uint16_t)buf_tmrs); - req->cmpl_aggr_dma_tmr_during_int = htole16(buf_tmrs >> 16); - /* Minimum time between 2 interrupts set to buf_tmr x 2 */ - req->int_lat_tmr_min = htole16((uint16_t)buf_tmrs * 2); - req->int_lat_tmr_max = htole16((uint16_t)buf_tmrs * 4); - req->num_cmpl_aggr_int = htole16((uint16_t)max_frames * 4); -} - - -int bnxt_hwrm_set_coal(struct bnxt_softc *softc) -{ - int i, rc = 0; - struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0}, - req_tx = {0}, *req; - uint16_t max_buf, max_buf_irq; - uint16_t buf_tmr, buf_tmr_irq; - uint32_t flags; - - bnxt_hwrm_cmd_hdr_init(softc, &req_rx, - HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS); - bnxt_hwrm_cmd_hdr_init(softc, &req_tx, - HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS); - - /* Each rx completion (2 records) should be DMAed immediately. - * DMA 1/4 of the completion buffers at a time. - */ - max_buf = min_t(uint16_t, softc->rx_coal_frames / 4, 2); - /* max_buf must not be zero */ - max_buf = clamp_t(uint16_t, max_buf, 1, 63); - max_buf_irq = clamp_t(uint16_t, softc->rx_coal_frames_irq, 1, 63); - buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs); - /* buf timer set to 1/4 of interrupt timer */ - buf_tmr = max_t(uint16_t, buf_tmr / 4, 1); - buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs_irq); - buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1); - - flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET; - - /* RING_IDLE generates more IRQs for lower latency. Enable it only - * if coal_usecs is less than 25 us. - */ - if (softc->rx_coal_usecs < 25) - flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE; - - bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf, - buf_tmr_irq << 16 | buf_tmr, flags, &req_rx); - - /* max_buf must not be zero */ - max_buf = clamp_t(uint16_t, softc->tx_coal_frames, 1, 63); - max_buf_irq = clamp_t(uint16_t, softc->tx_coal_frames_irq, 1, 63); - buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs); - /* buf timer set to 1/4 of interrupt timer */ - buf_tmr = max_t(uint16_t, buf_tmr / 4, 1); - buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs_irq); - buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1); - flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET; - bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf, - buf_tmr_irq << 16 | buf_tmr, flags, &req_tx); - - for (i = 0; i < softc->nrxqsets; i++) { - - - req = &req_rx; - /* - * TBD: - * Check if Tx also needs to be done - * So far, Tx processing has been done in softirq contest - * - * req = &req_tx; - */ - req->ring_id = htole16(softc->grp_info[i].cp_ring_id); - - rc = hwrm_send_message(softc, req, sizeof(*req)); - if (rc) - break; - } - return rc; -} - #endif void -- 2.20.1