MFC svn 267065 and 267187

make sure ifp->if_transmit returns 0 if a buffer is enqueued.
This should also be merged to stable/9.

After this fix, drivers still known to have this bug are igxbe/ixv
and i40e.

Drivers using if_transmit are correct, and so are most of the
other drivers that reassing if_transmit.

Among other things, this bug causes panics when using netmap emulation
on top of generic drivers.
This commit is contained in:
luigi 2014-06-09 15:09:05 +00:00
parent 5fc12f2e25
commit 63bea6a967
4 changed files with 6 additions and 8 deletions

View File

@ -988,12 +988,12 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
if (err)
return (err);
if (IGB_TX_TRYLOCK(txr)) {
err = igb_mq_start_locked(ifp, txr);
igb_mq_start_locked(ifp, txr);
IGB_TX_UNLOCK(txr);
} else
taskqueue_enqueue(que->tq, &txr->txq_task);
return (err);
return (0);
}
static int

View File

@ -831,12 +831,12 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m)
if (err)
return (err);
if (IXGBE_TX_TRYLOCK(txr)) {
err = ixgbe_mq_start_locked(ifp, txr);
ixgbe_mq_start_locked(ifp, txr);
IXGBE_TX_UNLOCK(txr);
} else
taskqueue_enqueue(que->tq, &txr->txq_task);
return (err);
return (0);
}
static int

View File

@ -2260,7 +2260,6 @@ vtnet_txq_mq_start_locked(struct vtnet_txq *txq, struct mbuf *m)
while ((m = drbr_peek(ifp, br)) != NULL) {
if (virtqueue_full(vq)) {
drbr_putback(ifp, br, m);
error = ENOBUFS;
break;
}
@ -2283,7 +2282,7 @@ vtnet_txq_mq_start_locked(struct vtnet_txq *txq, struct mbuf *m)
txq->vtntx_watchdog = VTNET_TX_TIMEOUT;
}
return (error);
return (0);
}
static int

View File

@ -2933,7 +2933,6 @@ vmxnet3_txq_mq_start_locked(struct vmxnet3_txqueue *txq, struct mbuf *m)
/* Assume worse case if this mbuf is the head of a chain. */
if (m->m_next != NULL && avail < VMXNET3_TX_MAXSEGS) {
drbr_putback(ifp, br, m);
error = ENOBUFS;
break;
}
@ -2956,7 +2955,7 @@ vmxnet3_txq_mq_start_locked(struct vmxnet3_txqueue *txq, struct mbuf *m)
txq->vxtxq_watchdog = VMXNET3_WATCHDOG_TIMEOUT;
}
return (error);
return (0);
}
static int