Skip to content

Commit

Permalink
ath5k: fix race condition in tx desc processing
Browse files Browse the repository at this point in the history
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: Bob Copeland <[email protected]>
Acked-by: Bruno Randolf <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
  • Loading branch information
bcopeland authored and linvjw committed Apr 8, 2010
1 parent 6b5d117 commit a05988b
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit a05988b

Please sign in to comment.