[rt2x00-users] [RFT] rt2x00: Tear down BA session on QoS frame failure
Helmut Schaa
helmut.schaa at googlemail.com
Thu Apr 19 21:19:54 EST 2012
On Thu, Apr 19, 2012 at 12:50 PM, Andreas Hartmann
<andihartmann at 01019freenet.de> wrote:
> Helmut Schaa wrote:
> [...]
>> diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
>> index 49a51b4..b57094a 100644
>> --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
>> +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
>> @@ -280,7 +280,8 @@ void rt2x00lib_txdone(struct queue_entry *entry,
>> u8 rate_idx, rate_flags, retry_rates;
>> u8 skbdesc_flags = skbdesc->flags;
>> bool success;
>> -
>> + struct ieee80211_sta *sta;
>> +
>> /*
>> * Unmap the skb.
>> */
>> @@ -340,6 +341,8 @@ void rt2x00lib_txdone(struct queue_entry *entry,
>> retry_rates = test_bit(TXDONE_FALLBACK, &txdesc->flags) ?
>> (txdesc->retry + 1) : 1;
>>
>> + sta = tx_info->control.sta;
>> +
>> /*
>> * Initialize TX status
>> */
>> @@ -392,8 +395,21 @@ void rt2x00lib_txdone(struct queue_entry *entry,
>> tx_info->status.ampdu_len = 1;
>> tx_info->status.ampdu_ack_len = success ? 1 : 0;
>>
>> - if (!success)
>> - tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
>> + /*
>> + * If an AMPDU failed, tear down the BA session
>> + * instead of letting mac80211 send a BAR.
>> + */
>> + struct ieee80211_hdr *hdr = (void *) skb->data;
>> + if (sta && !success &&
>> + ieee80211_is_data_qos(hdr->frame_control)) {
>> + /*
>> + * Tear down BA session
>> + */
>> + u8 *qc = ieee80211_get_qos_ctl(hdr);
>> + int tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
>> +
>> + ieee80211_stop_tx_ba_session(sta, tid);
>
> The call rcu_dereference_protected_tid_tx(sta, tid) in
> ieee80211_stop_tx_ba_session(sta, tid) hangs up the machine for me.
That brings us a bit closer. Can you still force the crash
after applying this?
Thanks a lot for your testing!
Helmut
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 4a4ad4d..4461425 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -672,7 +672,7 @@ int ieee80211_stop_tx_ba_session(struct
ieee80211_sta *pubsta, u16 tid)
return -EINVAL;
spin_lock_bh(&sta->lock);
- tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+ tid_tx = sta->ampdu_mlme.tid_tx[tid];
if (!tid_tx) {
ret = -ENOENT;
More information about the users
mailing list