提交 eaa336b0 编写于 作者: E Eliad Peller 提交者: Johannes Berg

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: NEliad Peller <eliadx.peller@intel.com>
Reviewed-by: NIlan Peer <ilan.peer@intel.com>
Signed-off-by: NEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 24ecd45e
......@@ -2352,6 +2352,58 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
return 0;
}
static bool ieee80211_coalesce_started_roc(struct ieee80211_local *local,
struct ieee80211_roc_work *new_roc,
struct ieee80211_roc_work *cur_roc)
{
unsigned long j = jiffies;
unsigned long cur_roc_end = cur_roc->hw_start_time +
msecs_to_jiffies(cur_roc->duration);
struct ieee80211_roc_work *next_roc;
int new_dur;
if (WARN_ON(!cur_roc->started || !cur_roc->hw_begun))
return false;
if (time_after(j + IEEE80211_ROC_MIN_LEFT, cur_roc_end))
return false;
ieee80211_handle_roc_started(new_roc);
new_dur = new_roc->duration - jiffies_to_msecs(cur_roc_end - j);
/* cur_roc is long enough - add new_roc to the dependents list. */
if (new_dur <= 0) {
list_add_tail(&new_roc->list, &cur_roc->dependents);
return true;
}
new_roc->duration = new_dur;
/*
* if cur_roc was already coalesced before, we might
* want to extend the next roc instead of adding
* a new one.
*/
next_roc = list_entry(cur_roc->list.next,
struct ieee80211_roc_work, list);
if (&next_roc->list != &local->roc_list &&
next_roc->chan == new_roc->chan &&
next_roc->sdata == new_roc->sdata &&
!WARN_ON(next_roc->started)) {
list_add_tail(&new_roc->list, &next_roc->dependents);
next_roc->duration = max(next_roc->duration,
new_roc->duration);
next_roc->type = max(next_roc->type, new_roc->type);
return true;
}
/* add right after cur_roc */
list_add(&new_roc->list, &cur_roc->list);
return true;
}
static int ieee80211_start_roc_work(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel *channel,
......@@ -2457,8 +2509,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
/* If it has already started, it's more difficult ... */
if (local->ops->remain_on_channel) {
unsigned long j = jiffies;
/*
* In the offloaded ROC case, if it hasn't begun, add
* this new one to the dependent list to be handled
......@@ -2481,29 +2531,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
break;
}
if (time_before(j + IEEE80211_ROC_MIN_LEFT,
tmp->hw_start_time +
msecs_to_jiffies(tmp->duration))) {
int new_dur;
ieee80211_handle_roc_started(roc);
new_dur = roc->duration -
jiffies_to_msecs(tmp->hw_start_time +
msecs_to_jiffies(
tmp->duration) -
j);
if (new_dur > 0) {
/* add right after tmp */
roc->duration = new_dur;
list_add(&roc->list, &tmp->list);
} else {
list_add_tail(&roc->list,
&tmp->dependents);
}
if (ieee80211_coalesce_started_roc(local, roc, tmp))
queued = true;
}
} else if (del_timer_sync(&tmp->work.timer)) {
unsigned long new_end;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册