mac80211: fix addba timer

The addba timer function acquires the sta spinlock,
but at the same time we try to del_timer_sync() it
under the spinlock which can produce deadlocks.

To fix this, always del_timer_sync() the timer in
ieee80211_process_addba_resp() and add it again
after checking the conditions, if necessary.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by Johannes Berg and committed by John W. Linville 2171abc5 e55ea2b1

+12 -7
+12 -7
net/mac80211/agg-tx.c
··· 666 667 state = &sta->ampdu_mlme.tid_state_tx[tid]; 668 669 spin_lock_bh(&sta->lock); 670 671 - if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 672 - spin_unlock_bh(&sta->lock); 673 - return; 674 - } 675 676 if (mgmt->u.action.u.addba_resp.dialog_token != 677 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 678 - spin_unlock_bh(&sta->lock); 679 #ifdef CONFIG_MAC80211_HT_DEBUG 680 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 681 #endif /* CONFIG_MAC80211_HT_DEBUG */ 682 - return; 683 } 684 685 - del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 686 #ifdef CONFIG_MAC80211_HT_DEBUG 687 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 688 #endif /* CONFIG_MAC80211_HT_DEBUG */ 689 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 690 == WLAN_STATUS_SUCCESS) { 691 u8 curstate = *state; ··· 698 } else { 699 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 700 } 701 spin_unlock_bh(&sta->lock); 702 }
··· 666 667 state = &sta->ampdu_mlme.tid_state_tx[tid]; 668 669 + del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 670 + 671 spin_lock_bh(&sta->lock); 672 673 + if (!(*state & HT_ADDBA_REQUESTED_MSK)) 674 + goto timer_still_needed; 675 676 if (mgmt->u.action.u.addba_resp.dialog_token != 677 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 678 #ifdef CONFIG_MAC80211_HT_DEBUG 679 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 680 #endif /* CONFIG_MAC80211_HT_DEBUG */ 681 + goto timer_still_needed; 682 } 683 684 #ifdef CONFIG_MAC80211_HT_DEBUG 685 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 686 #endif /* CONFIG_MAC80211_HT_DEBUG */ 687 + 688 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 689 == WLAN_STATUS_SUCCESS) { 690 u8 curstate = *state; ··· 699 } else { 700 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); 701 } 702 + 703 + goto out; 704 + 705 + timer_still_needed: 706 + add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 707 + out: 708 spin_unlock_bh(&sta->lock); 709 }