Fix a cleanup hang if cleanup gets called _during_ an active cleanup.
authoradrian <adrian@FreeBSD.org>
Mon, 21 Apr 2014 01:02:49 +0000 (01:02 +0000)
committeradrian <adrian@FreeBSD.org>
Mon, 21 Apr 2014 01:02:49 +0000 (01:02 +0000)
commit35123c2dbbd62df4ed7d1164656fa0ba07c14986
treefe99394f1f110d3fb048a2ec7b6b7addc25aade2
parent4dfafb6abe5ba6cdfd95cd1ab115cdd7ad5ec279
Fix a cleanup hang if cleanup gets called _during_ an active cleanup.

During power save testing I noticed that the cleanup code is being
called during a RUN->RUN state transition.  It's because the net80211
stack is treating that (for reasons I don't quitey know yet) as a
reassociation and this calls the node cleanup code.  The reason it's
seeing a RUN->RUN transition is because during active power save
stuff it's possible that the RUN->SLEEP and SLEEP->RUN transitions
happen so quickly that the deferred net80211 vap state code
"loses" a transition, namely the intermediary SLEEP transition.

So, this was causing the node reassociation code to sometimes be called
twice in quick succession and this would result in ath_tx_tid_cleanup()
to be called again.  The code calling it would always call pause, and
then only call resume if the TID didn't have "cleanup_inprogress" set.
Unfortunately it didn't check if it was already set on entry, so it
would pause but not call resume.  Thus, paused would be called more
than once (once before each entry into ath-tx_tid_cleanup()) but resume
would only be called once when the cleanup state was finished.

This doesn't entirely fix all of the issues seen in the cleanup path
but it's a necessary first step.

Since this is a stability fix, it should be merged to stable/10 at some
point.

Tested:

* AR5416, STA mode

MFC after: 7 days
sys/dev/ath/if_ath_tx.c