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/3510e86539e6
branches:  netbsd-8
changeset: 851424:3510e86539e6
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Feb 26 13:55:54 2018 +0000

description:
Pull up following revision(s) (requested by msaitoh in ticket #592):
        sys/dev/pci/ixgbe/ixv.c: revision 1.79
        sys/dev/pci/ixgbe/ixgbe.h: revision 1.30
        sys/dev/pci/ixgbe/ix_txrx.c: revision 1.31
        sys/dev/pci/ixgbe/ix_txrx.c: revision 1.32
        sys/dev/pci/ixgbe/ixgbe_type.h: revision 1.31
        sys/dev/pci/ixgbe/ixgbe.c: revision 1.120
        sys/dev/pci/ixgbe/ixgbe.c: revision 1.121
        sys/dev/pci/ixgbe/ixgbe.c: revision 1.123
        sys/dev/pci/ixgbe/ixgbe.c: revision 1.124
        sys/dev/pci/ixgbe/ixgbe.c: revision 1.125
        sys/dev/pci/ixgbe/ixgbe.c: revision 1.126
        sys/dev/pci/ixgbe/ixv.c: revision 1.80
        sys/dev/pci/ixgbe/ixv.c: revision 1.81
 CID-1427719: Integer handling issues  (BAD_SHIFT). Print bus/slot info
correctly on 82599_SFP_SF_QP(DID 0x154a) and 82599_QSFP_SF_QP(DID 0x1558).
 Fix a bug that RX may stall on heavy load on ixg(4). ixgbe_rxeof() has loop
limit and the function returns true if a packet are still in the RX ring.
ixgbe_handle_que() didn't check the return value. Check the return vaule
and issue a softint.
 This bug is derived from FreeBSD and ixv(4) has no this bug.
XXX pullup-8
 Fix a bug that the first call of ifflags_cb() causes linkdown. The first
call of ix(gbe|v)_ifflags_cb() refered uninitialized adapter->if_flags.
adapter->if_flags should be initialized in the end of xxx_init().
XXX pullup-[678] (ixgbe)
XXX pullup-8 (ixv)
- Fix a bug that RX may stall on heavy load on ixg(4) derived from FreeBSD's
 AIM (Auto Interrupt Moderation) bug.
 When I use a machine as a NFS client, sometimes one of queue pairs doesn't
 get any interrupt other than every second tick via ixgbe_local_timer1().
 When the problem occured, the queue pair's hw.ixgM.qN.interrupt_rate is
 always 500000. When this problem occuring, set hw.ixgM.qN.interrupt_rate lower
 than 166667 recover from stall. i.e.:
  sysctl -w hw.ixgM.qN.interrupt_rate=166667 (don't revocer)
  sysctl -w hw.ixgM.qN.interrupt_rate=166666 (recover)
  Relatios between the interrupt_rate and EICR's ITR_INTERVAL field is as
 follows:
 int_rate | EICR[11:0]   | interval in us | recover |
          |(ITR_INTERVAL)| (10G and 1G)   |         |
 ---------+--------------+----------------+---------+
   500000 | 0x008(0)     |              2 |     not |
   166667 | 0x010(1)     |              4 |     not |
   166666 | 0x018(2)     |              6 | recover |
  The reason why int_rate becomes 500000 is that xgbe_tx_eof() doesn't
 increment rxr->packets(*1). Even if we fix rxr->packets' bug, interrupt_rate
 might become greater than 166666 and it might cause stall.
  While reading datasheets, knakahara noticed a section titled with "ITR
 Affect on RSC Functionality". It says "When RSC is enabled on specific RX
 queues, the associated ITR interval with these queus must be enabled and must
 be larger (in time uints) than RSC delay". Currently, RSC_DELAY field in the
 GPIE register is 0 and it means 4us for 10G and 1G. The greater ITR_INTERVAL
 value of 4us is 6us == 166666. Yes, BINGO!
  This description is noted in 82599 and newer datasheets and not in 82598
 datasheet. I don't know if 82598 has this limitation but, I apply this
 limitation all of chips.
 (*1) Note that this bug is going to be fixed in the next commit to distinct
 between two different bugs.
- The bitfield of EITR register is different between 82598 and others.
 Only ixgbe_msix_que() taken care of it. Make new function ixgbe_eitr_write()
 and use it in all of functions which modify ITR_INTERVAL.
XXX pullup-8
 Increment rxr->packets correctly in ixgbe_rxeof() to calculate ITR value
of AIM (Auto Interrupt Moderation) correctly. See also ixgbe.c rev. 1.124.
XXX pullup-8
Improve a comment about reading EICS register defined write-only by spec.
It seems that is workaround for silicon errata.
ok by msaitoh@n.o.
- Apply ixgbe.c rev. 1.124 to ixv.c. Fix a bug that RX may stall on heavy load
 on ixv(4) derived from FreeBSD's AIM (Auto Interrupt Moderation) bug.
 ITR_INTERVAL value must be larger than 4us.
- The bitfield of EITR register is different between 82598 and others.
 ixv.c had a bug that it accessed 82598's way even though only 82599 and
 newer support virtual function. Fix it using with new ixv_eitr_write()
 function.
 Fix a potential bug that TX/RX might stall when TX rate limit reached.
This change is almost the same as the RX rate limit bug fix in ixgbe.c
rev. 1.121. I've never got any stall, but this must be a bug.

diffstat:

 sys/dev/pci/ixgbe/ix_txrx.c    |  11 ++--
 sys/dev/pci/ixgbe/ixgbe.c      |  87 ++++++++++++++++++++++++++++++++---------
 sys/dev/pci/ixgbe/ixgbe.h      |   4 +-
 sys/dev/pci/ixgbe/ixgbe_type.h |   7 ++-
 sys/dev/pci/ixgbe/ixv.c        |  43 +++++++++++++++++---
 5 files changed, 117 insertions(+), 35 deletions(-)

diffs (truncated from 383 to 300 lines):

diff -r 57bbbbeb6257 -r 3510e86539e6 sys/dev/pci/ixgbe/ix_txrx.c
--- a/sys/dev/pci/ixgbe/ix_txrx.c       Mon Feb 26 13:52:00 2018 +0000
+++ b/sys/dev/pci/ixgbe/ix_txrx.c       Mon Feb 26 13:55:54 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.24.2.3 2017/12/21 19:28:54 snj Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.24.2.4 2018/02/26 13:55:54 martin Exp $ */
 
 /******************************************************************************
 
@@ -993,7 +993,7 @@
  *   processing the packet then free associated resources. The
  *   tx_buffer is put back on the free queue.
  ************************************************************************/
-void
+bool
 ixgbe_txeof(struct tx_ring *txr)
 {
        struct adapter          *adapter = txr->adapter;
@@ -1032,13 +1032,13 @@
                     txd[kring->nr_kflags].wb.status & IXGBE_TXD_STAT_DD)) {
                        netmap_tx_irq(ifp, txr->me);
                }
-               return;
+               return false;
        }
 #endif /* DEV_NETMAP */
 
        if (txr->tx_avail == txr->num_desc) {
                txr->busy = 0;
-               return;
+               return false;
        }
 
        /* Get work starting point */
@@ -1139,7 +1139,7 @@
        if (txr->tx_avail == txr->num_desc)
                txr->busy = 0;
 
-       return;
+       return ((limit > 0) ? false : true);
 } /* ixgbe_txeof */
 
 /************************************************************************
@@ -1855,6 +1855,7 @@
                        mp->m_next = nbuf->buf;
                } else { /* Sending this frame */
                        m_set_rcvif(sendmp, ifp);
+                       ++rxr->packets;
                        rxr->rx_packets.ev_count++;
                        /* capture data for AIM */
                        rxr->bytes += sendmp->m_pkthdr.len;
diff -r 57bbbbeb6257 -r 3510e86539e6 sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Mon Feb 26 13:52:00 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Mon Feb 26 13:55:54 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.88.2.9 2018/02/26 00:25:16 snj Exp $ */
+/* $NetBSD: ixgbe.c,v 1.88.2.10 2018/02/26 13:55:54 martin Exp $ */
 
 /******************************************************************************
 
@@ -207,6 +207,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_setup_vlan_hw_support(struct adapter *);
 #if 0
@@ -2337,8 +2338,8 @@
        }
        /* ...and read the Link Status Register */
        link = pci_conf_read(adapter->osdep.pc, adapter->osdep.tag,
-           offset + PCIE_LCSR);
-       ixgbe_set_pci_config_data_generic(hw, link >> 16);
+           offset + PCIE_LCSR) >> 16;
+       ixgbe_set_pci_config_data_generic(hw, link);
 
 display:
        device_printf(dev, "PCI Express Bus: Speed %s Width %s\n",
@@ -2465,8 +2466,7 @@
         *    the last interval.
         */
        if (que->eitr_setting)
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(que->msix),
-                   que->eitr_setting);
+               ixgbe_eitr_write(que, que->eitr_setting);
 
        que->eitr_setting = 0;
 
@@ -2489,11 +2489,18 @@
        else
                newitr = (newitr / 2);
 
-        if (adapter->hw.mac.type == ixgbe_mac_82598EB)
-                newitr |= newitr << 16;
-        else
-                newitr |= IXGBE_EITR_CNT_WDIS;
-                 
+       /*
+        * When RSC is used, ITR interval must be larger than RSC_DELAY.
+        * Currently, we use 2us for RSC_DELAY. The minimum value is always
+        * greater than 2us on 100M (and 10M?(not documented)), but it's not
+        * on 1G and higher.
+        */
+       if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
+           && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
+               if (newitr < IXGBE_MIN_RSC_EITR_10G1G)
+                       newitr = IXGBE_MIN_RSC_EITR_10G1G;
+       }
+
         /* save for next interrupt */
         que->eitr_setting = newitr;
 
@@ -2831,6 +2838,12 @@
        IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_OTHER);
 
        /* First get the cause */
+       /*
+        * The specifications of 82598, 82599, X540 and X550 say EICS register
+        * is write only. However, Linux says it is a workaround for silicon
+        * errata to read EICS instead of EICR to get interrupt cause. It seems
+        * there is a problem about read clear mechanism for EICR register.
+        */
        eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
        /* Be sure the queue bits are not cleared */
        eicr &= ~IXGBE_EICR_RTX_QUEUE;
@@ -2933,6 +2946,21 @@
        return 1;
 } /* ixgbe_msix_link */
 
+static void
+ixgbe_eitr_write(struct ix_queue *que, uint32_t itr)
+{
+       struct adapter *adapter = que->adapter;
+       
+        if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+                itr |= itr << 16;
+        else
+                itr |= IXGBE_EITR_CNT_WDIS;
+
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(que->msix),
+           itr);
+}
+
+
 /************************************************************************
  * ixgbe_sysctl_interrupt_rate_handler
  ************************************************************************/
@@ -2941,6 +2969,7 @@
 {
        struct sysctlnode node = *rnode;
        struct ix_queue *que = (struct ix_queue *)node.sysctl_data;
+       struct adapter  *adapter = que->adapter;
        uint32_t reg, usec, rate;
        int error;
 
@@ -2957,14 +2986,26 @@
        if (error || newp == NULL)
                return error;
        reg &= ~0xfff; /* default, no limitation */
-       ixgbe_max_interrupt_rate = 0;
        if (rate > 0 && rate < 500000) {
                if (rate < 1000)
                        rate = 1000;
+               reg |= ((4000000/rate) & 0xff8);
+               /*
+                * When RSC is used, ITR interval must be larger than
+                * RSC_DELAY. Currently, we use 2us for RSC_DELAY.
+                * The minimum value is always greater than 2us on 100M
+                * (and 10M?(not documented)), but it's not on 1G and higher.
+                */
+               if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
+                   && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
+                       if ((adapter->num_queues > 1)
+                           && (reg < IXGBE_MIN_RSC_EITR_10G1G))
+                               return EINVAL;
+               }
                ixgbe_max_interrupt_rate = rate;
-               reg |= ((4000000/rate) & 0xff8);
-       }
-       IXGBE_WRITE_REG(&que->adapter->hw, IXGBE_EITR(que->msix), reg);
+       } else
+               ixgbe_max_interrupt_rate = 0;
+       ixgbe_eitr_write(que, reg);
 
        return (0);
 } /* ixgbe_sysctl_interrupt_rate_handler */
@@ -3779,6 +3820,9 @@
                IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
        }
 
+       /* Update saved flags. See ixgbe_ifflags_cb() */
+       adapter->if_flags = ifp->if_flags;
+
        /* Now inform the stack we're ready */
        ifp->if_flags |= IFF_RUNNING;
 
@@ -3883,7 +3927,7 @@
                /* ... and the TX */
                ixgbe_set_ivar(adapter, txr->me, que->msix, 1);
                /* Set an Initial EITR value */
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(que->msix), newitr);
+               ixgbe_eitr_write(que, newitr);
        }
 
        /* For the Link interrupt */
@@ -5717,13 +5761,14 @@
        struct adapter  *adapter = que->adapter;
        struct tx_ring  *txr = que->txr;
        struct ifnet    *ifp = adapter->ifp;
+       bool            more = false;
 
        adapter->handleq.ev_count++;
 
        if (ifp->if_flags & IFF_RUNNING) {
-               ixgbe_rxeof(que);
+               more = ixgbe_rxeof(que);
                IXGBE_TX_LOCK(txr);
-               ixgbe_txeof(txr);
+               more |= ixgbe_txeof(txr);
                if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX))
                        if (!ixgbe_mq_ring_empty(ifp, txr->txr_interq))
                                ixgbe_mq_start_locked(ifp, txr);
@@ -5735,10 +5780,12 @@
                IXGBE_TX_UNLOCK(txr);
        }
 
-       /* Re-enable this interrupt */
-       if (que->res != NULL)
+       if (more)
+               softint_schedule(que->que_si);
+       else if (que->res != NULL) {
+               /* Re-enable this interrupt */
                ixgbe_enable_queue(adapter, que->msix);
-       else
+       } else
                ixgbe_enable_intr(adapter);
 
        return;
diff -r 57bbbbeb6257 -r 3510e86539e6 sys/dev/pci/ixgbe/ixgbe.h
--- a/sys/dev/pci/ixgbe/ixgbe.h Mon Feb 26 13:52:00 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.h Mon Feb 26 13:55:54 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.24.6.2 2017/12/21 19:28:54 snj Exp $ */
+/* $NetBSD: ixgbe.h,v 1.24.6.3 2018/02/26 13:55:54 martin Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -717,7 +717,7 @@
 void ixgbe_free_transmit_structures(struct adapter *);
 int  ixgbe_setup_receive_structures(struct adapter *);
 void ixgbe_free_receive_structures(struct adapter *);
-void ixgbe_txeof(struct tx_ring *);
+bool ixgbe_txeof(struct tx_ring *);
 bool ixgbe_rxeof(struct ix_queue *);
 
 const struct sysctlnode *ixgbe_sysctl_instance(struct adapter *);
diff -r 57bbbbeb6257 -r 3510e86539e6 sys/dev/pci/ixgbe/ixgbe_type.h
--- a/sys/dev/pci/ixgbe/ixgbe_type.h    Mon Feb 26 13:52:00 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe_type.h    Mon Feb 26 13:55:54 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_type.h,v 1.22.2.2 2017/12/21 19:28:54 snj Exp $ */
+/* $NetBSD: ixgbe_type.h,v 1.22.2.3 2018/02/26 13:55:54 martin Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -312,6 +312,11 @@
  */
 #define IXGBE_MAX_INT_RATE     488281
 #define IXGBE_MIN_INT_RATE     956
+/* On 82599 and newer, minimum RSC_DELAY is 4us. ITR interval must be larger
+ * than RSC_DELAY if RSC is used. ITR_INTERVAL is in 2(.048) us units on 10G
+ * and 1G. The minimun EITR is 6us.
+ */
+#define IXGBE_MIN_RSC_EITR_10G1G 0x00000018
 #define IXGBE_MAX_EITR         0x00000FF8
 #define IXGBE_MIN_EITR         8
 #define IXGBE_EITR(_i)         (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : \
diff -r 57bbbbeb6257 -r 3510e86539e6 sys/dev/pci/ixgbe/ixv.c
--- a/sys/dev/pci/ixgbe/ixv.c   Mon Feb 26 13:52:00 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixv.c   Mon Feb 26 13:55:54 2018 +0000
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.56.2.6 2018/02/26 00:25:16 snj Exp $*/
+/*$NetBSD: ixv.c,v 1.56.2.7 2018/02/26 13:55:54 martin Exp $*/
 
 /******************************************************************************
 
@@ -118,6 +118,7 @@
 static void    ixv_set_ivar(struct adapter *, u8, u8, s8);
 static void    ixv_configure_ivars(struct adapter *);
 static u8 *    ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
+static void    ixv_eitr_write(struct ix_queue *, uint32_t);
 
 static void    ixv_setup_vlan_support(struct adapter *);
 #if 0
@@ -792,6 +793,9 @@
        /* And now turn on interrupts */
        ixv_enable_intr(adapter);
 
+       /* Update saved flags. See ixgbe_ifflags_cb() */



Home | Main Index | Thread Index | Old Index