Author: arybchik
Date: Wed Mar 25 09:56:48 2015
New Revision: 280499
URL: https://svnweb.freebsd.org/changeset/base/280499

Log:
  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.

Modified:
  stable/10/sys/dev/sfxge/sfxge_tx.c
  stable/10/sys/dev/sfxge/sfxge_tx.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/sfxge/sfxge_tx.c
==============================================================================
--- stable/10/sys/dev/sfxge/sfxge_tx.c  Wed Mar 25 09:54:07 2015        
(r280498)
+++ stable/10/sys/dev/sfxge/sfxge_tx.c  Wed Mar 25 09:56:48 2015        
(r280499)
@@ -476,6 +476,9 @@ sfxge_tx_qdpl_put(struct sfxge_txq *txq,
 
                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,
                                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 *tx
         */
        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;
        }

Modified: stable/10/sys/dev/sfxge/sfxge_tx.h
==============================================================================
--- stable/10/sys/dev/sfxge/sfxge_tx.h  Wed Mar 25 09:54:07 2015        
(r280498)
+++ stable/10/sys/dev/sfxge/sfxge_tx.h  Wed Mar 25 09:56:48 2015        
(r280499)
@@ -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.
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "[email protected]"

Reply via email to