mac80211: Move num_sta_ps counter decrement after synchronize_rcu
authorHelmut Schaa <helmut.schaa@googlemail.com>
Fri, 27 Jan 2012 10:02:53 +0000 (11:02 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 30 Jan 2012 20:48:28 +0000 (15:48 -0500)
Unted the assumption that the sta struct is still accessible before the
synchronize_rcu call we should move the num_sta_ps counter decrement
after synchronize_rcu to avoid incorrect decrements if num_sta_ps.

Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/sta_info.c

index 1fb4770a7d1376dba25db0d123cb49a340027188..fa0823892b2da16e7d4f8cc89a141eccd2a16d3e 100644 (file)
@@ -750,15 +750,6 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
 
        sta->dead = true;
 
-       if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
-               BUG_ON(!sdata->bss);
-
-               clear_sta_flag(sta, WLAN_STA_PS_STA);
-
-               atomic_dec(&sdata->bss->num_sta_ps);
-               sta_info_recalc_tim(sta);
-       }
-
        local->num_sta--;
        local->sta_generation++;
 
@@ -790,6 +781,15 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
         */
        synchronize_rcu();
 
+       if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+               BUG_ON(!sdata->bss);
+
+               clear_sta_flag(sta, WLAN_STA_PS_STA);
+
+               atomic_dec(&sdata->bss->num_sta_ps);
+               sta_info_recalc_tim(sta);
+       }
+
        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
                local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
                __skb_queue_purge(&sta->ps_tx_buf[ac]);