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>
This commit is contained in:
parent
8a2fbedcdc
commit
50febf6a1a
|
@ -2382,13 +2382,22 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
|||
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)
|
||||
*/
|
||||
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;
|
||||
else
|
||||
*cookie = (unsigned long)roc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2423,7 +2432,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
|||
struct ieee80211_roc_work *dep, *tmp2;
|
||||
|
||||
list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
|
||||
if (!mgmt_tx && (unsigned long)dep != cookie)
|
||||
if (!mgmt_tx && dep->cookie != cookie)
|
||||
continue;
|
||||
else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
|
||||
continue;
|
||||
|
@ -2435,7 +2444,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!mgmt_tx && (unsigned long)roc != cookie)
|
||||
if (!mgmt_tx && roc->cookie != cookie)
|
||||
continue;
|
||||
else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
|
||||
continue;
|
||||
|
|
|
@ -356,7 +356,7 @@ struct ieee80211_roc_work {
|
|||
|
||||
u32 duration, req_duration;
|
||||
struct sk_buff *frame;
|
||||
u64 mgmt_tx_cookie;
|
||||
u64 cookie, mgmt_tx_cookie;
|
||||
};
|
||||
|
||||
/* flags used in struct ieee80211_if_managed.flags */
|
||||
|
@ -1142,6 +1142,7 @@ struct ieee80211_local {
|
|||
struct list_head roc_list;
|
||||
struct work_struct hw_roc_start, hw_roc_done;
|
||||
unsigned long hw_roc_start_time;
|
||||
u64 roc_cookie_counter;
|
||||
|
||||
struct idr ack_status_frames;
|
||||
spinlock_t ack_status_lock;
|
||||
|
|
|
@ -204,7 +204,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
|
|||
roc->frame = NULL;
|
||||
}
|
||||
} 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->req_duration, GFP_KERNEL);
|
||||
}
|
||||
|
@ -320,9 +320,8 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
|
|||
|
||||
if (!roc->mgmt_tx_cookie)
|
||||
cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
|
||||
(unsigned long)roc,
|
||||
roc->chan, roc->chan_type,
|
||||
GFP_KERNEL);
|
||||
roc->cookie, roc->chan,
|
||||
roc->chan_type, GFP_KERNEL);
|
||||
|
||||
list_for_each_entry_safe(dep, tmp, &roc->dependents, list)
|
||||
ieee80211_roc_notify_destroy(dep);
|
||||
|
|
Loading…
Reference in a new issue