Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Mar 2012 23:53:38 +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: r232707 - head/sys/dev/ath
Message-ID:  <201203082353.q28Nrc5k070154@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Thu Mar  8 23:53:38 2012
New Revision: 232707
URL: http://svn.freebsd.org/changeset/base/232707

Log:
  Correctly initialise the TXQ link pointer to the last descriptor in
  the last buffer in the list.
  
  The current behaviour (due to me, so pointy hat is firmly on my head here)
  was incorrect - it was setting the link pointer to the last descriptor
  of the _first_ buffer in the TXQ.  Instead, it should have set it to the
  last descriptor in the _last_ buffer in the TXQ.
  
  This showed up as occasional TX stalls with frames in the TXQ but no
  TX progress being made.  Further inspection showed the TXQ looked like
  it contained multiple "lists" of frames - there'd be a list of correct
  frames, then a NULL link pointer, but there'd be a next buffer in the
  list.
  
  Since this code is only called upon an interface reset, it's likely
  this only began showing up when I started doing stress testing
  in environments which annoy the radios enough to cause lockups.
  
  I've not yet any TX stalls with this patch applied.
  
  PR:		kern/165866

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

Modified: head/sys/dev/ath/if_ath_tx.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx.c	Thu Mar  8 23:52:22 2012	(r232706)
+++ head/sys/dev/ath/if_ath_tx.c	Thu Mar  8 23:53:38 2012	(r232707)
@@ -623,19 +623,22 @@ void
 ath_txq_restart_dma(struct ath_softc *sc, struct ath_txq *txq)
 {
 	struct ath_hal *ah = sc->sc_ah;
-	struct ath_buf *bf;
+	struct ath_buf *bf, *bf_last;
 
 	ATH_TXQ_LOCK_ASSERT(txq);
 
 	/* This is always going to be cleared, empty or not */
 	txq->axq_flags &= ~ATH_TXQ_PUTPENDING;
 
+	/* XXX make this ATH_TXQ_FIRST */
 	bf = TAILQ_FIRST(&txq->axq_q);
+	bf_last = ATH_TXQ_LAST(txq, axq_q_s);
+
 	if (bf == NULL)
 		return;
 
 	ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
-	txq->axq_link = &bf->bf_lastds->ds_link;
+	txq->axq_link = &bf_last->bf_lastds->ds_link;
 	ath_hal_txstart(ah, txq->axq_qnum);
 }
 



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