aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2014-03-22 18:24:44 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2014-03-22 18:24:44 +0000
commitc1974e298d1f9efaafbd2724b15f2c2df955f5e5 (patch)
tree3b2dbc4f8df0e7c257a3b2780789dc7983291070 /sys/dev
parent97bd480fe38abb5950359b9d864a62037b4ab5f7 (diff)
downloadsrc-c1974e298d1f9efaafbd2724b15f2c2df955f5e5.tar.gz
src-c1974e298d1f9efaafbd2724b15f2c2df955f5e5.zip
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.
Notes
Notes: svn path=/head/; revision=263649
Diffstat (limited to 'sys/dev')
-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 b5df636d15a0..a7ac2a56c9b6 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -461,6 +461,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++;
@@ -480,8 +483,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);
@@ -512,12 +515,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 8c74729eb4e7..33ce8b9126f9 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.