aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2014-09-03 08:25:06 -0400
committerJohannes Berg <johannes.berg@intel.com>2014-09-05 07:52:09 -0400
commiteaa336b0f5087addb32217e6a70845ed57249f76 (patch)
treead4c34139f02db933f5a061058bba0b9c96a9825
parent24ecd45e2eb194dcadefeb60a16f4ca751402413 (diff)
mac80211: combine roc with the "next roc" if possible
If the remaining time in the current roc is not long enough, mac80211 adds the new roc right after it (if they have similar params). However, in case of multiple rocs, the "next roc" is not considered, resulting in multiple rocs, each one with its own duration. Refactor the code a bit and consider the next roc, so a single max roc will be used instead of multiple rocs (which might last much longer). Signed-off-by: Eliad Peller <eliadx.peller@intel.com> Reviewed-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/cfg.c77
1 files changed, 53 insertions, 24 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 4e57b67a91dd..4c1681bae232 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2352,6 +2352,58 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
2352 return 0; 2352 return 0;
2353} 2353}
2354 2354
2355static bool ieee80211_coalesce_started_roc(struct ieee80211_local *local,
2356 struct ieee80211_roc_work *new_roc,
2357 struct ieee80211_roc_work *cur_roc)
2358{
2359 unsigned long j = jiffies;
2360 unsigned long cur_roc_end = cur_roc->hw_start_time +
2361 msecs_to_jiffies(cur_roc->duration);
2362 struct ieee80211_roc_work *next_roc;
2363 int new_dur;
2364
2365 if (WARN_ON(!cur_roc->started || !cur_roc->hw_begun))
2366 return false;
2367
2368 if (time_after(j + IEEE80211_ROC_MIN_LEFT, cur_roc_end))
2369 return false;
2370
2371 ieee80211_handle_roc_started(new_roc);
2372
2373 new_dur = new_roc->duration - jiffies_to_msecs(cur_roc_end - j);
2374
2375 /* cur_roc is long enough - add new_roc to the dependents list. */
2376 if (new_dur <= 0) {
2377 list_add_tail(&new_roc->list, &cur_roc->dependents);
2378 return true;
2379 }
2380
2381 new_roc->duration = new_dur;
2382
2383 /*
2384 * if cur_roc was already coalesced before, we might
2385 * want to extend the next roc instead of adding
2386 * a new one.
2387 */
2388 next_roc = list_entry(cur_roc->list.next,
2389 struct ieee80211_roc_work, list);
2390 if (&next_roc->list != &local->roc_list &&
2391 next_roc->chan == new_roc->chan &&
2392 next_roc->sdata == new_roc->sdata &&
2393 !WARN_ON(next_roc->started)) {
2394 list_add_tail(&new_roc->list, &next_roc->dependents);
2395 next_roc->duration = max(next_roc->duration,
2396 new_roc->duration);
2397 next_roc->type = max(next_roc->type, new_roc->type);
2398 return true;
2399 }
2400
2401 /* add right after cur_roc */
2402 list_add(&new_roc->list, &cur_roc->list);
2403
2404 return true;
2405}
2406
2355static int ieee80211_start_roc_work(struct ieee80211_local *local, 2407static int ieee80211_start_roc_work(struct ieee80211_local *local,
2356 struct ieee80211_sub_if_data *sdata, 2408 struct ieee80211_sub_if_data *sdata,
2357 struct ieee80211_channel *channel, 2409 struct ieee80211_channel *channel,
@@ -2457,8 +2509,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2457 2509
2458 /* If it has already started, it's more difficult ... */ 2510 /* If it has already started, it's more difficult ... */
2459 if (local->ops->remain_on_channel) { 2511 if (local->ops->remain_on_channel) {
2460 unsigned long j = jiffies;
2461
2462 /* 2512 /*
2463 * In the offloaded ROC case, if it hasn't begun, add 2513 * In the offloaded ROC case, if it hasn't begun, add
2464 * this new one to the dependent list to be handled 2514 * this new one to the dependent list to be handled
@@ -2481,29 +2531,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2481 break; 2531 break;
2482 } 2532 }
2483 2533
2484 if (time_before(j + IEEE80211_ROC_MIN_LEFT, 2534 if (ieee80211_coalesce_started_roc(local, roc, tmp))
2485 tmp->hw_start_time +
2486 msecs_to_jiffies(tmp->duration))) {
2487 int new_dur;
2488
2489 ieee80211_handle_roc_started(roc);
2490
2491 new_dur = roc->duration -
2492 jiffies_to_msecs(tmp->hw_start_time +
2493 msecs_to_jiffies(
2494 tmp->duration) -
2495 j);
2496
2497 if (new_dur > 0) {
2498 /* add right after tmp */
2499 roc->duration = new_dur;
2500 list_add(&roc->list, &tmp->list);
2501 } else {
2502 list_add_tail(&roc->list,
2503 &tmp->dependents);
2504 }
2505 queued = true; 2535 queued = true;
2506 }
2507 } else if (del_timer_sync(&tmp->work.timer)) { 2536 } else if (del_timer_sync(&tmp->work.timer)) {
2508 unsigned long new_end; 2537 unsigned long new_end;
2509 2538