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 msaitoh@n.o. 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 *);