summaryrefslogtreecommitdiffstats
path: root/sys/dev/hme
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2005-02-02 08:35:11 +0000
committeryongari <yongari@FreeBSD.org>2005-02-02 08:35:11 +0000
commit5ed480f8c99da73c583ac89f292d23e0f1603cdc (patch)
tree375dd4d27e5b63cb85e1d86c2392b9ab0faaa4e7 /sys/dev/hme
parente55f5e8b6f4c9cf6b01f539144a14d2f9680e575 (diff)
downloadFreeBSD-src-5ed480f8c99da73c583ac89f292d23e0f1603cdc.zip
FreeBSD-src-5ed480f8c99da73c583ac89f292d23e0f1603cdc.tar.gz
Fix "Duplicate mbuf free panic".
The cause of "Duplicate mbuf free panic" is in the programming error of hme_load_txmbuf(). The code path of the panic is the following. 1. Due to unknown reason DMA engine was freezed. So TX descritors of HME become full and the last failed attempt to transmit a packet had set its associated mbuf address to hme_txdesc structure. Also the failed packet is requeued into interface queue structure in order to retrasmit it when there are more available TX descritors. 2. Since DMA engine was freezed, if_timer starts to decrement its counter. When if_timer expires it tries to reset HME. During the reset phase, hme_meminit() is called and it frees all associated mbuf with descriptors. The last failed mbuf is also freed here. 3. After HME reset completed, HME starts to retransmit packets by dequeing the first packet in interface queue.(Note! the packet was already freed in hme_meminit()!) 4. When a TX completion interrupt is posted by the HME, driver tries to free the successfylly transmitted mbuf. Since the mbuf was freed in step2, now we get "Duplicate mbuf free panic". However, the real cause is in DMA engine freeze. Since no fatal errors reported via interrupts, there might be other cause of the freeze. I tried hard to understand the cause of DMA engine freeze but couldn't find any clues. It seems that the freeze happens under very high network loads(e.g. 7.5-8.0 MB/s TX speed). Though this fix is not enough to eliminate DMA engine freeze it's better than panic. Reported by: jhb via sparc64 ML
Diffstat (limited to 'sys/dev/hme')
-rw-r--r--sys/dev/hme/if_hme.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/dev/hme/if_hme.c b/sys/dev/hme/if_hme.c
index 6a30b46..e8be309 100644
--- a/sys/dev/hme/if_hme.c
+++ b/sys/dev/hme/if_hme.c
@@ -998,7 +998,6 @@ hme_load_txmbuf(struct hme_softc *sc, struct mbuf *m0)
return (-1);
if ((m0->m_pkthdr.csum_flags & sc->sc_csum_features) != 0)
hme_txcksum(m0, &cflags);
- td->htx_m = m0;
cba.hta_sc = sc;
cba.hta_htx = td;
if ((error = bus_dmamap_load_mbuf(sc->sc_tdmatag, td->htx_dmamap,
@@ -1013,6 +1012,7 @@ hme_load_txmbuf(struct hme_softc *sc, struct mbuf *m0)
STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txfreeq, htx_q);
STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txbusyq, td, htx_q);
+ td->htx_m = m0;
/* Turn descriptor ownership to the hme, back to forth. */
ri = sc->sc_rb.rb_tdhead;
OpenPOWER on IntegriCloud