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