Subject: kern/12605: panic: _bus_dmamap_sync
To: None <gnats-bugs@gnats.netbsd.org>
From: H.Saito <saito@densan.co.jp>
List: netbsd-bugs
Date: 04/09/2001 21:27:24
>Number: 12605
>Category: kern
>Synopsis: bug of sys/dev/pci/if_de.c
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Apr 10 17:58:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: H.Saito
>Release: 1.5
>Organization:
>Environment:
DCP-R5000/30(DENSAN Compact-PCI bus Board)
big-endian, mips1, ELF
System: NetBSD vw5 1.5 NetBSD 1.5 (GENERIC) #4: Mon Apr 9 16:40:41 JST 2001 saito@vw4:/user5/NetBSD-1.5/usr/src/sys/arch/devos/compile/GENERIC devos
>Description:
A duplicate dma maps pointer was allocated from tulip_txput()
of sys/dev/pci/if_de.c.
Mayby, this Program is wrong, please see below.
if (sc->tulip_txmaps_free > 0) {
map = sc->tulip_txmaps[sc->tulip_txmaps_free-1];
} else {
...
}
...
--sc->tulip_txmaps_free; /* commit to using the dmamap */
>How-To-Repeat:
If NetBSD-1.5 transfer too many data with another machine by TCP/IP,
and cp a large file to /mnt that mounted by nfs with another machine,
immediately crashed(panic: _bus_dmamap_sync).
>Fix:
--- if_de.c.org Thu Mar 23 16:01:37 2000
+++ if_de.c Mon Apr 9 15:14:38 2001
@@ -3296,6 +3303,30 @@
#endif
}
+
+static void put_tulip_txmaps(tulip_softc_t * const sc, bus_dmamap_t map);
+static bus_dmamap_t get_tulip_txmaps(tulip_softc_t * const sc);
+
+static void
+put_tulip_txmaps(tulip_softc_t * const sc, bus_dmamap_t map)
+{
+#if defined(TULIP_TXMAPS_DEBUG)
+ int n;
+
+ for (n = 0; n < sc->tulip_txmaps_free; n++) {
+ if (sc->tulip_txmaps[n] == map)
+ printf("put_tulip_txmaps: %d: 0x%x\n", n, (int)map);
+ }
+#endif
+ sc->tulip_txmaps[sc->tulip_txmaps_free++] = map;
+}
+
+static bus_dmamap_t
+get_tulip_txmaps(tulip_softc_t * const sc)
+{
+ return (sc->tulip_txmaps[--sc->tulip_txmaps_free]);
+}
+
static void
tulip_reset(
tulip_softc_t * const sc)
@@ -3360,7 +3396,7 @@
#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
map = M_GETCTX(m, bus_dmamap_t);
bus_dmamap_unload(sc->tulip_dmatag, map);
- sc->tulip_txmaps[sc->tulip_txmaps_free++] = map;
+ put_tulip_txmaps(sc, map);
#endif
m_freem(m);
}
@@ -3868,7 +3904,7 @@
#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
bus_dmamap_t map = M_GETCTX(m, bus_dmamap_t);
TULIP_TXMAP_POSTSYNC(sc, map);
- sc->tulip_txmaps[sc->tulip_txmaps_free++] = map;
+ put_tulip_txmaps(sc, map);
#endif /* TULIP_BUS_DMA */
#if NBPFILTER > 0
if (sc->tulip_bpf != NULL)
@@ -4374,7 +4410,7 @@
free += tulip_tx_intr(sc);
}
if (sc->tulip_txmaps_free > 0) {
- map = sc->tulip_txmaps[sc->tulip_txmaps_free-1];
+ map = get_tulip_txmaps(sc);
} else {
sc->tulip_flags |= TULIP_WANTTXSTART;
#if defined(TULIP_DEBUG)
@@ -4395,6 +4431,7 @@
#if defined(TULIP_DEBUG)
sc->tulip_dbg.dbg_txput_finishes[2]++;
#endif
+ put_tulip_txmaps(sc, map);
goto finish;
}
error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT);
@@ -4405,6 +4442,7 @@
#if defined(TULIP_DEBUG)
sc->tulip_dbg.dbg_txput_finishes[3]++;
#endif
+ put_tulip_txmaps(sc, map);
goto finish;
}
}
@@ -4424,6 +4462,7 @@
sc->tulip_dbg.dbg_txput_finishes[4]++;
#endif
bus_dmamap_unload(sc->tulip_dmatag, map);
+ put_tulip_txmaps(sc, map);
goto finish;
}
for (; map->dm_nsegs - segcnt > 1; segcnt += 2) {
@@ -4452,7 +4491,6 @@
TULIP_TXMAP_PRESYNC(sc, map);
M_SETCTX(m, map);
map = NULL;
- --sc->tulip_txmaps_free; /* commit to using the dmamap */
#else /* !TULIP_BUS_DMA */
@@ -5237,12 +5275,11 @@
while (error == 0 && sc->tulip_txmaps_free < TULIP_TXDESCS) {
bus_dmamap_t map;
if ((error = TULIP_TXMAP_CREATE(sc, &map)) == 0)
- sc->tulip_txmaps[sc->tulip_txmaps_free++] = map;
+ put_tulip_txmaps(sc, map);
}
if (error) {
while (sc->tulip_txmaps_free > 0)
- bus_dmamap_destroy(sc->tulip_dmatag,
- sc->tulip_txmaps[--sc->tulip_txmaps_free]);
+ bus_dmamap_destroy(sc->tulip_dmatag, get_tulip_txmaps(sc));
}
}
#else
>Release-Note:
>Audit-Trail:
>Unformatted: