Source-Changes-HG archive

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

[src/netbsd-8]: src/sys/dev/pci Pull up following revision(s) (requested by m...



details:   https://anonhg.NetBSD.org/src/rev/fe7ca89d6919
branches:  netbsd-8
changeset: 435266:fe7ca89d6919
user:      martin <martin%NetBSD.org@localhost>
date:      Sun Sep 23 17:39:02 2018 +0000

description:
Pull up following revision(s) (requested by msaitoh in ticket #1027):
        sys/dev/pci/if_wm.c: revision 1.586
        sys/dev/pci/if_wm.c: revision 1.587
        sys/dev/pci/if_wm.c: revision 1.588

- Split txdrop evcnt into pcqdrop and descdrop.
- Simplify evcnt name by removing duplicated "tx" or "rx".
- s/tu/underrun/

- Try m_defrag() to reduce the number of DMA segment if bus_dmamap_load_mbuf()
   returned EFBIG. When m_defrag() is called, txqNNdefrag event counter is
   incremented. If the 2nd try of bus_dmamap_load_mbuf() failed, txqNNtoomanyseg
   event counter is incremented.

- Reduce the max number of DMA segments from 256 to 64 (it's the same value
   as other BSD's (EM_MAX_SCATTER) and more than before if_wm.c rev. 1.75's
   value (40)) because we do m_defrag() now.

  Fix comment.

diffstat:

 sys/dev/pci/if_wm.c |  202 ++++++++++++++++++++++++++++++---------------------
 1 files changed, 119 insertions(+), 83 deletions(-)

diffs (truncated from 459 to 300 lines):

diff -r 758872824afd -r fe7ca89d6919 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Sun Sep 23 17:35:33 2018 +0000
+++ b/sys/dev/pci/if_wm.c       Sun Sep 23 17:39:02 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.508.4.22 2018/08/11 14:47:31 martin Exp $  */
+/*     $NetBSD: if_wm.c,v 1.508.4.23 2018/09/23 17:39:02 martin Exp $  */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -83,7 +83,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.22 2018/08/11 14:47:31 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.23 2018/09/23 17:39:02 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -197,11 +197,12 @@
  * of packets, and we go ahead and manage up to 64 (16 for the i82547)
  * of them at a time.
  *
- * We allow up to 256 (!) DMA segments per packet.  Pathological packet
+ * We allow up to 64 DMA segments per packet.  Pathological packet
  * chains containing many small mbufs have been observed in zero-copy
- * situations with jumbo frames.
- */
-#define        WM_NTXSEGS              256
+ * situations with jumbo frames. If a mbuf chain has more than 64 DMA segments,
+ * m_defrag() is called to reduce it.
+ */
+#define        WM_NTXSEGS              64
 #define        WM_IFQUEUELEN           256
 #define        WM_TXQUEUELEN_MAX       64
 #define        WM_TXQUEUELEN_MAX_82547 16
@@ -376,23 +377,27 @@
        uint32_t txq_packets;           /* for AIM */
        uint32_t txq_bytes;             /* for AIM */
 #ifdef WM_EVENT_COUNTERS
-       WM_Q_EVCNT_DEFINE(txq, txsstall)        /* Tx stalled due to no txs */
-       WM_Q_EVCNT_DEFINE(txq, txdstall)        /* Tx stalled due to no txd */
-       WM_Q_EVCNT_DEFINE(txq, txfifo_stall)    /* Tx FIFO stalls (82547) */
-       WM_Q_EVCNT_DEFINE(txq, txdw)            /* Tx descriptor interrupts */
-       WM_Q_EVCNT_DEFINE(txq, txqe)            /* Tx queue empty interrupts */
-                                               /* XXX not used? */
-
-       WM_Q_EVCNT_DEFINE(txq, txipsum)         /* IP checksums comp. out-bound */
-       WM_Q_EVCNT_DEFINE(txq, txtusum)         /* TCP/UDP cksums comp. out-bound */
-       WM_Q_EVCNT_DEFINE(txq, txtusum6)        /* TCP/UDP v6 cksums comp. out-bound */
-       WM_Q_EVCNT_DEFINE(txq, txtso)           /* TCP seg offload out-bound (IPv4) */
-       WM_Q_EVCNT_DEFINE(txq, txtso6)          /* TCP seg offload out-bound (IPv6) */
-       WM_Q_EVCNT_DEFINE(txq, txtsopain)       /* painful header manip. for TSO */
-
-       WM_Q_EVCNT_DEFINE(txq, txdrop)          /* Tx packets dropped(too many segs) */
-
-       WM_Q_EVCNT_DEFINE(txq, tu)              /* Tx underrun */
+       /* TX event counters */
+       WM_Q_EVCNT_DEFINE(txq, txsstall)    /* Stalled due to no txs */
+       WM_Q_EVCNT_DEFINE(txq, txdstall)    /* Stalled due to no txd */
+       WM_Q_EVCNT_DEFINE(txq, fifo_stall)  /* FIFO stalls (82547) */
+       WM_Q_EVCNT_DEFINE(txq, txdw)        /* Tx descriptor interrupts */
+       WM_Q_EVCNT_DEFINE(txq, txqe)        /* Tx queue empty interrupts */
+                                           /* XXX not used? */
+
+       WM_Q_EVCNT_DEFINE(txq, ipsum)       /* IP checksums comp. */
+       WM_Q_EVCNT_DEFINE(txq, tusum)       /* TCP/UDP cksums comp. */
+       WM_Q_EVCNT_DEFINE(txq, tusum6)      /* TCP/UDP v6 cksums comp. */
+       WM_Q_EVCNT_DEFINE(txq, tso)         /* TCP seg offload (IPv4) */
+       WM_Q_EVCNT_DEFINE(txq, tso6)        /* TCP seg offload (IPv6) */
+       WM_Q_EVCNT_DEFINE(txq, tsopain)     /* Painful header manip. for TSO */
+       WM_Q_EVCNT_DEFINE(txq, pcqdrop)     /* Pkt dropped in pcq */
+       WM_Q_EVCNT_DEFINE(txq, descdrop)    /* Pkt dropped in MAC desc ring */
+                                           /* other than toomanyseg */
+
+       WM_Q_EVCNT_DEFINE(txq, toomanyseg)  /* Pkt dropped(toomany DMA segs) */
+       WM_Q_EVCNT_DEFINE(txq, defrag)      /* m_defrag() */
+       WM_Q_EVCNT_DEFINE(txq, underrun)    /* Tx underrun */
 
        char txq_txseg_evcnt_names[WM_NTXSEGS][sizeof("txqXXtxsegXXX")];
        struct evcnt txq_ev_txseg[WM_NTXSEGS]; /* Tx packets w/ N segments */
@@ -433,11 +438,12 @@
        uint32_t rxq_packets;           /* for AIM */
        uint32_t rxq_bytes;             /* for AIM */
 #ifdef WM_EVENT_COUNTERS
-       WM_Q_EVCNT_DEFINE(rxq, rxintr);         /* Rx interrupts */
-       WM_Q_EVCNT_DEFINE(rxq, rxdefer);        /* Rx deferred processing */
-
-       WM_Q_EVCNT_DEFINE(rxq, rxipsum);        /* IP checksums checked in-bound */
-       WM_Q_EVCNT_DEFINE(rxq, rxtusum);        /* TCP/UDP cksums checked in-bound */
+       /* RX event counters */
+       WM_Q_EVCNT_DEFINE(rxq, intr);   /* Interrupts */
+       WM_Q_EVCNT_DEFINE(rxq, defer);  /* Rx deferred processing */
+
+       WM_Q_EVCNT_DEFINE(rxq, ipsum);  /* IP checksums checked */
+       WM_Q_EVCNT_DEFINE(rxq, tusum);  /* TCP/UDP cksums checked */
 #endif
 };
 
@@ -6451,16 +6457,15 @@
 
                WM_Q_MISC_EVCNT_ATTACH(txq, txsstall, txq, i, xname);
                WM_Q_MISC_EVCNT_ATTACH(txq, txdstall, txq, i, xname);
-               WM_Q_MISC_EVCNT_ATTACH(txq, txfifo_stall, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, fifo_stall, txq, i, xname);
                WM_Q_INTR_EVCNT_ATTACH(txq, txdw, txq, i, xname);
                WM_Q_INTR_EVCNT_ATTACH(txq, txqe, txq, i, xname);
-
-               WM_Q_MISC_EVCNT_ATTACH(txq, txipsum, txq, i, xname);
-               WM_Q_MISC_EVCNT_ATTACH(txq, txtusum, txq, i, xname);
-               WM_Q_MISC_EVCNT_ATTACH(txq, txtusum6, txq, i, xname);
-               WM_Q_MISC_EVCNT_ATTACH(txq, txtso, txq, i, xname);
-               WM_Q_MISC_EVCNT_ATTACH(txq, txtso6, txq, i, xname);
-               WM_Q_MISC_EVCNT_ATTACH(txq, txtsopain, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, ipsum, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, tusum, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, tusum6, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, tso, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, tso6, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, tsopain, txq, i, xname);
 
                for (j = 0; j < WM_NTXSEGS; j++) {
                        snprintf(txq->txq_txseg_evcnt_names[j],
@@ -6469,9 +6474,11 @@
                            NULL, xname, txq->txq_txseg_evcnt_names[j]);
                }
 
-               WM_Q_MISC_EVCNT_ATTACH(txq, txdrop, txq, i, xname);
-
-               WM_Q_MISC_EVCNT_ATTACH(txq, tu, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, pcqdrop, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, descdrop, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, toomanyseg, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, defrag, txq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(txq, underrun, txq, i, xname);
 #endif /* WM_EVENT_COUNTERS */
 
                tx_done++;
@@ -6505,11 +6512,11 @@
 #ifdef WM_EVENT_COUNTERS
                xname = device_xname(sc->sc_dev);
 
-               WM_Q_INTR_EVCNT_ATTACH(rxq, rxintr, rxq, i, xname);
-               WM_Q_INTR_EVCNT_ATTACH(rxq, rxdefer, rxq, i, xname);
-
-               WM_Q_MISC_EVCNT_ATTACH(rxq, rxipsum, rxq, i, xname);
-               WM_Q_MISC_EVCNT_ATTACH(rxq, rxtusum, rxq, i, xname);
+               WM_Q_INTR_EVCNT_ATTACH(rxq, intr, rxq, i, xname);
+               WM_Q_INTR_EVCNT_ATTACH(rxq, defer, rxq, i, xname);
+
+               WM_Q_MISC_EVCNT_ATTACH(rxq, ipsum, rxq, i, xname);
+               WM_Q_MISC_EVCNT_ATTACH(rxq, tusum, rxq, i, xname);
 #endif /* WM_EVENT_COUNTERS */
 
                rx_done++;
@@ -6556,10 +6563,10 @@
                struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq;
 
 #ifdef WM_EVENT_COUNTERS
-               WM_Q_EVCNT_DETACH(rxq, rxintr, rxq, i);
-               WM_Q_EVCNT_DETACH(rxq, rxdefer, rxq, i);
-               WM_Q_EVCNT_DETACH(rxq, rxipsum, rxq, i);
-               WM_Q_EVCNT_DETACH(rxq, rxtusum, rxq, i);
+               WM_Q_EVCNT_DETACH(rxq, intr, rxq, i);
+               WM_Q_EVCNT_DETACH(rxq, defer, rxq, i);
+               WM_Q_EVCNT_DETACH(rxq, ipsum, rxq, i);
+               WM_Q_EVCNT_DETACH(rxq, tusum, rxq, i);
 #endif /* WM_EVENT_COUNTERS */
 
                wm_free_rx_buffer(sc, rxq);
@@ -6576,21 +6583,24 @@
 
                WM_Q_EVCNT_DETACH(txq, txsstall, txq, i);
                WM_Q_EVCNT_DETACH(txq, txdstall, txq, i);
-               WM_Q_EVCNT_DETACH(txq, txfifo_stall, txq, i);
+               WM_Q_EVCNT_DETACH(txq, fifo_stall, txq, i);
                WM_Q_EVCNT_DETACH(txq, txdw, txq, i);
                WM_Q_EVCNT_DETACH(txq, txqe, txq, i);
-               WM_Q_EVCNT_DETACH(txq, txipsum, txq, i);
-               WM_Q_EVCNT_DETACH(txq, txtusum, txq, i);
-               WM_Q_EVCNT_DETACH(txq, txtusum6, txq, i);
-               WM_Q_EVCNT_DETACH(txq, txtso, txq, i);
-               WM_Q_EVCNT_DETACH(txq, txtso6, txq, i);
-               WM_Q_EVCNT_DETACH(txq, txtsopain, txq, i);
+               WM_Q_EVCNT_DETACH(txq, ipsum, txq, i);
+               WM_Q_EVCNT_DETACH(txq, tusum, txq, i);
+               WM_Q_EVCNT_DETACH(txq, tusum6, txq, i);
+               WM_Q_EVCNT_DETACH(txq, tso, txq, i);
+               WM_Q_EVCNT_DETACH(txq, tso6, txq, i);
+               WM_Q_EVCNT_DETACH(txq, tsopain, txq, i);
 
                for (j = 0; j < WM_NTXSEGS; j++)
                        evcnt_detach(&txq->txq_ev_txseg[j]);
 
-               WM_Q_EVCNT_DETACH(txq, txdrop, txq, i);
-               WM_Q_EVCNT_DETACH(txq, tu, txq, i);
+               WM_Q_EVCNT_DETACH(txq, pcqdrop, txq, i);
+               WM_Q_EVCNT_DETACH(txq, descdrop, txq, i);
+               WM_Q_EVCNT_DETACH(txq, toomanyseg, txq, i);
+               WM_Q_EVCNT_DETACH(txq, defrag, txq, i);
+               WM_Q_EVCNT_DETACH(txq, underrun, txq, i);
 #endif /* WM_EVENT_COUNTERS */
 
                /* drain txq_interq */
@@ -6939,7 +6949,7 @@
                         */
                        struct tcphdr th;
 
-                       WM_Q_EVCNT_INCR(txq, txtsopain);
+                       WM_Q_EVCNT_INCR(txq, tsopain);
 
                        m_copydata(m0, hlen, sizeof(th), &th);
                        if (v4) {
@@ -6995,10 +7005,10 @@
                }
 
                if (v4) {
-                       WM_Q_EVCNT_INCR(txq, txtso);
+                       WM_Q_EVCNT_INCR(txq, tso);
                        cmdlen |= WTX_TCPIP_CMD_IP;
                } else {
-                       WM_Q_EVCNT_INCR(txq, txtso6);
+                       WM_Q_EVCNT_INCR(txq, tso6);
                        ipcse = 0;
                }
                cmd |= WTX_TCPIP_CMD_TSE;
@@ -7018,7 +7028,7 @@
            WTX_TCPIP_IPCSO(offset + offsetof(struct ip, ip_sum)) |
            WTX_TCPIP_IPCSE(ipcse);
        if (m0->m_pkthdr.csum_flags & (M_CSUM_IPv4 | M_CSUM_TSOv4)) {
-               WM_Q_EVCNT_INCR(txq, txipsum);
+               WM_Q_EVCNT_INCR(txq, ipsum);
                fields |= WTX_IXSM;
        }
 
@@ -7026,7 +7036,7 @@
 
        if (m0->m_pkthdr.csum_flags &
            (M_CSUM_TCPv4 | M_CSUM_UDPv4 | M_CSUM_TSOv4)) {
-               WM_Q_EVCNT_INCR(txq, txtusum);
+               WM_Q_EVCNT_INCR(txq, tusum);
                fields |= WTX_TXSM;
                tucs = WTX_TCPIP_TUCSS(offset) |
                    WTX_TCPIP_TUCSO(offset +
@@ -7034,7 +7044,7 @@
                    WTX_TCPIP_TUCSE(0) /* rest of packet */;
        } else if ((m0->m_pkthdr.csum_flags &
            (M_CSUM_TCPv6 | M_CSUM_UDPv6 | M_CSUM_TSOv6)) != 0) {
-               WM_Q_EVCNT_INCR(txq, txtusum6);
+               WM_Q_EVCNT_INCR(txq, tusum6);
                fields |= WTX_TXSM;
                tucs = WTX_TCPIP_TUCSS(offset) |
                    WTX_TCPIP_TUCSO(offset +
@@ -7131,7 +7141,7 @@
 
        if (__predict_false(!pcq_put(txq->txq_interq, m))) {
                m_freem(m);
-               WM_Q_EVCNT_INCR(txq, txdrop);
+               WM_Q_EVCNT_INCR(txq, pcqdrop);
                return ENOBUFS;
        }
 
@@ -7171,6 +7181,7 @@
        bus_size_t seglen, curlen;
        uint32_t cksumcmd;
        uint8_t cksumfields;
+       bool remap = true;
 
        KASSERT(mutex_owned(txq->txq_lock));
 
@@ -7244,11 +7255,23 @@
                 * since we can't sanely copy a jumbo packet to a single
                 * buffer.
                 */
+retry:
                error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
                    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
-               if (error) {
+               if (__predict_false(error)) {
                        if (error == EFBIG) {
-                               WM_Q_EVCNT_INCR(txq, txdrop);
+                               if (remap == true) {
+                                       struct mbuf *m;
+
+                                       remap = false;
+                                       m = m_defrag(m0, M_NOWAIT);
+                                       if (m != NULL) {
+                                               WM_Q_EVCNT_INCR(txq, defrag);
+                                               m0 = m;
+                                               goto retry;
+                                       }
+                               }
+                               WM_Q_EVCNT_INCR(txq, toomanyseg);
                                log(LOG_ERR, "%s: Tx packet consumes too many "
                                    "DMA segments, dropping...\n",
                                    device_xname(sc->sc_dev));
@@ -7310,7 +7333,7 @@
                                ifp->if_flags |= IFF_OACTIVE;
                        txq->txq_flags |= WM_TXQ_NO_SPACE;
                        bus_dmamap_unload(sc->sc_dmat, dmamap);
-                       WM_Q_EVCNT_INCR(txq, txfifo_stall);



Home | Main Index | Thread Index | Old Index