svn commit: r225225 - user/adrian/if_ath_tx/sys/dev/ath

Adrian Chadd adrian at FreeBSD.org
Sun Aug 28 04:17:57 UTC 2011


Author: adrian
Date: Sun Aug 28 04:17:56 2011
New Revision: 225225
URL: http://svn.freebsd.org/changeset/base/225225

Log:
  Fix locking (again).

Modified:
  user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Sun Aug 28 03:05:16 2011	(r225224)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Sun Aug 28 04:17:56 2011	(r225225)
@@ -2041,7 +2041,7 @@ ath_tx_tid_resume(struct ath_softc *sc, 
 {
 	struct ath_txq *txq = sc->sc_ac2q[tid->ac];
 
-	ATH_TXQ_LOCK(txq);
+	ATH_TXQ_LOCK_ASSERT(txq);
 
 	tid->paused--;
 
@@ -2049,24 +2049,13 @@ ath_tx_tid_resume(struct ath_softc *sc, 
 	    __func__, tid->paused);
 
 	if (tid->paused || tid->axq_depth == 0) {
-		ATH_TXQ_UNLOCK(txq);
 		return;
 	}
 
 	ath_tx_tid_sched(sc, tid->an, tid->tid);
-	ATH_TXQ_UNLOCK(txq);
-
 	ath_tx_sched_proc_sched(sc, txq);
 }
 
-/*
- * Mark packets currently in the hardware TXQ from this TID
- * as now having no parent software TXQ.
- *
- * XXX not yet needed; there shouldn't be any packets left
- * XXX for this node in any of the hardware queues; the node
- * XXX isn't freed until the last TX packet has been sent.
- */
 static void
 ath_tx_tid_txq_unmark(struct ath_softc *sc, struct ath_node *an,
     int tid)
@@ -2166,6 +2155,10 @@ ath_tx_tid_drain(struct ath_softc *sc, s
  * This occurs when a completion handler frees the last buffer
  * for a node, and the node is thus freed. This causes the node
  * to be cleaned up, which ends up calling ath_tx_node_flush.
+ *
+ * XXX Because the TXQ may be locked right now (when it's called
+ * XXX from a completion handler which frees the last node)
+ * XXX do a dirty recursive hack avoidance.
  */
 void
 ath_tx_node_flush(struct ath_softc *sc, struct ath_node *an)
@@ -2175,14 +2168,20 @@ ath_tx_node_flush(struct ath_softc *sc, 
 	for (tid = 0; tid < IEEE80211_TID_SIZE; tid++) {
 		struct ath_tid *atid = &an->an_tid[tid];
 		struct ath_txq *txq = sc->sc_ac2q[atid->ac];
+		int islocked = 0;
 
 		/* Remove this tid from the list of active tids */
-		ATH_TXQ_LOCK(txq);
+		/* XXX eww, this needs to be fixed */
+		if (ATH_TXQ_IS_LOCKED(txq))
+			islocked = 1;
+		else
+			ATH_TXQ_LOCK(txq);
 		ath_tx_tid_unsched(sc, an, tid);
 
 		/* Free packets */
 		ath_tx_tid_drain(sc, an, atid);
-		ATH_TXQ_UNLOCK(txq);
+		if (! islocked)
+			ATH_TXQ_UNLOCK(txq);
 	}
 }
 
@@ -3403,14 +3402,15 @@ ath_addba_response(struct ieee80211_node
 	 */
 	r = sc->sc_addba_response(ni, tap, status, code, batimeout);
 
+	ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]);
 	/*
 	 * XXX dirty!
 	 * Slide the BAW left edge to wherever net80211 left it for us.
 	 * Read above for more information.
 	 */
 	tap->txa_start = ni->ni_txseqs[tid];
-
 	ath_tx_tid_resume(sc, atid);
+	ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
 	return r;
 }
 


More information about the svn-src-user mailing list