cxgbe(4): Fix per-queue netmap operation.
Do not attempt to initialize netmap queues that are already initialized or aren't supposed to be initialized. Similarly, do not free queues that are not initialized or aren't supposed to be freed. PR: 217156 Sponsored by: Chelsio Communications
This commit is contained in:
parent
26edb1a898
commit
7fc0b94656
@ -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;
|
||||
|
@ -224,6 +224,7 @@ free_nm_rxq_hwq(struct vi_info *vi, struct sge_nm_rxq *nm_rxq)
|
||||
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, struct sge_nm_txq *nm_txq)
|
||||
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, struct vi_info *vi, struct ifnet *ifp,
|
||||
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, struct vi_info *vi, struct ifnet *ifp,
|
||||
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, struct vi_info *vi, struct ifnet *ifp,
|
||||
}
|
||||
|
||||
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, struct vi_info *vi, struct ifnet *ifp,
|
||||
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, struct vi_info *vi, struct ifnet *ifp,
|
||||
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);
|
||||
|
||||
|
@ -3264,6 +3264,7 @@ alloc_nm_rxq(struct vi_info *vi, struct sge_nm_rxq *nm_rxq, int intr_idx,
|
||||
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 sge_nm_rxq *nm_rxq)
|
||||
{
|
||||
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 sge_nm_txq *nm_txq, int iqidx, int idx,
|
||||
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 sge_nm_txq *nm_txq)
|
||||
{
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user