[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