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/ixgbe Pull up following revision(s) (requeste...



details:   https://anonhg.NetBSD.org/src/rev/768c7c76cb47
branches:  netbsd-8
changeset: 319744:768c7c76cb47
user:      martin <martin%NetBSD.org@localhost>
date:      Sat Jun 09 14:59:43 2018 +0000

description:
Pull up following revision(s) (requested by msaitoh in ticket #864):

        sys/dev/pci/ixgbe/ix_txrx.c                     1.40-1.47 (patch)
        sys/dev/pci/ixgbe/ixgbe.c                       1.148,1.149,1.151,
                                                        1.152,1.154,
                                                        1.155,1.157-1.160 (patch)
        sys/dev/pci/ixgbe/ixgbe.h                       1.43,1.44,1.46,1.49 (patch)
        sys/dev/pci/ixgbe/ixgbe_netbsd.c                1.7 (patch)
        sys/dev/pci/ixgbe/ixgbe_netbsd.h                1.8 (patch)
        sys/dev/pci/ixgbe/ixgbe_osdep.h                 1.22 (patch)
        sys/dev/pci/ixgbe/ixv.c                         1.100-1.104 (patch)
        sys/dev/pci/ixgbe/ixv.c                         1.94,1.95,1.99 (patch)

 Remove unused structure entries. No functional change.
 -
 Remove unused IXGBE_FC_HI and IXGBE_FC_LO. The watermark of the flow control
is automatically calculated from the size of the packet buffer.
 -
 Use ixgbe_eitr_write() when writing the EITR for the link interrupt like
queue's EITR to write the register safely. This change is not relatively
so important than queue's EITR because link's EITR is written in if_init().
 -
 Don't free and reallocate bus_dmamem when it's not required. Currently,
the watchdog timer is completely broken and never fire (it's from FreeBSD
(pre iflib)). If the problem is fixed and watchdog fired, ixgbe_init() always
calls ixgbe_jcl_reinit() and it causes panic. The reason is that
ixgbe_local_timer1(it includes watchdog function) is softint and
xgbe_jcl_reinit() calls bus_dmamem*() functions. bus_dmamem*() can't be called
from interrupt context.

 One of the way to prevent panic is use worqueue for the timer, but it's
not a small change. (I'll do it in future).

 Another way is not reallocate dmamem if it's not required. If both the MTU
(rx_mbuf_sz in reality) and the number of RX descriptors are not changed, it's
not required to call bus_dmamem_{unmap,free}(). Even if we use workque, this
change save time of ixgbe_init().

 I have a code to fix broken watchdog timer but it sometime causes watchdog
timeout, so I don't commit it yet.
 -
Count some register correctly:
- QPRDC register is only for 82599 and newer.
- Count IXGBE_QPRDC, PX{ON,OFF}{T,R}XC[NT].
 The TQSMR register is not for receiving but for transmitting, so move the
initialization from ixgbe_initialize_receive_units() to
ixgbe_initialize_transmit_units(). No functional change.
 -
 Whitespace fix. No functional change.
 -
 Add rxd_nxck (Receive Descriptor next to check) read only sysctl.
 Don't check IFF_RUNNING in ixgbe_rxeof(). Doing break and leaving a deacriptor
with DD bit is worse than just processing the entry. And it's also racy to
check IFF_RUNNING in rxeof(). If you'd like to strictly obey IFF_RUNNING,
it would be better to do it in the upper layer.
 Same as DragonFly (a part of 79251f5ebe4cf9dd2f3e6aed590e09d756d39922).
 Add "bool txr_no_space" for TX descriptor shortage. Use it like IFF_OACTIVE.
 Clear que->disabled_count in {ixgbe,ixv}_init_locked(). Without this,
interrupt mask state and EIMS may mismatch and if_init doesn't recover
from TX/RX stall problem.
 This change itself doesn't fix PR#53294.
 -
 Add hw.ixgN.debug sysctl. "sysctl -w hw.ixgN.debug=1" dumps some registers
to console.
 -
Constify several variables in ixgbe/ so that they land in .rodata (1038
bytes).
 -
 Don't call ixgbe_rearm_queues() in ixgbe_local_timer1().
   ixgbe_enable_queue() and ixgbe_disable_queue() try to enable/disable queue
  interrupt safely. It has the internal counter. When a queue's MSI-X is
  received, ixgbe_msix_que() is called (IPL_NET). This function disable the
  queue's interrupt by ixgbe_disable_queue() and issues an softint.
  ixgbe_handle() queue is called by the softint (IPL_SOFTNET), process TX, RX
  and call ixgbe_enable_queue() at the end.

   ixgbe_local_timer1() is a callout and run always on CPU 0 (IPL_SOFTCLOCK).
  When ixgbe_rearm_queues() called, an MSI-X interrupt is issued for a specific
  queue. It may not CPU 0. If this interrupt's ixgbe_msix_que() is called and
  sofint_schedule() is called before the last sofint's softint_execute() is not
  called, the softint_schedule() fails because of SOFTINT_PENDING. It result
  in breaking ixgbe_{enable,disable}_queue()'s internal counter.
   ixgbe_local_timer1() is written not to call ixgbe_rearm_queues() if
  the interrupt is disabled, but it's called because of unknown bug or a race.

  One solution to avoid this problem is to not to use the internal counter,
  but it's little difficult. Another solution is stop using
  ixgbe_rearm_queues() at all. Essentially, ixgbe_rearm_queues() is not
  required (it was added in ixgbe.c rev. 1.43 (2016/12/01)).
  ixgbe_rearm_queues() helps for lost interrupt problem but I've never seen it
  other than ixgbe_rearm_queues() problem.

XXX pullup-8.

diffstat:

 sys/dev/pci/ixgbe/ix_txrx.c      |   53 ++++---
 sys/dev/pci/ixgbe/ixgbe.c        |  273 ++++++++++++++++++++++++++++++++------
 sys/dev/pci/ixgbe/ixgbe.h        |   28 +--
 sys/dev/pci/ixgbe/ixgbe_netbsd.c |   25 +++-
 sys/dev/pci/ixgbe/ixgbe_netbsd.h |    3 +-
 sys/dev/pci/ixgbe/ixgbe_osdep.h  |    4 +-
 sys/dev/pci/ixgbe/ixv.c          |   70 +++++++--
 7 files changed, 346 insertions(+), 110 deletions(-)

diffs (truncated from 1140 to 300 lines):

diff -r 2e90e1266ebe -r 768c7c76cb47 sys/dev/pci/ixgbe/ix_txrx.c
--- a/sys/dev/pci/ixgbe/ix_txrx.c       Sat Jun 09 14:47:37 2018 +0000
+++ b/sys/dev/pci/ixgbe/ix_txrx.c       Sat Jun 09 14:59:43 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.24.2.10 2018/04/14 10:25:11 martin Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.24.2.11 2018/06/09 14:59:43 martin Exp $ */
 
 /******************************************************************************
 
@@ -146,7 +146,9 @@
        }
        if ((ifp->if_flags & IFF_RUNNING) == 0)
                return (ENETDOWN);
-
+       if (txr->txr_no_space)
+               return (ENETDOWN);
+       
        while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
                if (txr->tx_avail <= IXGBE_QUEUE_MIN_FREE)
                        break;
@@ -247,6 +249,8 @@
                IXGBE_TX_UNLOCK(txr);
        } else {
                if (adapter->txrx_use_workqueue) {
+                       u_int *enqueued;
+
                        /*
                         * This function itself is not called in interrupt
                         * context, however it can be called in fast softint
@@ -255,11 +259,12 @@
                         * enqueuing when the machine uses both spontaneous
                         * packets and forwarding packets.
                         */
-                       u_int *enqueued = percpu_getref(adapter->txr_wq_enqueued);
+                       enqueued = percpu_getref(adapter->txr_wq_enqueued);
                        if (*enqueued == 0) {
                                *enqueued = 1;
                                percpu_putref(adapter->txr_wq_enqueued);
-                               workqueue_enqueue(adapter->txr_wq, &txr->wq_cookie, curcpu());
+                               workqueue_enqueue(adapter->txr_wq,
+                                   &txr->wq_cookie, curcpu());
                        } else
                                percpu_putref(adapter->txr_wq_enqueued);
                } else
@@ -288,6 +293,8 @@
        }
        if ((ifp->if_flags & IFF_RUNNING) == 0)
                return (ENETDOWN);
+       if (txr->txr_no_space)
+               return (ENETDOWN);
 
        /* Process the queue */
        while ((next = pcq_get(txr->txr_interq)) != NULL) {
@@ -458,6 +465,7 @@
 
        /* Make certain there are enough descriptors */
        if (txr->tx_avail < (map->dm_nsegs + 2)) {
+               txr->txr_no_space = true;
                txr->no_desc_avail.ev_count++;
                ixgbe_dmamap_unload(txr->txtag, txbuf->map);
                return EAGAIN;
@@ -494,8 +502,7 @@
                segaddr = htole64(map->dm_segs[j].ds_addr);
 
                txd->read.buffer_addr = segaddr;
-               txd->read.cmd_type_len = htole32(txr->txd_cmd |
-                   cmd_type_len | seglen);
+               txd->read.cmd_type_len = htole32(cmd_type_len | seglen);
                txd->read.olinfo_status = htole32(olinfo_status);
 
                if (++i == txr->num_desc)
@@ -1157,6 +1164,7 @@
                        buf->m_head = NULL;
                }
                buf->eop = NULL;
+               txr->txr_no_space = false;
                ++txr->tx_avail;
 
                /* We clean the range if multi segment */
@@ -1608,7 +1616,7 @@
         * or size of jumbo mbufs may have changed.
         * Assume all of rxr->ptag are the same.
         */
-       ixgbe_jcl_reinit(&adapter->jcl_head, rxr->ptag->dt_dmat,
+       ixgbe_jcl_reinit(adapter, rxr->ptag->dt_dmat,
            (2 * adapter->num_rx_desc) * adapter->num_queues,
            adapter->rx_mbuf_sz);
 
@@ -1831,8 +1839,6 @@
 
                if ((staterr & IXGBE_RXD_STAT_DD) == 0)
                        break;
-               if ((ifp->if_flags & IFF_RUNNING) == 0)
-                       break;
 
                count--;
                sendmp = NULL;
@@ -1970,46 +1976,46 @@
                        if (adapter->num_queues > 1) {
                                sendmp->m_pkthdr.flowid =
                                    le32toh(cur->wb.lower.hi_dword.rss);
-                               switch (pkt_info & IXGBE_RXDADV_RSSTYPE_MASK) {  
-                                   case IXGBE_RXDADV_RSSTYPE_IPV4:
+                               switch (pkt_info & IXGBE_RXDADV_RSSTYPE_MASK) {
+                               case IXGBE_RXDADV_RSSTYPE_IPV4:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_IPV4);
                                        break;
-                                   case IXGBE_RXDADV_RSSTYPE_IPV4_TCP:
+                               case IXGBE_RXDADV_RSSTYPE_IPV4_TCP:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_TCP_IPV4);
                                        break;
-                                   case IXGBE_RXDADV_RSSTYPE_IPV6:
+                               case IXGBE_RXDADV_RSSTYPE_IPV6:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_IPV6);
                                        break;
-                                   case IXGBE_RXDADV_RSSTYPE_IPV6_TCP:
+                               case IXGBE_RXDADV_RSSTYPE_IPV6_TCP:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_TCP_IPV6);
                                        break;
-                                   case IXGBE_RXDADV_RSSTYPE_IPV6_EX:
+                               case IXGBE_RXDADV_RSSTYPE_IPV6_EX:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_IPV6_EX);
                                        break;
-                                   case IXGBE_RXDADV_RSSTYPE_IPV6_TCP_EX:
+                               case IXGBE_RXDADV_RSSTYPE_IPV6_TCP_EX:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_TCP_IPV6_EX);
                                        break;
 #if __FreeBSD_version > 1100000
