MFC: 263649

sfxge: limit software Tx queue size.

Previous implementation limits put queue size only (when Tx lock can't
be acquired), but get queue may grow unboundedly which results in mbuf
pools exhaustion and latency growth.

Submitted by:   Andrew Rybchenko <Andrew.Rybchenko at oktetlabs.ru>
Sponsored by:   Solarflare Communications, Inc.
This commit is contained in:
arybchik 2015-03-25 09:56:48 +00:00
parent 88a57b9049
commit 8b33241032
2 changed files with 9 additions and 8 deletions

View File

@ -476,6 +476,9 @@ sfxge_tx_qdpl_put(struct sfxge_txq *txq, struct mbuf *mbuf, int locked)
sfxge_tx_qdpl_swizzle(txq);
if (stdp->std_count >= SFXGE_TX_DPL_GET_PKT_LIMIT_DEFAULT)
return (ENOBUFS);
*(stdp->std_getp) = mbuf;
stdp->std_getp = &mbuf->m_nextpkt;
stdp->std_count++;
@ -495,8 +498,8 @@ sfxge_tx_qdpl_put(struct sfxge_txq *txq, struct mbuf *mbuf, int locked)
old_len = mp->m_pkthdr.csum_data;
} else
old_len = 0;
if (old_len >= SFXGE_TX_MAX_DEFERRED)
return ENOBUFS;
if (old_len >= SFXGE_TX_DPL_PUT_PKT_LIMIT_DEFAULT)
return (ENOBUFS);
mbuf->m_pkthdr.csum_data = old_len + 1;
mbuf->m_nextpkt = (void *)old;
} while (atomic_cmpset_ptr(putp, old, new) == 0);
@ -527,12 +530,9 @@ sfxge_tx_packet_add(struct sfxge_txq *txq, struct mbuf *m)
*/
locked = mtx_trylock(&txq->lock);
/*
* Can only fail if we weren't able to get the lock.
*/
if (sfxge_tx_qdpl_put(txq, m, locked) != 0) {
KASSERT(!locked,
("sfxge_tx_qdpl_put() failed locked"));
if (locked)
mtx_unlock(&txq->lock);
rc = ENOBUFS;
goto fail;
}

View File

@ -75,7 +75,8 @@ struct sfxge_tx_mapping {
enum sfxge_tx_buf_flags flags;
};
#define SFXGE_TX_MAX_DEFERRED 64
#define SFXGE_TX_DPL_GET_PKT_LIMIT_DEFAULT 64
#define SFXGE_TX_DPL_PUT_PKT_LIMIT_DEFAULT 64
/*
* Deferred packet list.