Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci Some bus_dma(9)-related and memory allocation fi...



details:   https://anonhg.NetBSD.org/src/rev/467412d9e75b
branches:  trunk
changeset: 763680:467412d9e75b
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Wed Mar 30 18:11:37 2011 +0000

description:
Some bus_dma(9)-related and memory allocation fixes:
- always bus_dmamap_unload() before recycling a receive descriptor
- make sure to not sleep from interrupt context: call bus_dmamap_load with
  M_NOWAIT, and create dma maps BUS_DMA_ALLOCNOW.
- if a receive descriptor has a NULL mbuf try to allocate a new one, don't
  try to receive it.

diffstat:

 sys/dev/pci/if_jme.c |  59 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 47 insertions(+), 12 deletions(-)

diffs (146 lines):

diff -r 37eb90efcc50 -r 467412d9e75b sys/dev/pci/if_jme.c
--- a/sys/dev/pci/if_jme.c      Wed Mar 30 18:04:27 2011 +0000
+++ b/sys/dev/pci/if_jme.c      Wed Mar 30 18:11:37 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_jme.c,v 1.16 2011/01/09 00:12:45 kochi Exp $        */
+/*     $NetBSD: if_jme.c,v 1.17 2011/03/30 18:11:37 bouyer Exp $       */
 
 /*
  * Copyright (c) 2008 Manuel Bouyer.  All rights reserved.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_jme.c,v 1.16 2011/01/09 00:12:45 kochi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_jme.c,v 1.17 2011/03/30 18:11:37 bouyer Exp $");
 
 
 #include <sys/param.h>
@@ -439,13 +439,14 @@
        for (i = 0; i < JME_NBUFS; i++) {
                sc->jme_txmbuf[i] = sc->jme_rxmbuf[i] = NULL;
                if (bus_dmamap_create(sc->jme_dmatag, JME_MAX_TX_LEN,
-                   JME_NBUFS, JME_MAX_TX_LEN, 0, BUS_DMA_NOWAIT,
+                   JME_NBUFS, JME_MAX_TX_LEN, 0,
+                   BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                    &sc->jme_txmbufm[i]) != 0) {
                        aprint_error_dev(self, "can't allocate DMA TX map\n");
                        return;
                }
                if (bus_dmamap_create(sc->jme_dmatag, JME_MAX_RX_LEN,
-                   1, JME_MAX_RX_LEN, 0, BUS_DMA_NOWAIT,
+                   1, JME_MAX_RX_LEN, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                    &sc->jme_rxmbufm[i]) != 0) {
                        aprint_error_dev(self, "can't allocate DMA RX map\n");
                        return;
@@ -706,6 +707,8 @@
        }
        map = sc->jme_rxmbufm[i];
        m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
+       KASSERT(m->m_len == MCLBYTES);
+
        error = bus_dmamap_load_mbuf(sc->jme_dmatag, map, m,
            BUS_DMA_READ|BUS_DMA_NOWAIT);
        if (error) {
@@ -1051,6 +1054,7 @@
 static void
 jme_intr_rx(jme_softc_t *sc) {
        struct mbuf *m, *mhead;
+       bus_dmamap_t mmap;
        struct ifnet *ifp = &sc->jme_if;
        uint32_t flags,  buflen;
        int i, ipackets, nsegs, seg, error;
@@ -1064,7 +1068,7 @@
            sc->jme_rx_cons, le32toh(sc->jme_rxring[sc->jme_rx_cons].flags));
 #endif
        ipackets = 0;
-       while((le32toh(sc->jme_rxring[ sc->jme_rx_cons].flags) & JME_RD_OWN)
+       while((le32toh(sc->jme_rxring[sc->jme_rx_cons].flags) & JME_RD_OWN)
            == 0) {
                i = sc->jme_rx_cons;
                desc = &sc->jme_rxring[i];
@@ -1072,11 +1076,19 @@
                printf("rxintr i %d flags 0x%x buflen 0x%x\n",
                    i,  le32toh(desc->flags), le32toh(desc->buflen));
 #endif
+               if (sc->jme_rxmbuf[i] == NULL) {
+                       if ((error = jme_add_rxbuf(sc, NULL)) != 0) {
+                               aprint_error_dev(sc->jme_dev,
+                                   "can't add new mbuf to empty slot: %d\n",
+                                   error);
+                               break;
+                       }
+                       JME_DESC_INC(sc->jme_rx_cons, JME_NBUFS);
+                       i = sc->jme_rx_cons;
+                       continue;
+               }
                if ((le32toh(desc->buflen) & JME_RD_VALID) == 0)
                        break;
-               bus_dmamap_sync(sc->jme_dmatag, sc->jme_rxmbufm[i], 0,
-                   sc->jme_rxmbufm[i]->dm_mapsize, BUS_DMASYNC_POSTREAD);
-               bus_dmamap_unload(sc->jme_dmatag, sc->jme_rxmbufm[i]);
 
                buflen = le32toh(desc->buflen);
                nsegs = JME_RX_NSEGS(buflen);
@@ -1094,6 +1106,10 @@
                        for (seg = 0; seg < nsegs; seg++) {
                                m = sc->jme_rxmbuf[i];
                                sc->jme_rxmbuf[i] = NULL;
+                               mmap = sc->jme_rxmbufm[i];
+                               bus_dmamap_sync(sc->jme_dmatag, mmap, 0,
+                                   mmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+                               bus_dmamap_unload(sc->jme_dmatag, mmap);
                                if ((error = jme_add_rxbuf(sc, m)) != 0)
                                        aprint_error_dev(sc->jme_dev,
                                            "can't reuse mbuf: %d\n", error);
@@ -1105,11 +1121,24 @@
                /* receive this packet */
                mhead = m = sc->jme_rxmbuf[i];
                sc->jme_rxmbuf[i] = NULL;
