aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-12-08 07:16:41 -0500
committerJohannes Berg <johannes.berg@intel.com>2016-01-14 05:10:09 -0500
commite9db45578706e216d9bb0fb5f459b137da54be63 (patch)
treee452f456c0f86cfbd7e009e5bc29f1a26fd87fde /net
parent701a0fd5231866db08cebcd502894699f49cb960 (diff)
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>
Diffstat (limited to 'net')
-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 8b2f4eaac2ba..34541bcd1621 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,
252static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc, 252static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
253 unsigned long start_time) 253 unsigned long start_time)
254{ 254{
255 struct ieee80211_local *local = roc->sdata->local;
256
257 if (WARN_ON(roc->notified)) 255 if (WARN_ON(roc->notified))
258 return; 256 return;
259 257
@@ -274,9 +272,6 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
274 } 272 }
275 273
276 roc->notified = true; 274 roc->notified = true;
277
278 if (!local->ops->remain_on_channel)
279 ieee80211_recalc_sw_work(local, start_time);
280} 275}
281 276
282static void ieee80211_hw_roc_start(struct work_struct *work) 277static void ieee80211_hw_roc_start(struct work_struct *work)
@@ -658,6 +653,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
658 queued = true; 653 queued = true;
659 roc->on_channel = tmp->on_channel; 654 roc->on_channel = tmp->on_channel;
660 ieee80211_handle_roc_started(roc, now); 655 ieee80211_handle_roc_started(roc, now);
656 ieee80211_recalc_sw_work(local, now);
661 break; 657 break;
662 } 658 }
663 659