Re: head -r356066 reaching kern.ipc.nmbclusters on Rock64 (CortexA53 with 4GiByte of RAM) while putting files on it via nfs: some evidence

From: Peter Jeremy <peter_at_rulingia.com>
Date: Sun, 5 Jan 2020 07:35:35 +1100
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

Received on Sat Jan 04 2020 - 19:35:59 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:22 UTC