-                                   case IXGBE_RXDADV_RSSTYPE_IPV4_UDP:
+                               case IXGBE_RXDADV_RSSTYPE_IPV4_UDP:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_UDP_IPV4);
                                        break;
-                                   case IXGBE_RXDADV_RSSTYPE_IPV6_UDP:
+                               case IXGBE_RXDADV_RSSTYPE_IPV6_UDP:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_UDP_IPV6);
                                        break;
-                                   case IXGBE_RXDADV_RSSTYPE_IPV6_UDP_EX:
+                               case IXGBE_RXDADV_RSSTYPE_IPV6_UDP_EX:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_RSS_UDP_IPV6_EX);
                                        break;
 #endif
-                                   default:
+                               default:
                                        M_HASHTYPE_SET(sendmp,
                                            M_HASHTYPE_OPAQUE_HASH);
                                }
@@ -2134,7 +2140,8 @@
                               &dma->dma_tag);
        if (r != 0) {
                aprint_error_dev(dev,
-                   "%s: ixgbe_dma_tag_create failed; error %d\n", __func__, r);
+                   "%s: ixgbe_dma_tag_create failed; error %d\n", __func__,
+                   r);
                goto fail_0;
        }
 
@@ -2266,8 +2273,6 @@
                txr->num_desc = adapter->num_tx_desc;
 
                /* Initialize the TX side lock */
