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

Adrian Chadd adrian at FreeBSD.org
Wed Aug 3 09:32:58 UTC 2011


Author: adrian
Date: Wed Aug  3 09:32:57 2011
New Revision: 224630
URL: http://svn.freebsd.org/changeset/base/224630

Log:
  Revert the previous commit - it meant a LOR was unavoidable between the
  TXQ lock and the IEEE80211_NODE_LOCK.
  
  Eg:
  
   1st 0xc086c6cc ath1_node_lock (ath1_node_lock) @ /data/freebsd/mips/if_ath_tx/src/sys/net80211/ieee80211_node.c:1702
   2nd 0x80a02738 ath1_txq1 (ath1_txq1) @ /data/freebsd/mips/if_ath_tx/src/sys/dev/ath/if_ath_tx.c:1631
   1st 0x80a027c8 ath1_txq3 (ath1_txq3) @ /data/freebsd/mips/if_ath_tx/src/sys/dev/ath/if_ath.c:4147
   2nd 0xc086c6cc ath1_node_lock (ath1_node_lock) @ /data/freebsd/mips/if_ath_tx/src/sys/net80211/ieee80211_node.c:1702
  
  I'm going to do some digging to see whether this is a false LOR - ie, whether
  it's possible for the LOR to involve the same node AND TXQ.
  
  For now, this means completion functions need to do their own TXQ locking
  if they're going to fiddle with TID state. This introduces a few potential
  race conditions - which is why I'd like to hold this lock across the
  completion function if possible.

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

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath.c	Wed Aug  3 09:21:52 2011	(r224629)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath.c	Wed Aug  3 09:32:57 2011	(r224630)
@@ -4146,9 +4146,11 @@ ath_tx_processq(struct ath_softc *sc, st
 	nacked = 0;
 	ATH_TXQ_LOCK(txq);
 	for (;;) {
+		ATH_TXQ_LOCK(txq);
 		txq->axq_intrcnt = 0;	/* reset periodic desc intr count */
 		bf = STAILQ_FIRST(&txq->axq_q);
 		if (bf == NULL) {
+			ATH_TXQ_UNLOCK(txq);
 			break;
 		}
 		ds0 = &bf->bf_desc[0];
@@ -4161,6 +4163,7 @@ ath_tx_processq(struct ath_softc *sc, st
 			    status == HAL_OK);
 #endif
 		if (status == HAL_EINPROGRESS) {
+			ATH_TXQ_UNLOCK(txq);
 			break;
 		}
 		ATH_TXQ_REMOVE_HEAD(txq, bf_list);
@@ -4177,6 +4180,7 @@ ath_tx_processq(struct ath_softc *sc, st
 		if (txq->axq_depth == 0)
 #endif
 			txq->axq_link = NULL;
+		ATH_TXQ_UNLOCK(txq);
 
 		ni = bf->bf_node;
 		/*
@@ -4220,6 +4224,14 @@ ath_tx_processq(struct ath_softc *sc, st
 #endif
 
 	/* Kick the TXQ scheduler */
+	/*
+	 * We can't hold the TXQ lock across the completion function;
+	 * the IEEE80211_NODE_LOCK is likely going to be held there
+	 * during buffer/node free. It's up to the completion
+	 * function to grab the TXQ lock before updating TID state
+	 * (eg sliding the BAW along.)
+	 */
+	ATH_TXQ_LOCK(txq);
 	ath_txq_sched(sc, txq);
 	ATH_TXQ_UNLOCK(txq);
 


More information about the svn-src-user mailing list