Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e73dee7 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

mac80211: fix TX aggregation session timer



In commit 12d3952f
("mac80211: optimize aggregation session timeout handling")
two bugs were introduced:
 1) RCU usage was completely broken since no locks are held
 2) the timer must not rearm when agg session is stopping

Reported-and-tested-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Cc: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a9d3c05c
Loading
Loading
Loading
Loading
+8 −2
Original line number Original line Diff line number Diff line
@@ -421,16 +421,22 @@ static void sta_tx_agg_session_timer_expired(unsigned long data)
	struct tid_ampdu_tx *tid_tx;
	struct tid_ampdu_tx *tid_tx;
	unsigned long timeout;
	unsigned long timeout;


	tid_tx = rcu_dereference_protected_tid_tx(sta, *ptid);
	rcu_read_lock();
	if (!tid_tx)
	tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[*ptid]);
	if (!tid_tx || test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
		rcu_read_unlock();
		return;
		return;
	}


	timeout = tid_tx->last_tx + TU_TO_JIFFIES(tid_tx->timeout);
	timeout = tid_tx->last_tx + TU_TO_JIFFIES(tid_tx->timeout);
	if (time_is_after_jiffies(timeout)) {
	if (time_is_after_jiffies(timeout)) {
		mod_timer(&tid_tx->session_timer, timeout);
		mod_timer(&tid_tx->session_timer, timeout);
		rcu_read_unlock();
		return;
		return;
	}
	}


	rcu_read_unlock();

#ifdef CONFIG_MAC80211_HT_DEBUG
#ifdef CONFIG_MAC80211_HT_DEBUG
	printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid);
	printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid);
#endif
#endif