Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci simplify wpi_rx_intr rbuf handling and add some ...



details:   https://anonhg.NetBSD.org/src/rev/b39d97870943
branches:  trunk
changeset: 331275:b39d97870943
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Thu Aug 07 02:28:52 2014 +0000

description:
simplify wpi_rx_intr rbuf handling and add some more bus_dmamap_sync; fixes stalls when downloading large files for me

diffstat:

 sys/dev/pci/if_wpi.c    |  115 +++++++++++++++++++++--------------------------
 sys/dev/pci/if_wpivar.h |    3 +-
 2 files changed, 53 insertions(+), 65 deletions(-)

diffs (213 lines):

diff -r 405dc63032d9 -r b39d97870943 sys/dev/pci/if_wpi.c
--- a/sys/dev/pci/if_wpi.c      Thu Aug 07 01:02:30 2014 +0000
+++ b/sys/dev/pci/if_wpi.c      Thu Aug 07 02:28:52 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_wpi.c,v 1.64 2014/08/05 21:54:39 jmcneill Exp $     */
+/*     $NetBSD: if_wpi.c,v 1.65 2014/08/07 02:28:52 jmcneill Exp $     */
 
 /*-
  * Copyright (c) 2006, 2007
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.64 2014/08/05 21:54:39 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wpi.c,v 1.65 2014/08/07 02:28:52 jmcneill Exp $");
 
 /*
  * Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters.
@@ -536,7 +536,6 @@
        rbuf = SLIST_FIRST(&sc->rxq.freelist);
        if (rbuf != NULL) {
                SLIST_REMOVE_HEAD(&sc->rxq.freelist, next);
-               sc->rxq.nb_free_entries --;
        }
        mutex_exit(&sc->rxq.freelist_mtx);
 
@@ -558,8 +557,6 @@
        mutex_enter(&sc->rxq.freelist_mtx);
        SLIST_INSERT_HEAD(&sc->rxq.freelist, rbuf, next);
        mutex_exit(&sc->rxq.freelist_mtx);
-       /* No need to protect this with a mutex, see wpi_rx_intr */
-       sc->rxq.nb_free_entries ++;
 
        if (__predict_true(m != NULL))
                pool_cache_put(mb_cache, m);
@@ -593,7 +590,6 @@
                SLIST_INSERT_HEAD(&ring->freelist, rbuf, next);
        }
 
-       ring->nb_free_entries = WPI_RBUF_COUNT;
        return 0;
 }
 
@@ -1471,7 +1467,7 @@
        struct ieee80211_frame *wh;
        struct ieee80211_node *ni;
        struct mbuf *m, *mnew;
-       int data_off;
+       int data_off, error;
 
        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
            BUS_DMASYNC_POSTREAD);
@@ -1505,69 +1501,57 @@
        /* Compute where are the useful datas */
        data_off = (char*)(head + 1) - mtod(data->m, char*);
                        
-       /*
-        * If the number of free entry is too low
-        * just dup the data->m socket and reuse the same rbuf entry
-        * Note that thi test is not protected by a mutex because the
-        * only path that causes nb_free_entries to decrease is through
-        * this interrupt routine, which is not re-entrent.
-        * What may not be obvious is that the safe path is if that test
-        * evaluates as true, so nb_free_entries can grow any time.
-        */
-       if (sc->rxq.nb_free_entries <= WPI_RBUF_LOW_LIMIT) {
-       
-               /* Prepare the mbuf for the m_dup */
-               data->m->m_pkthdr.len = data->m->m_len = le16toh(head->len);
-               data->m->m_data = (char*) data->m->m_data + data_off;
-
-               m = m_dup(data->m,0,M_COPYALL,M_DONTWAIT);
-
-               /* Restore the m_data pointer for future use */
-               data->m->m_data = (char*) data->m->m_data - data_off;
-
-               if (m == NULL) {
-                       ifp->if_ierrors++;
-                       return;
-               }
-       } else {
-               int error;
-
-               MGETHDR(mnew, M_DONTWAIT, MT_DATA);
-               if (mnew == NULL) {
-                       ifp->if_ierrors++;
-                       return;
-               }
-
-               rbuf = wpi_alloc_rbuf(sc);
-               KASSERT(rbuf != NULL);
-
-               /* attach Rx buffer to mbuf */
-               MEXTADD(mnew, rbuf->vaddr, WPI_RBUF_SIZE, 0, wpi_free_rbuf,
-                       rbuf);
-               mnew->m_flags |= M_EXT_RW;
-
-               bus_dmamap_unload(sc->sc_dmat, data->map);
-               m = data->m;
-               data->m = mnew;
+       MGETHDR(mnew, M_DONTWAIT, MT_DATA);
+       if (mnew == NULL) {
+               ifp->if_ierrors++;
+               return;
+       }
+
+       rbuf = wpi_alloc_rbuf(sc);
+       if (rbuf == NULL) {
+               m_freem(mnew);
+               ifp->if_ierrors++;
+               return;
+       }
+
+       /* attach Rx buffer to mbuf */
+       MEXTADD(mnew, rbuf->vaddr, WPI_RBUF_SIZE, 0, wpi_free_rbuf,
+               rbuf);
+       mnew->m_flags |= M_EXT_RW;
+
+       bus_dmamap_unload(sc->sc_dmat, data->map);
+
+       error = bus_dmamap_load(sc->sc_dmat, data->map,
+           mtod(mnew, void *), WPI_RBUF_SIZE, NULL,
+           BUS_DMA_NOWAIT | BUS_DMA_READ);
+       if (error) {
+               device_printf(sc->sc_dev,
+                   "couldn't load rx mbuf: %d\n", error);
+               m_freem(mnew);
+               ifp->if_ierrors++;
 
                error = bus_dmamap_load(sc->sc_dmat, data->map,
                    mtod(data->m, void *), WPI_RBUF_SIZE, NULL,
                    BUS_DMA_NOWAIT | BUS_DMA_READ);
-               if (error) {
+               if (error)
                        panic("%s: bus_dmamap_load failed: %d\n",
                            device_xname(sc->sc_dev), error);
-               }
-
-               /* update Rx descriptor */
-               ring->desc[ring->cur] = htole32(rbuf->paddr);
-               bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
-                   ring->desc_dma.size,
-                   BUS_DMASYNC_PREWRITE);
-
-               m->m_data = (char*)m->m_data + data_off;
-               m->m_pkthdr.len = m->m_len = le16toh(head->len);
+               return;
        }
 
