Commit 50febf6a authored by Johannes Berg's avatar Johannes Berg

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent 8a2fbedc
...@@ -2382,13 +2382,22 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, ...@@ -2382,13 +2382,22 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
list_add_tail(&roc->list, &local->roc_list); list_add_tail(&roc->list, &local->roc_list);
/* /*
* cookie is either the roc (for normal roc) * cookie is either the roc cookie (for normal roc)
* or the SKB (for mgmt TX) * or the SKB (for mgmt TX)
*/ */
if (txskb) if (!txskb) {
/* local->mtx protects this */
local->roc_cookie_counter++;
roc->cookie = local->roc_cookie_counter;
/* wow, you wrapped 64 bits ... more likely a bug */
if (WARN_ON(roc->cookie == 0)) {
roc->cookie = 1;
local->roc_cookie_counter++;
}
*cookie = roc->cookie;
} else {
*cookie = (unsigned long)txskb; *cookie = (unsigned long)txskb;
else }
*cookie = (unsigned long)roc;
return 0; return 0;
} }
...@@ -2423,7 +2432,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, ...@@ -2423,7 +2432,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
struct ieee80211_roc_work *dep, *tmp2; struct ieee80211_roc_work *dep, *tmp2;
list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) { list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
if (!mgmt_tx && (unsigned long)dep != cookie) if (!mgmt_tx && dep->cookie != cookie)
continue; continue;
else if (mgmt_tx && dep->mgmt_tx_cookie != cookie) else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
continue; continue;
...@@ -2435,7 +2444,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, ...@@ -2435,7 +2444,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
return 0; return 0;
} }
if (!mgmt_tx && (unsigned long)roc != cookie) if (!mgmt_tx && roc->cookie != cookie)
continue; continue;
else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
continue; continue;
......
...@@ -356,7 +356,7 @@ struct ieee80211_roc_work { ...@@ -356,7 +356,7 @@ struct ieee80211_roc_work {
u32 duration, req_duration; u32 duration, req_duration;
struct sk_buff *frame; struct sk_buff *frame;
u64 mgmt_tx_cookie; u64 cookie, mgmt_tx_cookie;
}; };
/* flags used in struct ieee80211_if_managed.flags */ /* flags used in struct ieee80211_if_managed.flags */
...@@ -1142,6 +1142,7 @@ struct ieee80211_local { ...@@ -1142,6 +1142,7 @@ struct ieee80211_local {
struct list_head roc_list; struct list_head roc_list;
struct work_struct hw_roc_start, hw_roc_done; struct work_struct hw_roc_start, hw_roc_done;
unsigned long hw_roc_start_time; unsigned long hw_roc_start_time;
u64 roc_cookie_counter;
struct idr ack_status_frames; struct idr ack_status_frames;
spinlock_t ack_status_lock; spinlock_t ack_status_lock;
......
...@@ -204,7 +204,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) ...@@ -204,7 +204,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
roc->frame = NULL; roc->frame = NULL;
} }
} else { } else {
cfg80211_ready_on_channel(&roc->sdata->wdev, (unsigned long)roc, cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie,
roc->chan, roc->chan_type, roc->chan, roc->chan_type,
roc->req_duration, GFP_KERNEL); roc->req_duration, GFP_KERNEL);
} }
...@@ -320,9 +320,8 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) ...@@ -320,9 +320,8 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
if (!roc->mgmt_tx_cookie) if (!roc->mgmt_tx_cookie)
cfg80211_remain_on_channel_expired(&roc->sdata->wdev, cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
(unsigned long)roc, roc->cookie, roc->chan,
roc->chan, roc->chan_type, roc->chan_type, GFP_KERNEL);
GFP_KERNEL);
list_for_each_entry_safe(dep, tmp, &roc->dependents, list) list_for_each_entry_safe(dep, tmp, &roc->dependents, list)
ieee80211_roc_notify_destroy(dep); ieee80211_roc_notify_destroy(dep);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment