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 Avoid issues caused by sending old packets...



details:   https://anonhg.NetBSD.org/src/rev/3ce776a2d5ba
branches:  trunk
changeset: 321720:3ce776a2d5ba
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Mon Apr 02 05:02:55 2018 +0000

description:
Avoid issues caused by sending old packets at next link-up time.

This modification consists by the following two parts.
    - drain packets in if_snd queue or corresponding txr->txr_interq
      when link_active == false in ifp->if_start(), ifp->if_transmit(),
      and deferred Tx processing
    - drain packets in if_snd queue and all of txr->txr_interq's
      at link-down time

ok by msaitoh@n.o.

diffstat:

 sys/dev/pci/ixgbe/ix_txrx.c |  63 +++++++++++++++++++++++++++++++++++++++++---
 sys/dev/pci/ixgbe/ixgbe.c   |   3 +-
 sys/dev/pci/ixgbe/ixgbe.h   |   3 +-
 3 files changed, 62 insertions(+), 7 deletions(-)

diffs (141 lines):

diff -r 80f429d7c3a1 -r 3ce776a2d5ba sys/dev/pci/ixgbe/ix_txrx.c
--- a/sys/dev/pci/ixgbe/ix_txrx.c       Mon Apr 02 04:26:17 2018 +0000
+++ b/sys/dev/pci/ixgbe/ix_txrx.c       Mon Apr 02 05:02:55 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.37 2018/03/30 03:58:20 knakahara Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.38 2018/04/02 05:02:55 knakahara Exp $ */
 
 /******************************************************************************
 
@@ -103,6 +103,7 @@
 static void          ixgbe_rx_checksum(u32, struct mbuf *, u32,
                                        struct ixgbe_hw_stats *);
 static void          ixgbe_refresh_mbufs(struct rx_ring *, int);
+static void          ixgbe_drain(struct ifnet *, struct tx_ring *);
 static int           ixgbe_xmit(struct tx_ring *, struct mbuf *);
 static int           ixgbe_tx_ctx_setup(struct tx_ring *,
                                         struct mbuf *, u32 *, u32 *);
@@ -135,9 +136,15 @@
 
        IXGBE_TX_LOCK_ASSERT(txr);
 
-       if ((ifp->if_flags & IFF_RUNNING) == 0)
+       if (!adapter->link_active) {
+               /*
+                * discard all packets buffered in IFQ to avoid
+                * sending old packets at next link up timing.
+                */
+               ixgbe_drain(ifp, txr);
                return (ENETDOWN);
-       if (!adapter->link_active)
+       }
+       if ((ifp->if_flags & IFF_RUNNING) == 0)
                return (ENETDOWN);
 
        while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
@@ -271,9 +278,15 @@
        struct mbuf    *next;
        int            enqueued = 0, err = 0;
 
-       if ((ifp->if_flags & IFF_RUNNING) == 0)
+       if (!txr->adapter->link_active) {
+               /*
+                * discard all packets buffered in txr_interq to avoid
+                * sending old packets at next link up timing.
+                */
+               ixgbe_drain(ifp, txr);
                return (ENETDOWN);
-       if (txr->adapter->link_active == 0)
+       }
+       if ((ifp->if_flags & IFF_RUNNING) == 0)
                return (ENETDOWN);
 
        /* Process the queue */
@@ -342,6 +355,23 @@
        ixgbe_deferred_mq_start(txr);
 } /* ixgbe_deferred_mq_start */
 
+/************************************************************************
+ * ixgbe_drain_all
+ ************************************************************************/
+void
+ixgbe_drain_all(struct adapter *adapter)
+{
+       struct ifnet *ifp = adapter->ifp;
+       struct ix_queue *que = adapter->queues;
+
+       for (int i = 0; i < adapter->num_queues; i++, que++) {
+               struct tx_ring  *txr = que->txr;
+
+               IXGBE_TX_LOCK(txr);
+               ixgbe_drain(ifp, txr);
+               IXGBE_TX_UNLOCK(txr);
+       }
+}
 
 /************************************************************************
  * ixgbe_xmit
@@ -515,6 +545,29 @@
        return (0);
 } /* ixgbe_xmit */
 
+/************************************************************************
+ * ixgbe_drain
+ ************************************************************************/
+static void
+ixgbe_drain(struct ifnet *ifp, struct tx_ring *txr)
+{
+       struct mbuf *m;
+
+       IXGBE_TX_LOCK_ASSERT(txr);
+
+       if (txr->me == 0) {
+               while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
+                       IFQ_DEQUEUE(&ifp->if_snd, m);
+                       m_freem(m);
+                       IF_DROP(&ifp->if_snd);
+               }
+       }
+
+       while ((m = pcq_get(txr->txr_interq)) != NULL) {
+               m_freem(m);
+               txr->pcq_drops.ev_count++;
+       }
+}
 
 /************************************************************************
  * ixgbe_allocate_transmit_buffers
diff -r 80f429d7c3a1 -r 3ce776a2d5ba sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Mon Apr 02 04:26:17 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Mon Apr 02 05:02:55 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.140 2018/03/30 06:44:30 msaitoh Exp $ */
+/* $NetBSD: ixgbe.c,v 1.141 2018/04/02 05:02:55 knakahara Exp $ */
 
 /******************************************************************************
 
@@ -4600,6 +4600,7 @@
                        adapter->link_active = FALSE;
                        if (adapter->feat_en & IXGBE_FEATURE_SRIOV)
                                ixgbe_ping_all_vfs(adapter);
+                       ixgbe_drain_all(adapter);
                }
        }
 } /* ixgbe_update_link_status */
diff -r 80f429d7c3a1 -r 3ce776a2d5ba sys/dev/pci/ixgbe/ixgbe.h
--- a/sys/dev/pci/ixgbe/ixgbe.h Mon Apr 02 04:26:17 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.h Mon Apr 02 05:02:55 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.39 2018/03/30 03:58:20 knakahara Exp $ */
+/* $NetBSD: ixgbe.h,v 1.40 2018/04/02 05:02:55 knakahara Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -746,6 +746,7 @@
 int  ixgbe_mq_start_locked(struct ifnet *, struct tx_ring *);
 void ixgbe_deferred_mq_start(void *);
 void ixgbe_deferred_mq_start_work(struct work *, void *);
+void ixgbe_drain_all(struct adapter *);
 
 int  ixgbe_allocate_queues(struct adapter *);
 int  ixgbe_setup_transmit_structures(struct adapter *);



Home | Main Index | Thread Index | Old Index