+       /* new mbuf loaded successfully */
+       m = data->m;
+       data->m = mnew;
+
+       /* update Rx descriptor */
+       ring->desc[ring->cur] = htole32(rbuf->paddr);
+       bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
+           ring->desc_dma.size,
+           BUS_DMASYNC_PREWRITE);
+
+       m->m_data = (char*)m->m_data + data_off;
+       m->m_pkthdr.len = m->m_len = le16toh(head->len);
+
        /* finalize mbuf */
        m->m_pkthdr.rcvif = ifp;
 
@@ -1698,10 +1682,11 @@
        hw = le32toh(sc->shared->next);
        while (sc->rxq.cur != hw) {
                struct wpi_rx_data *data = &sc->rxq.data[sc->rxq.cur];
-               struct wpi_rx_desc *desc = mtod(data->m, struct wpi_rx_desc *);
+               struct wpi_rx_desc *desc;
 
                bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
                    BUS_DMASYNC_POSTREAD);
+               desc = mtod(data->m, struct wpi_rx_desc *);
 
                DPRINTFN(4, ("rx notification qid=%x idx=%d flags=%x type=%d "
                    "len=%d\n", desc->qid, desc->idx, desc->flags,
@@ -2699,6 +2684,8 @@
        desc->segs[1].addr = htole32(data->map->dm_segs[0].ds_addr);
        desc->segs[1].len  = htole32(data->map->dm_segs[0].ds_len);
 
+       bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
+           ring->desc_dma.map->dm_mapsize, BUS_DMASYNC_PREWRITE);
        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
            BUS_DMASYNC_PREWRITE);
 
@@ -2932,6 +2919,8 @@
        desc->segs[0].addr = htole32(data->map->dm_segs[0].ds_addr);
        desc->segs[0].len  = htole32(data->map->dm_segs[0].ds_len);
 
+       bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
+           ring->desc_dma.map->dm_mapsize, BUS_DMASYNC_PREWRITE);
        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
            BUS_DMASYNC_PREWRITE);
 
diff -r 405dc63032d9 -r b39d97870943 sys/dev/pci/if_wpivar.h
--- a/sys/dev/pci/if_wpivar.h   Thu Aug 07 01:02:30 2014 +0000
+++ b/sys/dev/pci/if_wpivar.h   Thu Aug 07 02:28:52 2014 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: if_wpivar.h,v 1.16 2014/08/05 21:54:39 jmcneill Exp $    */
+/*  $NetBSD: if_wpivar.h,v 1.17 2014/08/07 02:28:52 jmcneill Exp $    */
 
 /*-
  * Copyright (c) 2006
@@ -104,7 +104,6 @@
        struct wpi_rbuf         rbuf[WPI_RBUF_COUNT];
        SLIST_HEAD(, wpi_rbuf)  freelist;
        kmutex_t                freelist_mtx;
-       int                     nb_free_entries;
        int                     cur;
 };
 



Home | Main Index | Thread Index | Old Index