[rt2x00-users] [RFT] rt2x00: Tear down BA session on QoS frame failure

Andreas Hartmann andihartmann at 01019freenet.de
Thu Apr 19 22:10:20 EST 2012


Helmut Schaa wrote:
> 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;

The crash didn't disappear :-(. But I have to say, that the machine does
not crash with this small patch, as long as ieee80211_stop_tx_ba_session
isn't called by rt2x00lib_txdone().

Thanks,
regards,
Andreas



More information about the users mailing list