diff -r 488fbe994a6c -r 533feb86054b sys/dev/cxgbe/adapter.h --- a/sys/dev/cxgbe/adapter.h Wed Jun 14 19:36:28 2017 +0000 +++ b/sys/dev/cxgbe/adapter.h Thu Jun 15 09:37:30 2017 -0700 @@ -647,7 +647,7 @@ struct sge_wrq { } __aligned(CACHE_LINE_SIZE); - +#define INVALID_NM_RXQ_CNTXT_ID ((uint16_t)(-1)) struct sge_nm_rxq { struct vi_info *vi; @@ -680,6 +680,7 @@ struct sge_nm_rxq { bus_addr_t fl_ba; } __aligned(CACHE_LINE_SIZE); +#define INVALID_NM_TXQ_CNTXT_ID ((u_int)(-1)) struct sge_nm_txq { struct tx_desc *desc; uint16_t cidx; diff -r 488fbe994a6c -r 533feb86054b sys/dev/cxgbe/t4_netmap.c --- a/sys/dev/cxgbe/t4_netmap.c Wed Jun 14 19:36:28 2017 +0000 +++ b/sys/dev/cxgbe/t4_netmap.c Thu Jun 15 09:37:30 2017 -0700 @@ -224,6 +224,7 @@ free_nm_rxq_hwq(struct vi_info *vi, stru if (rc != 0) device_printf(sc->dev, "%s: failed for iq %d, fl %d: %d\n", __func__, nm_rxq->iq_cntxt_id, nm_rxq->fl_cntxt_id, rc); + nm_rxq->iq_cntxt_id = INVALID_NM_RXQ_CNTXT_ID; return (rc); } @@ -310,6 +311,7 @@ free_nm_txq_hwq(struct vi_info *vi, stru if (rc != 0) device_printf(sc->dev, "%s: failed for eq %d: %d\n", __func__, nm_txq->cntxt_id, rc); + nm_txq->cntxt_id = INVALID_NM_TXQ_CNTXT_ID; return (rc); } @@ -318,6 +320,7 @@ cxgbe_netmap_on(struct adapter *sc, stru struct netmap_adapter *na) { struct netmap_slot *slot; + struct netmap_kring *kring; struct sge_nm_rxq *nm_rxq; struct sge_nm_txq *nm_txq; int rc, i, j, hwidx; @@ -347,6 +350,11 @@ cxgbe_netmap_on(struct adapter *sc, stru for_each_nm_rxq(vi, i, nm_rxq) { struct irq *irq = &sc->irq[vi->first_intr + i]; + kring = &na->rx_rings[nm_rxq->nid]; + if (!nm_kring_pending_on(kring) || + nm_rxq->iq_cntxt_id != INVALID_NM_RXQ_CNTXT_ID) + continue; + alloc_nm_rxq_hwq(vi, nm_rxq, tnl_cong(vi->pi, nm_cong_drop)); nm_rxq->fl_hwidx = hwidx; slot = netmap_reset(na, NR_RX, i, 0); @@ -373,6 +381,11 @@ cxgbe_netmap_on(struct adapter *sc, stru } for_each_nm_txq(vi, i, nm_txq) { + kring = &na->tx_rings[nm_txq->nid]; + if (!nm_kring_pending_on(kring) || + nm_txq->cntxt_id != INVALID_NM_TXQ_CNTXT_ID) + continue; + alloc_nm_txq_hwq(vi, nm_txq); slot = netmap_reset(na, NR_TX, i, 0); MPASS(slot != NULL); /* XXXNM: error check, not assert */ @@ -401,6 +414,7 @@ static int cxgbe_netmap_off(struct adapter *sc, struct vi_info *vi, struct ifnet *ifp, struct netmap_adapter *na) { + struct netmap_kring *kring; int rc, i; struct sge_nm_txq *nm_txq; struct sge_nm_rxq *nm_rxq; @@ -419,6 +433,11 @@ cxgbe_netmap_off(struct adapter *sc, str for_each_nm_txq(vi, i, nm_txq) { struct sge_qstat *spg = (void *)&nm_txq->desc[nm_txq->sidx]; + kring = &na->tx_rings[nm_txq->nid]; + if (!nm_kring_pending_off(kring) || + nm_txq->cntxt_id == INVALID_NM_TXQ_CNTXT_ID) + continue; + /* Wait for hw pidx to catch up ... */ while (be16toh(nm_txq->pidx) != spg->pidx) pause("nmpidx", 1); @@ -432,6 +451,11 @@ cxgbe_netmap_off(struct adapter *sc, str for_each_nm_rxq(vi, i, nm_rxq) { struct irq *irq = &sc->irq[vi->first_intr + i]; + kring = &na->rx_rings[nm_rxq->nid]; + if (!nm_kring_pending_off(kring) || + nm_rxq->iq_cntxt_id == INVALID_NM_RXQ_CNTXT_ID) + continue; + while (!atomic_cmpset_int(&irq->nm_state, NM_ON, NM_OFF)) pause("nmst", 1); diff -r 488fbe994a6c -r 533feb86054b sys/dev/cxgbe/t4_sge.c --- a/sys/dev/cxgbe/t4_sge.c Wed Jun 14 19:36:28 2017 +0000 +++ b/sys/dev/cxgbe/t4_sge.c Thu Jun 15 09:37:30 2017 -0700 @@ -3264,6 +3264,7 @@ alloc_nm_rxq(struct vi_info *vi, struct nm_rxq->fl_pidx = nm_rxq->fl_cidx = 0; nm_rxq->fl_sidx = na->num_rx_desc; nm_rxq->intr_idx = intr_idx; + nm_rxq->iq_cntxt_id = INVALID_NM_RXQ_CNTXT_ID; ctx = &vi->ctx; children = SYSCTL_CHILDREN(oid); @@ -3305,6 +3306,8 @@ free_nm_rxq(struct vi_info *vi, struct s { struct adapter *sc = vi->pi->adapter; + MPASS(nm_rxq->iq_cntxt_id == INVALID_NM_RXQ_CNTXT_ID); + free_ring(sc, nm_rxq->iq_desc_tag, nm_rxq->iq_desc_map, nm_rxq->iq_ba, nm_rxq->iq_desc); free_ring(sc, nm_rxq->fl_desc_tag, nm_rxq->fl_desc_map, nm_rxq->fl_ba, @@ -3339,6 +3342,7 @@ alloc_nm_txq(struct vi_info *vi, struct V_TXPKT_INTF(pi->tx_chan) | V_TXPKT_PF(G_FW_VIID_PFN(vi->viid)) | V_TXPKT_VF(G_FW_VIID_VIN(vi->viid)) | V_TXPKT_VF_VLD(G_FW_VIID_VIVLD(vi->viid))); + nm_txq->cntxt_id = INVALID_NM_TXQ_CNTXT_ID; snprintf(name, sizeof(name), "%d", idx); oid = SYSCTL_ADD_NODE(&vi->ctx, children, OID_AUTO, name, CTLFLAG_RD, @@ -3362,6 +3366,8 @@ free_nm_txq(struct vi_info *vi, struct s { struct adapter *sc = vi->pi->adapter; + MPASS(nm_txq->cntxt_id == INVALID_NM_TXQ_CNTXT_ID); + free_ring(sc, nm_txq->desc_tag, nm_txq->desc_map, nm_txq->ba, nm_txq->desc);