Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci if bnx_tx_encap() fails because mbuf is too frag...



details:   https://anonhg.NetBSD.org/src/rev/8ea85a150a11
branches:  trunk
changeset: 936055:8ea85a150a11
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Fri Jul 17 10:56:15 2020 +0000

description:
if bnx_tx_encap() fails because mbuf is too fragmented or too long,
drop the mbuf instead of wedging the TX queue forever; found by code inspection

this is quite unlikely scenario since it requires mbuf chain consisting of
more than 8 frags and m_defrag() failing, so probably unrelated to PR kern/47229

diffstat:

 sys/dev/pci/if_bnx.c |  34 +++++++++++++++++++++++-----------
 1 files changed, 23 insertions(+), 11 deletions(-)

diffs (77 lines):

diff -r 3f5a771c3671 -r 8ea85a150a11 sys/dev/pci/if_bnx.c
--- a/sys/dev/pci/if_bnx.c      Fri Jul 17 10:08:04 2020 +0000
+++ b/sys/dev/pci/if_bnx.c      Fri Jul 17 10:56:15 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bnx.c,v 1.104 2020/07/17 10:08:04 jdolecek Exp $    */
+/*     $NetBSD: if_bnx.c,v 1.105 2020/07/17 10:56:15 jdolecek Exp $    */
 /*     $OpenBSD: if_bnx.c,v 1.101 2013/03/28 17:21:44 brad Exp $       */
 
 /*-
@@ -35,7 +35,7 @@
 #if 0
 __FBSDID("$FreeBSD: src/sys/dev/bce/if_bce.c,v 1.3 2006/04/13 14:12:26 ru Exp $");
 #endif
-__KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.104 2020/07/17 10:08:04 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.105 2020/07/17 10:56:15 jdolecek Exp $");
 
 /*
  * The following controllers are supported by this driver:
@@ -5174,8 +5174,10 @@
        bus_dmamap_sync(sc->bnx_dmatag, map, 0, map->dm_mapsize,
            BUS_DMASYNC_PREWRITE);
        /* Make sure there's room in the chain */
-       if (map->dm_nsegs > (sc->max_tx_bd - sc->used_tx_bd))
+       if (map->dm_nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
+               error = ENOMEM;
                goto nospace;
+       }
 
        /* prod points to an empty tx_bd at this point. */
        prod_bseq = sc->tx_prod_bseq;
@@ -5254,7 +5256,7 @@
        TAILQ_INSERT_TAIL(&sc->tx_free_pkts, pkt, pkt_entry);
        mutex_exit(&sc->tx_pkt_mtx);
 
-       return ENOMEM;
+       return error;
 }
 
 /****************************************************************************/
@@ -5268,7 +5270,7 @@
 {
        struct bnx_softc        *sc = ifp->if_softc;
        struct mbuf             *m_head = NULL;
-       int                     count = 0;
+       int                     count = 0, error;
 #ifdef BNX_DEBUG
        uint16_t                tx_chain_prod;
 #endif
@@ -5306,12 +5308,22 @@
                 * don't have room, set the OACTIVE flag to wait
                 * for the NIC to drain the chain.
                 */
-               if (bnx_tx_encap(sc, m_head)) {
-                       ifp->if_flags |= IFF_OACTIVE;
-                       DBPRINT(sc, BNX_INFO_SEND, "TX chain is closed for "
-                           "business! Total tx_bd used = %d\n",
-                           sc->used_tx_bd);
-                       break;
+               if ((error = bnx_tx_encap(sc, m_head))) {
+                       if (error == ENOMEM) {
+                               ifp->if_flags |= IFF_OACTIVE;
+                               DBPRINT(sc, BNX_INFO_SEND,
+                                   "TX chain is closed for "
+                                   "business! Total tx_bd used = %d\n",
+                                   sc->used_tx_bd);
+                               break;
+                       } else {
+                               /* Permanent error for the mbuf, drop it */
+                               IFQ_DEQUEUE(&ifp->if_snd, m_head);
+                               m_freem(m_head);
+                               DBPRINT(sc, BNX_INFO_SEND,
+                                   "mbuf load error %d, dropped\n", error);
+                               continue;
+                       }
                }
 
                IFQ_DEQUEUE(&ifp->if_snd, m_head);



Home | Main Index | Thread Index | Old Index