aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index cedd73a0c875..5540cbf7c445 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -51,17 +51,15 @@
51 * 51 *
52 * In order to remove a STA info structure, the caller needs to first 52 * In order to remove a STA info structure, the caller needs to first
53 * unlink it (sta_info_unlink()) from the list and hash tables and 53 * unlink it (sta_info_unlink()) from the list and hash tables and
54 * then destroy it while holding the RTNL; sta_info_destroy() will wait 54 * then destroy it; sta_info_destroy() will wait for an RCU grace period
55 * for an RCU grace period to elapse before actually freeing it. Due to 55 * to elapse before actually freeing it. Due to the pinning and the
56 * the pinning and the possibility of multiple callers trying to remove 56 * possibility of multiple callers trying to remove the same STA info at
57 * the same STA info at the same time, sta_info_unlink() can clear the 57 * the same time, sta_info_unlink() can clear the STA info pointer it is
58 * STA info pointer it is passed to indicate that the STA info is owned 58 * passed to indicate that the STA info is owned by somebody else now.
59 * by somebody else now.
60 * 59 *
61 * If sta_info_unlink() did not clear the pointer then the caller owns 60 * If sta_info_unlink() did not clear the pointer then the caller owns
62 * the STA info structure now and is responsible of destroying it with 61 * the STA info structure now and is responsible of destroying it with
63 * a call to sta_info_destroy(), not before RCU synchronisation, of 62 * a call to sta_info_destroy().
64 * course. Note that sta_info_destroy() must be protected by the RTNL.
65 * 63 *
66 * In all other cases, there is no concept of ownership on a STA entry, 64 * In all other cases, there is no concept of ownership on a STA entry,
67 * each structure is owned by the global hash table/list until it is 65 * each structure is owned by the global hash table/list until it is
@@ -164,7 +162,6 @@ void sta_info_destroy(struct sta_info *sta)
164 struct sk_buff *skb; 162 struct sk_buff *skb;
165 int i; 163 int i;
166 164
167 ASSERT_RTNL();
168 might_sleep(); 165 might_sleep();
169 166
170 if (!sta) 167 if (!sta)
@@ -180,22 +177,16 @@ void sta_info_destroy(struct sta_info *sta)
180 mesh_plink_deactivate(sta); 177 mesh_plink_deactivate(sta);
181#endif 178#endif
182 179
183 if (sta->key) { 180 /*
184 /* 181 * We have only unlinked the key, and actually destroying it
185 * NOTE: This will call synchronize_rcu() internally to 182 * may mean it is removed from hardware which requires that
186 * make sure no key references can be in use. We rely on 183 * the key->sta pointer is still valid, so flush the key todo
187 * that when we take this branch to make sure nobody can 184 * list here.
188 * reference this STA struct any longer! 185 *
189 */ 186 * ieee80211_key_todo() will synchronize_rcu() so after this
190 ieee80211_key_free(sta->key); 187 * nothing can reference this sta struct any more.
191 WARN_ON(sta->key); 188 */
192 } else { 189 ieee80211_key_todo();
193 /*
194 * Make sure that nobody can reference this STA struct
195 * any longer.
196 */
197 synchronize_rcu();
198 }
199 190
200#ifdef CONFIG_MAC80211_MESH 191#ifdef CONFIG_MAC80211_MESH
201 if (ieee80211_vif_is_mesh(&sta->sdata->vif)) 192 if (ieee80211_vif_is_mesh(&sta->sdata->vif))
@@ -439,6 +430,11 @@ void __sta_info_unlink(struct sta_info **sta)
439 return; 430 return;
440 } 431 }
441 432
433 if ((*sta)->key) {
434 ieee80211_key_free((*sta)->key);
435 WARN_ON((*sta)->key);
436 }
437
442 list_del(&(*sta)->list); 438 list_del(&(*sta)->list);
443 439
444 if ((*sta)->flags & WLAN_STA_PS) { 440 if ((*sta)->flags & WLAN_STA_PS) {
@@ -652,7 +648,7 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
652} 648}
653#endif 649#endif
654 650
655void __ieee80211_run_pending_flush(struct ieee80211_local *local) 651static void __ieee80211_run_pending_flush(struct ieee80211_local *local)
656{ 652{
657 struct sta_info *sta; 653 struct sta_info *sta;
658 unsigned long flags; 654 unsigned long flags;