Commit 8ade0082 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: fix addba timer (again...)

commit 2171abc5
  Author: Johannes Berg <johannes@sipsolutions.net>
  Date:   Thu Oct 29 08:34:00 2009 +0100

      mac80211: fix addba timer

left a problem in there, even if the timer was
never started it could be deleted and then added.

Linus pointed out that del_timer_sync() isn't
actually needed if we make the timer able to
deal with no longer being needed when it gets
queued _while_ we're in the locked section that
also deletes it. For that the timer function only
needs to check the HT_ADDBA_RECEIVED_MSK bit as
well as the HT_ADDBA_REQUESTED_MSK bit, only if
the former is clear should it do anything.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 70e3bb50
...@@ -173,12 +173,14 @@ static void sta_addba_resp_timer_expired(unsigned long data) ...@@ -173,12 +173,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
/* check if the TID waits for addBA response */ /* check if the TID waits for addBA response */
spin_lock_bh(&sta->lock); spin_lock_bh(&sta->lock);
if (!(*state & HT_ADDBA_REQUESTED_MSK)) { if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
HT_ADDBA_REQUESTED_MSK) {
spin_unlock_bh(&sta->lock); spin_unlock_bh(&sta->lock);
*state = HT_AGG_STATE_IDLE; *state = HT_AGG_STATE_IDLE;
#ifdef CONFIG_MAC80211_HT_DEBUG #ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "timer expired on tid %d but we are not " printk(KERN_DEBUG "timer expired on tid %d but we are not "
"expecting addBA response there", tid); "(or no longer) expecting addBA response there",
tid);
#endif #endif
return; return;
} }
...@@ -666,21 +668,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, ...@@ -666,21 +668,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
state = &sta->ampdu_mlme.tid_state_tx[tid]; state = &sta->ampdu_mlme.tid_state_tx[tid];
del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
spin_lock_bh(&sta->lock); spin_lock_bh(&sta->lock);
if (!(*state & HT_ADDBA_REQUESTED_MSK)) if (!(*state & HT_ADDBA_REQUESTED_MSK))
goto timer_still_needed; goto out;
if (mgmt->u.action.u.addba_resp.dialog_token != if (mgmt->u.action.u.addba_resp.dialog_token !=
sta->ampdu_mlme.tid_tx[tid]->dialog_token) { sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
#ifdef CONFIG_MAC80211_HT_DEBUG #ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */ #endif /* CONFIG_MAC80211_HT_DEBUG */
goto timer_still_needed; goto out;
} }
del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
#ifdef CONFIG_MAC80211_HT_DEBUG #ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */ #endif /* CONFIG_MAC80211_HT_DEBUG */
...@@ -699,10 +701,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, ...@@ -699,10 +701,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
} }
goto out;
timer_still_needed:
add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
out: out:
spin_unlock_bh(&sta->lock); spin_unlock_bh(&sta->lock);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment