Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Jan 2014 03:48:32 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r260363 - head/sys/dev/ath
Message-ID:  <201401060348.s063mW8C031852@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Mon Jan  6 03:48:32 2014
New Revision: 260363
URL: http://svnweb.freebsd.org/changeset/base/260363

Log:
  Correctly remove entries from the relevant receive ath_buf list before
  freeing them.
  
  The current code would walk the list and call the buffer free, which
  didn't remove it from any lists before pushing it back on the free list.
  
  Tested:		AR9485, STA mode
  
  Noticed by:	dillon@apollo.dragonflybsd.org

Modified:
  head/sys/dev/ath/if_ath_rx_edma.c

Modified: head/sys/dev/ath/if_ath_rx_edma.c
==============================================================================
--- head/sys/dev/ath/if_ath_rx_edma.c	Mon Jan  6 01:51:08 2014	(r260362)
+++ head/sys/dev/ath/if_ath_rx_edma.c	Mon Jan  6 03:48:32 2014	(r260363)
@@ -450,18 +450,20 @@ ath_edma_recv_proc_queue(struct ath_soft
 static void
 ath_edma_flush_deferred_queue(struct ath_softc *sc)
 {
-	struct ath_buf *bf, *next;
+	struct ath_buf *bf;
 
 	ATH_RX_LOCK_ASSERT(sc);
 
 	/* Free in one set, inside the lock */
-	TAILQ_FOREACH_SAFE(bf,
-	    &sc->sc_rx_rxlist[HAL_RX_QUEUE_LP], bf_list, next) {
+	while (! TAILQ_EMPTY(&sc->sc_rx_rxlist[HAL_RX_QUEUE_LP])) {
+		bf = TAILQ_FIRST(&sc->sc_rx_rxlist[HAL_RX_QUEUE_LP]);
+		TAILQ_REMOVE(&sc->sc_rx_rxlist[HAL_RX_QUEUE_LP], bf, bf_list);
 		/* Free the buffer/mbuf */
 		ath_edma_rxbuf_free(sc, bf);
 	}
-	TAILQ_FOREACH_SAFE(bf,
-	    &sc->sc_rx_rxlist[HAL_RX_QUEUE_HP], bf_list, next) {
+	while (! TAILQ_EMPTY(&sc->sc_rx_rxlist[HAL_RX_QUEUE_HP])) {
+		bf = TAILQ_FIRST(&sc->sc_rx_rxlist[HAL_RX_QUEUE_HP]);
+		TAILQ_REMOVE(&sc->sc_rx_rxlist[HAL_RX_QUEUE_HP], bf, bf_list);
 		/* Free the buffer/mbuf */
 		ath_edma_rxbuf_free(sc, bf);
 	}
@@ -495,6 +497,10 @@ ath_edma_recv_proc_deferred_queue(struct
 	ATH_RX_UNLOCK(sc);
 
 	/* Handle the completed descriptors */
+	/*
+	 * XXX is this SAFE call needed? The ath_buf entries
+	 * aren't modified by ath_rx_pkt, right?
+	 */
 	TAILQ_FOREACH_SAFE(bf, &rxlist, bf_list, next) {
 		/*
 		 * Skip the RX descriptor status - start at the data offset
@@ -520,7 +526,9 @@ ath_edma_recv_proc_deferred_queue(struct
 
 	/* Free in one set, inside the lock */
 	ATH_RX_LOCK(sc);
-	TAILQ_FOREACH_SAFE(bf, &rxlist, bf_list, next) {
+	while (! TAILQ_EMPTY(&rxlist)) {
+		bf = TAILQ_FIRST(&rxlist);
+		TAILQ_REMOVE(&rxlist, bf, bf_list);
 		/* Free the buffer/mbuf */
 		ath_edma_rxbuf_free(sc, bf);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401060348.s063mW8C031852>