+               mmap = sc->jme_rxmbufm[i];
+               bus_dmamap_sync(sc->jme_dmatag, mmap, 0,
+                   mmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+               bus_dmamap_unload(sc->jme_dmatag, mmap);
                /* add a new buffer to chain */
-               if (jme_add_rxbuf(sc, NULL) == ENOBUFS) {
-                       for (seg = 0; seg < nsegs; seg++) {
+               if (jme_add_rxbuf(sc, NULL) != 0) {
+                       if ((error = jme_add_rxbuf(sc, m)) != 0)
+                               aprint_error_dev(sc->jme_dev,
+                                   "can't reuse mbuf: %d\n", error);
+                       JME_DESC_INC(sc->jme_rx_cons, JME_NBUFS);
+                       i = sc->jme_rx_cons;
+                       for (seg = 1; seg < nsegs; seg++) {
                                m = sc->jme_rxmbuf[i];
                                sc->jme_rxmbuf[i] = NULL;
+                               mmap = sc->jme_rxmbufm[i];
+                               bus_dmamap_sync(sc->jme_dmatag, mmap, 0,
+                                   mmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+                               bus_dmamap_unload(sc->jme_dmatag, mmap);
                                if ((error = jme_add_rxbuf(sc, m)) != 0)
                                        aprint_error_dev(sc->jme_dev,
                                            "can't reuse mbuf: %d\n", error);
@@ -1131,7 +1160,13 @@
                        i = sc->jme_rx_cons;
                        m = sc->jme_rxmbuf[i];
                        sc->jme_rxmbuf[i] = NULL;
-                       (void)jme_add_rxbuf(sc, NULL);
+                       mmap = sc->jme_rxmbufm[i];
+                       bus_dmamap_sync(sc->jme_dmatag, mmap, 0,
+                           mmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+                       bus_dmamap_unload(sc->jme_dmatag, mmap);
+                       if ((error = jme_add_rxbuf(sc, NULL)) != 0)
+                               aprint_error_dev(sc->jme_dev,
+                                   "can't add new mbuf: %d\n", error);
                        m->m_flags &= ~M_PKTHDR;
                        m_cat(mhead, m);
                        JME_DESC_INC(sc->jme_rx_cons, JME_NBUFS);
@@ -1425,7 +1460,7 @@
        txd = &sc->jme_txring[prod];
 
        error = bus_dmamap_load_mbuf(sc->jme_dmatag, sc->jme_txmbufm[prod],
-           *m_head, BUS_DMA_WRITE);
+           *m_head, BUS_DMA_NOWAIT | BUS_DMA_WRITE);
        if (error) {
                if (error == EFBIG) {
                        log(LOG_ERR, "%s: Tx packet consumes too many "



Home | Main Index | Thread Index | Old Index