aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-12-08 13:16:41 +0100
committerJohannes Berg <johannes.berg@intel.com>2015-12-08 23:22:47 +0100
commitfde34ded7cf868f710596e78ed771293e90e7fb5 (patch)
tree2b6a814b9a6c6ee7c99fee3013bb108ef2cfab24
parent1b894521e60c1b91db1e8ba1278660e5c89f1b5f (diff)
downloadwireless-testing-fde34ded7cf868f710596e78ed771293e90e7fb5.tar.gz
mac80211: recalculate SW ROC only when needed
The current (new) code recalculates the new work timeout for software remain-on-channel whenever any item started. In two of the callers of ieee80211_handle_roc_started(), this is completely pointless since they're for hardware and will skip the recalculation entirely; it's necessary only in the case of having just added a new item to the list, as in the last remaining case the recalculation had just been done. This last case, however, is also problematic - if one of the items on the list actually expires during the recalc the list iteration outside becomes corrupted and crashes. Fix this by moving the recalculation to the only place where it's required. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/offchannel.c6
1 files changed, 1 insertions, 5 deletions
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 8b2f4eaac2ba6..34541bcd16213 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -252,8 +252,6 @@ static bool ieee80211_recalc_sw_work(struct ieee80211_local *local,
static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
unsigned long start_time)
{
- struct ieee80211_local *local = roc->sdata->local;
-
if (WARN_ON(roc->notified))
return;
@@ -274,9 +272,6 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
}
roc->notified = true;
-
- if (!local->ops->remain_on_channel)
- ieee80211_recalc_sw_work(local, start_time);
}
static void ieee80211_hw_roc_start(struct work_struct *work)
@@ -658,6 +653,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
queued = true;
roc->on_channel = tmp->on_channel;
ieee80211_handle_roc_started(roc, now);
+ ieee80211_recalc_sw_work(local, now);
break;
}