aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-10-26 10:13:06 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-30 04:33:40 -0400
commit50febf6a1a9270b3558671864a27b23f671598ab (patch)
treeba700ee435487e31857d165f836ea084983d10cb /net/mac80211
parent8a2fbedcdc9bec1d613961f97cb87d6b71a66076 (diff)
mac80211: use a counter for remain-on-channel cookie
Instead of using the pointer which can be re-used fairly quickly due to allocator patterns and then makes debugging difficult, maintain a counter and use its value. Since it's a 64-bit value it can't really wrap, but catch that case anyway since it most likely points to a bug somewhere. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c21
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/offchannel.c7
3 files changed, 20 insertions, 11 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 986e9a139d42..eebb70b0aa11 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2382,13 +2382,22 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2382 list_add_tail(&roc->list, &local->roc_list); 2382 list_add_tail(&roc->list, &local->roc_list);
2383 2383
2384 /* 2384 /*
2385 * cookie is either the roc (for normal roc) 2385 * cookie is either the roc cookie (for normal roc)
2386 * or the SKB (for mgmt TX) 2386 * or the SKB (for mgmt TX)
2387 */ 2387 */
2388 if (txskb) 2388 if (!txskb) {
2389 /* local->mtx protects this */
2390 local->roc_cookie_counter++;
2391 roc->cookie = local->roc_cookie_counter;
2392 /* wow, you wrapped 64 bits ... more likely a bug */
2393 if (WARN_ON(roc->cookie == 0)) {
2394 roc->cookie = 1;
2395 local->roc_cookie_counter++;
2396 }
2397 *cookie = roc->cookie;
2398 } else {
2389 *cookie = (unsigned long)txskb; 2399 *cookie = (unsigned long)txskb;
2390 else 2400 }
2391 *cookie = (unsigned long)roc;
2392 2401
2393 return 0; 2402 return 0;
2394} 2403}
@@ -2423,7 +2432,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2423 struct ieee80211_roc_work *dep, *tmp2; 2432 struct ieee80211_roc_work *dep, *tmp2;
2424 2433
2425 list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) { 2434 list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
2426 if (!mgmt_tx && (unsigned long)dep != cookie) 2435 if (!mgmt_tx && dep->cookie != cookie)
2427 continue; 2436 continue;
2428 else if (mgmt_tx && dep->mgmt_tx_cookie != cookie) 2437 else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
2429 continue; 2438 continue;
@@ -2435,7 +2444,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2435 return 0; 2444 return 0;
2436 } 2445 }
2437 2446
2438 if (!mgmt_tx && (unsigned long)roc != cookie) 2447 if (!mgmt_tx && roc->cookie != cookie)
2439 continue; 2448 continue;
2440 else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) 2449 else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
2441 continue; 2450 continue;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a1f7c139308e..d272e0cabc37 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -356,7 +356,7 @@ struct ieee80211_roc_work {
356 356
357 u32 duration, req_duration; 357 u32 duration, req_duration;
358 struct sk_buff *frame; 358 struct sk_buff *frame;
359 u64 mgmt_tx_cookie; 359 u64 cookie, mgmt_tx_cookie;
360}; 360};
361 361
362/* flags used in struct ieee80211_if_managed.flags */ 362/* flags used in struct ieee80211_if_managed.flags */
@@ -1142,6 +1142,7 @@ struct ieee80211_local {
1142 struct list_head roc_list; 1142 struct list_head roc_list;
1143 struct work_struct hw_roc_start, hw_roc_done; 1143 struct work_struct hw_roc_start, hw_roc_done;
1144 unsigned long hw_roc_start_time; 1144 unsigned long hw_roc_start_time;
1145 u64 roc_cookie_counter;
1145 1146
1146 struct idr ack_status_frames; 1147 struct idr ack_status_frames;
1147 spinlock_t ack_status_lock; 1148 spinlock_t ack_status_lock;
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index c349f3aaf59e..0cd42d52880c 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -204,7 +204,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
204 roc->frame = NULL; 204 roc->frame = NULL;
205 } 205 }
206 } else { 206 } else {
207 cfg80211_ready_on_channel(&roc->sdata->wdev, (unsigned long)roc, 207 cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie,
208 roc->chan, roc->chan_type, 208 roc->chan, roc->chan_type,
209 roc->req_duration, GFP_KERNEL); 209 roc->req_duration, GFP_KERNEL);
210 } 210 }
@@ -320,9 +320,8 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
320 320
321 if (!roc->mgmt_tx_cookie) 321 if (!roc->mgmt_tx_cookie)
322 cfg80211_remain_on_channel_expired(&roc->sdata->wdev, 322 cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
323 (unsigned long)roc, 323 roc->cookie, roc->chan,
324 roc->chan, roc->chan_type, 324 roc->chan_type, GFP_KERNEL);
325 GFP_KERNEL);
326 325
327 list_for_each_entry_safe(dep, tmp, &roc->dependents, list) 326 list_for_each_entry_safe(dep, tmp, &roc->dependents, list)
328 ieee80211_roc_notify_destroy(dep); 327 ieee80211_roc_notify_destroy(dep);