cxgbe(4): Do not assume that if_qflush is always followed by inteface-down.
MFC after: 3 days Sponsored by: Chelsio Communications
This commit is contained in:
parent
7dd10fded0
commit
1404daa76c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=318091
@ -399,6 +399,7 @@ enum {
|
||||
EQ_TYPEMASK = 0x3, /* 2 lsbits hold the type (see above) */
|
||||
EQ_ALLOCATED = (1 << 2), /* firmware resources allocated */
|
||||
EQ_ENABLED = (1 << 3), /* open for business */
|
||||
EQ_QFLUSH = (1 << 4), /* if_qflush in progress */
|
||||
};
|
||||
|
||||
/* Listed in order of preference. Update t4_sysctls too if you change these */
|
||||
|
@ -1869,12 +1869,15 @@ cxgbe_qflush(struct ifnet *ifp)
|
||||
if (vi->flags & VI_INIT_DONE) {
|
||||
for_each_txq(vi, i, txq) {
|
||||
TXQ_LOCK(txq);
|
||||
txq->eq.flags &= ~EQ_ENABLED;
|
||||
txq->eq.flags |= EQ_QFLUSH;
|
||||
TXQ_UNLOCK(txq);
|
||||
while (!mp_ring_is_idle(txq->r)) {
|
||||
mp_ring_check_drainage(txq->r, 0);
|
||||
pause("qflush", 1);
|
||||
}
|
||||
TXQ_LOCK(txq);
|
||||
txq->eq.flags &= ~EQ_QFLUSH;
|
||||
TXQ_UNLOCK(txq);
|
||||
}
|
||||
}
|
||||
if_qflush(ifp);
|
||||
|
@ -2452,6 +2452,13 @@ cannot_use_txpkts(struct mbuf *m)
|
||||
return (needs_tso(m));
|
||||
}
|
||||
|
||||
static inline int
|
||||
discard_tx(struct sge_eq *eq)
|
||||
{
|
||||
|
||||
return ((eq->flags & (EQ_ENABLED | EQ_QFLUSH)) != EQ_ENABLED);
|
||||
}
|
||||
|
||||
/*
|
||||
* r->items[cidx] to r->items[pidx], with a wraparound at r->size, are ready to
|
||||
* be consumed. Return the actual number consumed. 0 indicates a stall.
|
||||
@ -2477,7 +2484,7 @@ eth_tx(struct mp_ring *r, u_int cidx, u_int pidx)
|
||||
total = 0;
|
||||
|
||||
TXQ_LOCK(txq);
|
||||
if (__predict_false((eq->flags & EQ_ENABLED) == 0)) {
|
||||
if (__predict_false(discard_tx(eq))) {
|
||||
while (cidx != pidx) {
|
||||
m0 = r->items[cidx];
|
||||
m_freem(m0);
|
||||
|
Loading…
Reference in New Issue
Block a user