Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a05988bb authored by Bob Copeland's avatar Bob Copeland Committed by John W. Linville
Browse files

ath5k: fix race condition in tx desc processing



As pointed out by Benoit Papillault, there is a potential
race condition between the host and the hardware in reading
the next link in the transmit descriptor list:

cpu0              hw
                  tx for buf completed
                  raise tx_ok interrupt
process buf
buf->ds_link = 0
                  read buf->ds_link

This change checks txdp before processing a descriptor
(if there are any subsequent descriptors) to see if
hardware moved on.  We'll then process this descriptor on
the next tasklet.

Signed-off-by: default avatarBob Copeland <me@bobcopeland.com>
Acked-by: default avatarBruno Randolf <br1@einfach.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 6b5d117e
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -2083,6 +2083,17 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
	list_for_each_entry_safe(bf, bf0, &txq->q, list) {
		ds = bf->desc;

		/*
		 * It's possible that the hardware can say the buffer is
		 * completed when it hasn't yet loaded the ds_link from
		 * host memory and moved on.  If there are more TX
		 * descriptors in the queue, wait for TXDP to change
		 * before processing this one.
		 */
		if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr &&
		    !list_is_last(&bf->list, &txq->q))
			break;

		ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
		if (unlikely(ret == -EINPROGRESS))
			break;