-               snprintf(txr->mtx_name, sizeof(txr->mtx_name), "%s:tx(%d)",
-                   device_xname(dev), txr->me);
                mutex_init(&txr->tx_mtx, MUTEX_DEFAULT, IPL_NET);
 
                if (ixgbe_dma_malloc(adapter, tsize, &txr->txdma,
@@ -2318,8 +2323,6 @@
                rxr->num_desc = adapter->num_rx_desc;
 
                /* Initialize the RX side lock */
-               snprintf(rxr->mtx_name, sizeof(rxr->mtx_name), "%s:rx(%d)",
-                   device_xname(dev), rxr->me);
                mutex_init(&rxr->rx_mtx, MUTEX_DEFAULT, IPL_NET);
 
                if (ixgbe_dma_malloc(adapter, rsize, &rxr->rxdma,
diff -r 2e90e1266ebe -r 768c7c76cb47 sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Sat Jun 09 14:47:37 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Sat Jun 09 14:59:43 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.88.2.19 2018/06/07 17:42:24 martin Exp $ */
+/* $NetBSD: ixgbe.c,v 1.88.2.20 2018/06/09 14:59:43 martin Exp $ */
 
 /******************************************************************************
 
@@ -80,7 +80,7 @@
 /************************************************************************
  * Driver version
  ************************************************************************/
-char ixgbe_driver_version[] = "4.0.1-k";
+static const char ixgbe_driver_version[] = "4.0.1-k";
 
 
 /************************************************************************
@@ -92,7 +92,7 @@
  *
  *   { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
  ************************************************************************/
-static ixgbe_vendor_info_t ixgbe_vendor_info_array[] =
+static const ixgbe_vendor_info_t ixgbe_vendor_info_array[] =
 {
        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_DUAL_PORT, 0, 0, 0},
        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_SINGLE_PORT, 0, 0, 0},
@@ -208,7 +208,7 @@
 static void    ixgbe_set_ivar(struct adapter *, u8, u8, s8);
 static void    ixgbe_configure_ivars(struct adapter *);
 static u8 *    ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
-static void    ixgbe_eitr_write(struct ix_queue *, uint32_t);
+static void    ixgbe_eitr_write(struct adapter *, uint32_t, uint32_t);
 
 static void    ixgbe_setup_vlan_hw_support(struct adapter *);
 #if 0
@@ -236,11 +236,13 @@
 static int     ixgbe_sysctl_power_state(SYSCTLFN_PROTO);
 static int     ixgbe_sysctl_print_rss_config(SYSCTLFN_PROTO);
 #endif
+static int      ixgbe_sysctl_next_to_check_handler(SYSCTLFN_PROTO);
 static int      ixgbe_sysctl_rdh_handler(SYSCTLFN_PROTO);
 static int      ixgbe_sysctl_rdt_handler(SYSCTLFN_PROTO);
 static int      ixgbe_sysctl_tdt_handler(SYSCTLFN_PROTO);
 static int      ixgbe_sysctl_tdh_handler(SYSCTLFN_PROTO);
 static int      ixgbe_sysctl_eee_state(SYSCTLFN_PROTO);
+static int     ixgbe_sysctl_debug(SYSCTLFN_PROTO);
 static int     ixgbe_sysctl_wol_enable(SYSCTLFN_PROTO);
 static int     ixgbe_sysctl_wufc(SYSCTLFN_PROTO);
 
@@ -264,7 +266,7 @@
 /* Workqueue handler for deferred work */
 static void    ixgbe_handle_que_work(struct work *, void *);
 
-static ixgbe_vendor_info_t *ixgbe_lookup(const struct pci_attach_args *);
+static const ixgbe_vendor_info_t *ixgbe_lookup(const struct pci_attach_args *);
 
 /************************************************************************
  *  NetBSD Device Interface Entry Points
@@ -581,7 +583,7 @@
 
        for (i = 0; i < adapter->num_queues; i++, rxr++) {
                u64 rdba = rxr->rxdma.dma_paddr;
-               u32 tqsmreg, reg;
+               u32 reg;
                int regnum = i / 4;     /* 1 register per 4 queues */
                int regshift = i % 4;   /* 4 bits per 1 queue */
                j = rxr->me;
@@ -607,20 +609,6 @@
                IXGBE_WRITE_REG(hw, IXGBE_RQSMR(regnum), reg);
 
                /*
-                * Set RQSMR (Receive Queue Statistic Mapping) register.
-                * Register location for queue 0...7 are different between
-                * 82598 and newer.
-                */
-               if (adapter->hw.mac.type == ixgbe_mac_82598EB)
-                       tqsmreg = IXGBE_TQSMR(regnum);
-               else
-                       tqsmreg = IXGBE_TQSM(regnum);
-               reg = IXGBE_READ_REG(hw, tqsmreg);
-               reg &= ~(0x000000ff << (regshift * 8));
-               reg |= i << (regshift * 8);
-               IXGBE_WRITE_REG(hw, tqsmreg, reg);
-
-               /*
                 * Set DROP_EN iff we have no flow control and >1 queue.
                 * Note that srrctl was cleared shortly before during reset,
                 * so we do not need to clear the bit, but do it just in case
@@ -685,6 +673,9 @@
        for (i = 0; i < adapter->num_queues; i++, txr++) {
                u64 tdba = txr->txdma.dma_paddr;
                u32 txctrl = 0;
+               u32 tqsmreg, reg;
+               int regnum = i / 4;     /* 1 register per 4 queues */
+               int regshift = i % 4;   /* 4 bits per 1 queue */
                int j = txr->me;
 
                IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
@@ -693,6 +684,19 @@
                IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j),
                    adapter->num_tx_desc * sizeof(union ixgbe_adv_tx_desc));
 
+               /*
+                * Set TQSMR (Transmit Queue Statistic Mapping) register.
+                * Register location is different between 82598 and others.
+                */
+               if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+                       tqsmreg = IXGBE_TQSMR(regnum);
+               else
+                       tqsmreg = IXGBE_TQSM(regnum);
+               reg = IXGBE_READ_REG(hw, tqsmreg);
+               reg &= ~(0x000000ff << (regshift * 8));
+               reg |= i << (regshift * 8);
+               IXGBE_WRITE_REG(hw, tqsmreg, reg);
+
                /* Setup the HW Tx Head and Tail descriptor pointers */



Home | Main Index | Thread Index | Old Index