git: 9c67ab24b0e9 - stable/15 - rge: correctly free busdma memory / zero things out only if allocated

From: Adrian Chadd <adrian_at_FreeBSD.org>
Date: Sat, 31 Oct 2026 20:24:27 UTC
The branch stable/15 has been updated by adrian:

URL: https://cgit.FreeBSD.org/src/commit/?id=9c67ab24b0e947a527206d02dd4262897610858c

commit 9c67ab24b0e947a527206d02dd4262897610858c
Author:     John <john@cybersashi.com>
AuthorDate: 2026-02-22 18:06:44 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2026-10-31 20:15:04 +0000

    rge: correctly free busdma memory / zero things out only if allocated
    
    * Only free busdma memory that was allocated
    * Don't free tx/rx rings until their buffers have also been freed
    
    PR:     kern/293307
    
    Reviewed by:    zlei
    Differential Revision:  https://reviews.freebsd.org/D55420
    
    (cherry picked from commit d1947d0a1a55f905e5ed076d46d4f75a00c6f823)
---
 sys/dev/rge/if_rge.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/sys/dev/rge/if_rge.c b/sys/dev/rge/if_rge.c
index 5daede0ac95d..dfa6cd1325e5 100644
--- a/sys/dev/rge/if_rge.c
+++ b/sys/dev/rge/if_rge.c
@@ -1762,13 +1762,6 @@ rge_freemem(struct rge_softc *sc)
 
 	RGE_ASSERT_UNLOCKED(sc);
 
-	/* TX desc */
-	bus_dmamap_unload(sc->sc_dmat_tx_desc, q->q_tx.rge_tx_list_map);
-	if (q->q_tx.rge_tx_list != NULL)
-		bus_dmamem_free(sc->sc_dmat_tx_desc, q->q_tx.rge_tx_list,
-		    q->q_tx.rge_tx_list_map);
-	memset(&q->q_tx, 0, sizeof(q->q_tx));
-
 	/* TX buf */
 	for (i = 0; i < RGE_TX_LIST_CNT; i++) {
 		struct rge_txq *tx = &q->q_tx.rge_txq[i];
@@ -1800,12 +1793,13 @@ rge_freemem(struct rge_softc *sc)
 		}
 	}
 
-	/* RX desc */
-	bus_dmamap_unload(sc->sc_dmat_rx_desc, q->q_rx.rge_rx_list_map);
-	if (q->q_rx.rge_rx_list != 0)
-		bus_dmamem_free(sc->sc_dmat_rx_desc, q->q_rx.rge_rx_list,
-		    q->q_rx.rge_rx_list_map);
-	memset(&q->q_rx, 0, sizeof(q->q_tx));
+	/* TX desc */
+	if (q->q_tx.rge_tx_list != NULL) {
+		bus_dmamap_unload(sc->sc_dmat_tx_desc, q->q_tx.rge_tx_list_map);
+		bus_dmamem_free(sc->sc_dmat_tx_desc, q->q_tx.rge_tx_list,
+		    q->q_tx.rge_tx_list_map);
+	}
+	memset(&q->q_tx, 0, sizeof(q->q_tx));
 
 	/* RX buf */
 	for (i = 0; i < RGE_RX_LIST_CNT; i++) {
@@ -1830,6 +1824,14 @@ rge_freemem(struct rge_softc *sc)
 		}
 	}
 
+	/* RX desc */
+	if (q->q_rx.rge_rx_list != NULL) {
+		bus_dmamap_unload(sc->sc_dmat_rx_desc, q->q_rx.rge_rx_list_map);
+		bus_dmamem_free(sc->sc_dmat_rx_desc, q->q_rx.rge_rx_list,
+		    q->q_rx.rge_rx_list_map);
+	}
+	memset(&q->q_rx, 0, sizeof(q->q_tx));
+
 	return (0);
 }
 
@@ -1845,9 +1847,10 @@ rge_free_stats_mem(struct rge_softc *sc)
 
 	RGE_ASSERT_UNLOCKED(sc);
 
-	bus_dmamap_unload(sc->sc_dmat_stats_buf, ss->map);
-	if (ss->stats != NULL)
+	if (ss->stats != NULL) {
+		bus_dmamap_unload(sc->sc_dmat_stats_buf, ss->map);
 		bus_dmamem_free(sc->sc_dmat_stats_buf, ss->stats, ss->map);
+	}
 	memset(ss, 0, sizeof(*ss));
 	return (0);
 }