summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2015-03-25 09:56:48 +0000
committerarybchik <arybchik@FreeBSD.org>2015-03-25 09:56:48 +0000
commit8b332410328c1b1719bdd73f64cc33faff216ec7 (patch)
tree34aae2fe2415a73cb7a93fd312cef00748336332
parent88a57b90495bbfea2ee8318c44b1444ef3b09ff8 (diff)
downloadFreeBSD-src-8b332410328c1b1719bdd73f64cc33faff216ec7.zip
FreeBSD-src-8b332410328c1b1719bdd73f64cc33faff216ec7.tar.gz
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.
-rw-r--r--sys/dev/sfxge/sfxge_tx.c14
-rw-r--r--sys/dev/sfxge/sfxge_tx.h3
2 files changed, 9 insertions, 8 deletions
diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c
index 4d97cac..20f6f87 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -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;
}
diff --git a/sys/dev/sfxge/sfxge_tx.h b/sys/dev/sfxge/sfxge_tx.h
index 8c74729..33ce8b9 100644
--- a/sys/dev/sfxge/sfxge_tx.h
+++ b/sys/dev/sfxge/sfxge_tx.h
@@ -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.
OpenPOWER on IntegriCloud