Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci fix about IFF_OACTIVE.



details:   https://anonhg.NetBSD.org/src/rev/abd95a9e535b
branches:  trunk
changeset: 351489:abd95a9e535b
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Thu Feb 16 05:36:41 2017 +0000

description:
fix about IFF_OACTIVE.

It is required manipulate IFF_OACTIVE for old ethernet controllers and ALTQ
to use if_start. To avoid race, txq_lock of 0th txq is needed to write
IFF_OACTIVE.

TODO: read side refactor

diffstat:

 sys/dev/pci/if_wm.c |  39 ++++++++++++++++++++++++++++++---------
 1 files changed, 30 insertions(+), 9 deletions(-)

diffs (134 lines):

diff -r c604af57662a -r abd95a9e535b sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c       Thu Feb 16 03:53:20 2017 +0000
+++ b/sys/dev/pci/if_wm.c       Thu Feb 16 05:36:41 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wm.c,v 1.478 2017/02/13 05:02:21 knakahara Exp $    */
+/*     $NetBSD: if_wm.c,v 1.479 2017/02/16 05:36:41 knakahara Exp $    */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -84,7 +84,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.478 2017/02/13 05:02:21 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.479 2017/02/16 05:36:41 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -6522,11 +6522,15 @@
        bus_size_t seglen, curlen;
        uint32_t cksumcmd;
        uint8_t cksumfields;
+       struct wm_queue *wmq = container_of(txq, struct wm_queue, wmq_txq);
+       int qid = wmq->wmq_id;
 
        KASSERT(mutex_owned(txq->txq_lock));
 
        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                return;
+       if ((txq->txq_flags & WM_TXQ_NO_SPACE) != 0)
+               return;
 
        /* Remember the previous number of free descriptors. */
        ofree = txq->txq_free;
@@ -6635,7 +6639,9 @@
                            ("%s: TX: need %d (%d) descriptors, have %d\n",
                            device_xname(sc->sc_dev), dmamap->dm_nsegs,
                            segs_needed, txq->txq_free - 1));
-                       ifp->if_flags |= IFF_OACTIVE;
+                       if (qid == 0)
+                               ifp->if_flags |= IFF_OACTIVE;
+                       txq->txq_flags |= WM_TXQ_NO_SPACE;
                        bus_dmamap_unload(sc->sc_dmat, dmamap);
                        WM_Q_EVCNT_INCR(txq, txdstall);
                        break;
@@ -6651,7 +6657,9 @@
                        DPRINTF(WM_DEBUG_TX,
                            ("%s: TX: 82547 Tx FIFO bug detected\n",
                            device_xname(sc->sc_dev)));
-                       ifp->if_flags |= IFF_OACTIVE;
+                       if (qid == 0)
+                               ifp->if_flags |= IFF_OACTIVE;
+                       txq->txq_flags |= WM_TXQ_NO_SPACE;
                        bus_dmamap_unload(sc->sc_dmat, dmamap);
                        WM_Q_EVCNT_INCR(txq, txfifo_stall);
                        break;
@@ -6795,7 +6803,9 @@
        }
 
        if (m0 != NULL) {
-               ifp->if_flags |= IFF_OACTIVE;
+               if (qid == 0)
+                       ifp->if_flags |= IFF_OACTIVE;
+               txq->txq_flags |= WM_TXQ_NO_SPACE;
                WM_Q_EVCNT_INCR(txq, txdrop);
                DPRINTF(WM_DEBUG_TX, ("%s: TX: error after IFQ_DEQUEUE\n",
                        __func__));
@@ -6804,7 +6814,9 @@
 
        if (txq->txq_sfree == 0 || txq->txq_free <= 2) {
                /* No more slots; notify upper layer. */
-               ifp->if_flags |= IFF_OACTIVE;
+               if (qid == 0)
+                       ifp->if_flags |= IFF_OACTIVE;
+               txq->txq_flags |= WM_TXQ_NO_SPACE;
        }
 
        if (txq->txq_free != ofree) {
@@ -7103,6 +7115,8 @@
        bus_dmamap_t dmamap;
        int error, nexttx, lasttx = -1, seg, segs_needed;
        bool do_csum, sent;
+       struct wm_queue *wmq = container_of(txq, struct wm_queue, wmq_txq);
+       int qid = wmq->wmq_id;
 
        KASSERT(mutex_owned(txq->txq_lock));
 
@@ -7196,6 +7210,8 @@
                            ("%s: TX: need %d (%d) descriptors, have %d\n",
                            device_xname(sc->sc_dev), dmamap->dm_nsegs,
                            segs_needed, txq->txq_free - 1));
+                       if (qid == 0)
+                               ifp->if_flags |= IFF_OACTIVE;
                        txq->txq_flags |= WM_TXQ_NO_SPACE;
                        bus_dmamap_unload(sc->sc_dmat, dmamap);
                        WM_Q_EVCNT_INCR(txq, txdstall);
@@ -7353,6 +7369,8 @@
        }
 
        if (m0 != NULL) {
+               if (qid == 0)
+                       ifp->if_flags |= IFF_OACTIVE;
                txq->txq_flags |= WM_TXQ_NO_SPACE;
                WM_Q_EVCNT_INCR(txq, txdrop);
                DPRINTF(WM_DEBUG_TX, ("%s: TX: error after IFQ_DEQUEUE\n",
@@ -7362,6 +7380,8 @@
 
        if (txq->txq_sfree == 0 || txq->txq_free <= 2) {
                /* No more slots; notify upper layer. */
+               if (qid == 0)
+                       ifp->if_flags |= IFF_OACTIVE;
                txq->txq_flags |= WM_TXQ_NO_SPACE;
        }
 
@@ -7430,15 +7450,16 @@
        int count = 0;
        int i;
        uint8_t status;
+       struct wm_queue *wmq = container_of(txq, struct wm_queue, wmq_txq);
 
        KASSERT(mutex_owned(txq->txq_lock));
 
        if (txq->txq_stopping)
                return 0;
 
-       if ((sc->sc_flags & WM_F_NEWQUEUE) != 0)
-               txq->txq_flags &= ~WM_TXQ_NO_SPACE;
-       else
+       txq->txq_flags &= ~WM_TXQ_NO_SPACE;
+       /* for ALTQ and legacy(not use multiqueue) ethernet controller */
+       if (wmq->wmq_id == 0)
                ifp->if_flags &= ~IFF_OACTIVE;
 
        /*



Home | Main Index | Thread Index | Old Index