Module Name: src Committed By: riz Date: Tue Apr 5 06:12:46 UTC 2011
Modified Files: src/sys/dev/pci [netbsd-5]: if_jme.c Log Message: Pull up following revision(s) (requested by bouyer in ticket #1588): sys/dev/pci/if_jme.c: revision 1.17 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. To generate a diff of this commit: cvs rdiff -u -r1.4.6.3 -r1.4.6.4 src/sys/dev/pci/if_jme.c 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/if_jme.c diff -u src/sys/dev/pci/if_jme.c:1.4.6.3 src/sys/dev/pci/if_jme.c:1.4.6.4 --- src/sys/dev/pci/if_jme.c:1.4.6.3 Sun Jan 16 12:51:59 2011 +++ src/sys/dev/pci/if_jme.c Tue Apr 5 06:12:46 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: if_jme.c,v 1.4.6.3 2011/01/16 12:51:59 bouyer Exp $ */ +/* $NetBSD: if_jme.c,v 1.4.6.4 2011/04/05 06:12:46 riz Exp $ */ /* * Copyright (c) 2008 Manuel Bouyer. All rights reserved. @@ -63,7 +63,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_jme.c,v 1.4.6.3 2011/01/16 12:51:59 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_jme.c,v 1.4.6.4 2011/04/05 06:12:46 riz Exp $"); #include <sys/param.h> @@ -447,13 +447,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; @@ -705,6 +706,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) { @@ -1050,6 +1053,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; @@ -1063,7 +1067,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]; @@ -1071,11 +1075,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); @@ -1093,6 +1105,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); @@ -1104,11 +1120,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); @@ -1130,7 +1159,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); @@ -1427,7 +1462,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 "