Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci/ixgbe Fix jcl's starvation case in ixgbe_rxeof()...



details:   https://anonhg.NetBSD.org/src/rev/5da19777acfd
branches:  trunk
changeset: 953262:5da19777acfd
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Mar 02 11:10:53 2021 +0000

description:
Fix jcl's starvation case in ixgbe_rxeof() again.

 ix_txrx.c rev.1.64 preallocates jcl to prevent starvation but it's not
perfect. Don't use ixgbe_rx_discard() and just update the old descriptor
for reuse. It's also required for multiple descriptors case to refresh
subsequent descriptor(s). Reviewed by knakahara@.

diffstat:

 sys/dev/pci/ixgbe/ix_txrx.c |  48 ++++++++++++++++++++++++++++++++++++++------
 1 files changed, 41 insertions(+), 7 deletions(-)

diffs (98 lines):

diff -r c35510bd5e9b -r 5da19777acfd sys/dev/pci/ixgbe/ix_txrx.c
--- a/sys/dev/pci/ixgbe/ix_txrx.c       Tue Mar 02 10:17:25 2021 +0000
+++ b/sys/dev/pci/ixgbe/ix_txrx.c       Tue Mar 02 11:10:53 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.64 2021/01/18 09:09:04 knakahara Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.65 2021/03/02 11:10:53 msaitoh Exp $ */
 
 /******************************************************************************
 
@@ -1319,6 +1319,11 @@
  *      exhaustion are unnecessary, if an mbuf cannot be obtained
  *      it just returns, keeping its placeholder, thus it can simply
  *      be recalled to try again.
+ *
+ *   XXX NetBSD TODO:
+ *    - The ixgbe_rxeof() function always preallocates mbuf cluster (jcl),
+ *      so the ixgbe_refresh_mbufs() function can be simplified.
+ *
  ************************************************************************/
 static void
 ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit)
@@ -1799,7 +1804,9 @@
        struct ixgbe_rx_buf     *rbuf, *nbuf;
        int                     i, nextp, processed = 0;
        u32                     staterr = 0;
-       u32                     count = adapter->rx_process_limit;
+       u32                     count = 0;
+       u32                     limit = adapter->rx_process_limit;
+       bool                    discard_multidesc = false;
 #ifdef RSS
        u16                     pkt_info;
 #endif
@@ -1816,7 +1823,14 @@
        }
 #endif /* DEV_NETMAP */
 
-       for (i = rxr->next_to_check; count != 0;) {
+       /*
+        * The max number of loop is rx_process_limit. If discard_multidesc is
+        * true, continue processing to not to send broken packet to the upper
+        * layer.
+        */
+       for (i = rxr->next_to_check;
+            (count < limit) || (discard_multidesc == true);) {
+
                struct mbuf *sendmp, *mp;
                struct mbuf *newmp;
                u32         rsc, ptype;
@@ -1837,7 +1851,7 @@
                if ((staterr & IXGBE_RXD_STAT_DD) == 0)
                        break;
 
-               count--;
+               count++;
                sendmp = NULL;
                nbuf = NULL;
                rsc = 0;
@@ -1858,17 +1872,37 @@
 #endif
                        rxr->rx_discarded.ev_count++;
                        ixgbe_rx_discard(rxr, i);
+                       discard_multidesc = false;
                        goto next_desc;
                }
 
                /* pre-alloc new mbuf */
-               newmp = ixgbe_getjcl(&rxr->jcl_head, M_NOWAIT, MT_DATA, M_PKTHDR,
-                   rxr->mbuf_sz);
+               if (!discard_multidesc)
+                       newmp = ixgbe_getjcl(&rxr->jcl_head, M_NOWAIT, MT_DATA,
+                           M_PKTHDR, rxr->mbuf_sz);
+               else
+                       newmp = NULL;
                if (newmp == NULL) {
                        rxr->rx_discarded.ev_count++;
-                       ixgbe_rx_discard(rxr, i);
+                       /*
+                        * Descriptor initialization is already done by the
+                        * above code (cur->wb.upper.status_error = 0).
+                        * So, we can reuse current rbuf->buf for new packet.
+                        *
+                        * Rewrite the buffer addr, see comment in
+                        * ixgbe_rx_discard().
+                        */
+                       cur->read.pkt_addr = rbuf->addr;
+                       m_freem(rbuf->fmp);
+                       rbuf->fmp = NULL;
+                       if (!eop) {
+                               /* Discard the entire packet. */
+                               discard_multidesc = true;
+                       } else
+                               discard_multidesc = false;
                        goto next_desc;
                }
+               discard_multidesc = false;
 
                bus_dmamap_sync(rxr->ptag->dt_dmat, rbuf->pmap, 0,
                    rbuf->buf->m_pkthdr.len, BUS_DMASYNC_POSTREAD);



Home | Main Index | Thread Index | Old Index