Sorry for the delay in responding. On 2019-Dec-27 21:59:49 -0800, Mark Millard via freebsd-arm <freebsd-arm_at_freebsd.org> wrote: >The following sort of sequence leads to the Rock64 not >responding on the console or over ethernet, after notifying >of nmbclusters having been reached. (This limits what >information I have of what things were like at the end.) There's a bug in the dwc(4) driver such that it can leak mbuf clusters. I've been running with the following patch but need to clean it up samewhat before I can commit it: Index: sys/dev/dwc/if_dwc.c =================================================================== --- sys/dev/dwc/if_dwc.c (revision 356350) +++ sys/dev/dwc/if_dwc.c (working copy) _at__at_ -755,7 +755,6 _at__at_ dwc_rxfinish_locked(struct dwc_softc *sc) { struct ifnet *ifp; - struct mbuf *m0; struct mbuf *m; int error, idx, len; uint32_t rdes0; _at__at_ -762,9 +761,8 _at__at_ ifp = sc->ifp; - for (;;) { + for (; ; sc->rx_idx = next_rxidx(sc, sc->rx_idx)) { idx = sc->rx_idx; - rdes0 = sc->rxdesc_ring[idx].tdes0; if ((rdes0 & DDESC_RDES0_OWN) != 0) break; _at__at_ -773,9 +771,9 _at__at_ BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->rxbuf_tag, sc->rxbuf_map[idx].map); + m = sc->rxbuf_map[idx].mbuf; len = (rdes0 >> DDESC_RDES0_FL_SHIFT) & DDESC_RDES0_FL_MASK; if (len != 0) { - m = sc->rxbuf_map[idx].mbuf; m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = len; m->m_len = len; _at__at_ -784,24 +782,33 _at__at_ /* Remove trailing FCS */ m_adj(m, -ETHER_CRC_LEN); + /* Consume the mbuf and mark it as consumed */ + sc->rxbuf_map[idx].mbuf = NULL; DWC_UNLOCK(sc); (*ifp->if_input)(ifp, m); DWC_LOCK(sc); + m = NULL; } else { /* XXX Zero-length packet ? */ } - if ((m0 = dwc_alloc_mbufcl(sc)) != NULL) { - if ((error = dwc_setup_rxbuf(sc, idx, m0)) != 0) { - /* - * XXX Now what? - * We've got a hole in the rx ring. - */ + if (m == NULL) { + if ((m = dwc_alloc_mbufcl(sc)) == NULL) { + if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS, 1); + continue; } - } else + } + + if ((error = dwc_setup_rxbuf(sc, idx, m)) != 0) { + m_free(m); + device_printf(sc->dev, + "dwc_setup_rxbuf returned %d\n", error); if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS, 1); - - sc->rx_idx = next_rxidx(sc, sc->rx_idx); + /* + * XXX Now what? + * We've got a hole in the rx ring. + */ + } } } -- Peter Jeremy
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:22 UTC