mac80211: allow station add/remove to sleep
[safe/jmp/linux-2.6] / net / mac80211 / ibss.c
index 85c4ba1..f3e9424 100644 (file)
@@ -275,10 +275,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                                    (unsigned long long) supp_rates,
                                    (unsigned long long) sta->sta.supp_rates[band]);
 #endif
-               } else
-                       ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
-
-               rcu_read_unlock();
+                       rcu_read_unlock();
+               } else {
+                       rcu_read_unlock();
+                       ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
+                                              supp_rates, GFP_KERNEL);
+               }
        }
 
        bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
@@ -368,7 +370,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                       sdata->name, mgmt->bssid);
 #endif
                ieee80211_sta_join_ibss(sdata, bss);
-               ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
+               ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
+                                      supp_rates, GFP_KERNEL);
        }
 
  put_bss:
@@ -381,7 +384,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
  * must be callable in atomic context.
  */
 struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
-                                       u8 *bssid,u8 *addr, u32 supp_rates)
+                                       u8 *bssid,u8 *addr, u32 supp_rates,
+                                       gfp_t gfp)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
@@ -410,7 +414,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
               wiphy_name(local->hw.wiphy), addr, sdata->name);
 #endif
 
-       sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
+       sta = sta_info_alloc(sdata, addr, gfp);
        if (!sta)
                return NULL;
 
@@ -422,9 +426,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 
        rate_control_rate_init(sta);
 
+       /* If it fails, maybe we raced another insertion? */
        if (sta_info_insert(sta))
-               return NULL;
-
+               return sta_info_get(sdata, addr);
        return sta;
 }