Module Name: src
Committed By: knakahara
Date: Mon Apr 2 05:02:55 UTC 2018
Modified Files:
src/sys/dev/pci/ixgbe: ix_txrx.c ixgbe.c ixgbe.h
Log Message:
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 [email protected].
To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/pci/ixgbe/ix_txrx.c
cvs rdiff -u -r1.140 -r1.141 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.39 -r1.40 src/sys/dev/pci/ixgbe/ixgbe.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/ixgbe/ix_txrx.c
diff -u src/sys/dev/pci/ixgbe/ix_txrx.c:1.37 src/sys/dev/pci/ixgbe/ix_txrx.c:1.38
--- src/sys/dev/pci/ixgbe/ix_txrx.c:1.37 Fri Mar 30 03:58:20 2018
+++ src/sys/dev/pci/ixgbe/ix_txrx.c Mon Apr 2 05:02:55 2018
@@ -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_free_receive_
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_legacy_start_locked(struct ifnet *
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 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
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_work(struct work
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 @@ retry:
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
Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.140 src/sys/dev/pci/ixgbe/ixgbe.c:1.141
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.140 Fri Mar 30 06:44:30 2018
+++ src/sys/dev/pci/ixgbe/ixgbe.c Mon Apr 2 05:02:55 2018
@@ -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 @@ ixgbe_update_link_status(struct adapter
adapter->link_active = FALSE;
if (adapter->feat_en & IXGBE_FEATURE_SRIOV)
ixgbe_ping_all_vfs(adapter);
+ ixgbe_drain_all(adapter);
}
}
} /* ixgbe_update_link_status */
Index: src/sys/dev/pci/ixgbe/ixgbe.h
diff -u src/sys/dev/pci/ixgbe/ixgbe.h:1.39 src/sys/dev/pci/ixgbe/ixgbe.h:1.40
--- src/sys/dev/pci/ixgbe/ixgbe.h:1.39 Fri Mar 30 03:58:20 2018
+++ src/sys/dev/pci/ixgbe/ixgbe.h Mon Apr 2 05:02:55 2018
@@ -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(struct ifnet *, stru
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 *);