mirror of https://gitee.com/openkylin/linux.git
iwlwifi: mvm: reserve bandwidth for low-latency interface
If there is/are interface(s) in low-latency mode, reserve a percentage (currently 64%) of the quota for that binding to improve the quality of service for those interfaces. However, if there's more than one binding that has low-latency, then give up and don't reserve, we can't allocate more than 100%. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This commit is contained in:
parent
e03f9bef2f
commit
6ca40d6eae
|
@ -78,5 +78,6 @@
|
||||||
#define IWL_MVM_PS_SNOOZE_INTERVAL 25
|
#define IWL_MVM_PS_SNOOZE_INTERVAL 25
|
||||||
#define IWL_MVM_PS_SNOOZE_WINDOW 50
|
#define IWL_MVM_PS_SNOOZE_WINDOW 50
|
||||||
#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
|
#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
|
||||||
|
#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64
|
||||||
|
|
||||||
#endif /* __MVM_CONSTANTS_H */
|
#endif /* __MVM_CONSTANTS_H */
|
||||||
|
|
|
@ -65,9 +65,14 @@
|
||||||
#include "fw-api.h"
|
#include "fw-api.h"
|
||||||
#include "mvm.h"
|
#include "mvm.h"
|
||||||
|
|
||||||
|
#define QUOTA_100 IWL_MVM_MAX_QUOTA
|
||||||
|
#define QUOTA_LOWLAT_MIN ((QUOTA_100 * IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT) / 100)
|
||||||
|
|
||||||
struct iwl_mvm_quota_iterator_data {
|
struct iwl_mvm_quota_iterator_data {
|
||||||
int n_interfaces[MAX_BINDINGS];
|
int n_interfaces[MAX_BINDINGS];
|
||||||
int colors[MAX_BINDINGS];
|
int colors[MAX_BINDINGS];
|
||||||
|
int low_latency[MAX_BINDINGS];
|
||||||
|
int n_low_latency_bindings;
|
||||||
struct ieee80211_vif *new_vif;
|
struct ieee80211_vif *new_vif;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,22 +112,29 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
|
||||||
switch (vif->type) {
|
switch (vif->type) {
|
||||||
case NL80211_IFTYPE_STATION:
|
case NL80211_IFTYPE_STATION:
|
||||||
if (vif->bss_conf.assoc)
|
if (vif->bss_conf.assoc)
|
||||||
data->n_interfaces[id]++;
|
break;
|
||||||
break;
|
return;
|
||||||
case NL80211_IFTYPE_AP:
|
case NL80211_IFTYPE_AP:
|
||||||
case NL80211_IFTYPE_ADHOC:
|
case NL80211_IFTYPE_ADHOC:
|
||||||
if (mvmvif->ap_ibss_active)
|
if (mvmvif->ap_ibss_active)
|
||||||
data->n_interfaces[id]++;
|
break;
|
||||||
break;
|
return;
|
||||||
case NL80211_IFTYPE_MONITOR:
|
case NL80211_IFTYPE_MONITOR:
|
||||||
if (mvmvif->monitor_active)
|
if (mvmvif->monitor_active)
|
||||||
data->n_interfaces[id]++;
|
break;
|
||||||
break;
|
return;
|
||||||
case NL80211_IFTYPE_P2P_DEVICE:
|
case NL80211_IFTYPE_P2P_DEVICE:
|
||||||
break;
|
return;
|
||||||
default:
|
default:
|
||||||
WARN_ON_ONCE(1);
|
WARN_ON_ONCE(1);
|
||||||
break;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->n_interfaces[id]++;
|
||||||
|
|
||||||
|
if (iwl_mvm_vif_low_latency(mvmvif) && !data->low_latency[id]) {
|
||||||
|
data->n_low_latency_bindings++;
|
||||||
|
data->low_latency[id] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +174,7 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
|
||||||
int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
|
int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
|
||||||
{
|
{
|
||||||
struct iwl_time_quota_cmd cmd = {};
|
struct iwl_time_quota_cmd cmd = {};
|
||||||
int i, idx, ret, num_active_macs, quota, quota_rem;
|
int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat;
|
||||||
struct iwl_mvm_quota_iterator_data data = {
|
struct iwl_mvm_quota_iterator_data data = {
|
||||||
.n_interfaces = {},
|
.n_interfaces = {},
|
||||||
.colors = { -1, -1, -1, -1 },
|
.colors = { -1, -1, -1, -1 },
|
||||||
|
@ -197,11 +209,30 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
|
||||||
num_active_macs += data.n_interfaces[i];
|
num_active_macs += data.n_interfaces[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
quota = 0;
|
n_non_lowlat = num_active_macs;
|
||||||
quota_rem = 0;
|
|
||||||
if (num_active_macs) {
|
if (data.n_low_latency_bindings == 1) {
|
||||||
quota = IWL_MVM_MAX_QUOTA / num_active_macs;
|
for (i = 0; i < MAX_BINDINGS; i++) {
|
||||||
quota_rem = IWL_MVM_MAX_QUOTA % num_active_macs;
|
if (data.low_latency[i]) {
|
||||||
|
n_non_lowlat -= data.n_interfaces[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n_non_lowlat) {
|
||||||
|
quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat;
|
||||||
|
quota_rem = QUOTA_100 - n_non_lowlat * quota -
|
||||||
|
QUOTA_LOWLAT_MIN;
|
||||||
|
} else {
|
||||||
|
quota = QUOTA_100;
|
||||||
|
quota_rem = 0;
|
||||||
|
}
|
||||||
|
} else if (num_active_macs) {
|
||||||
|
quota = QUOTA_100 / num_active_macs;
|
||||||
|
quota_rem = QUOTA_100 % num_active_macs;
|
||||||
|
} else {
|
||||||
|
/* values don't really matter - won't be used */
|
||||||
|
quota = 0;
|
||||||
|
quota_rem = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
|
for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
|
||||||
|
@ -214,6 +245,10 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
|
||||||
if (data.n_interfaces[i] <= 0) {
|
if (data.n_interfaces[i] <= 0) {
|
||||||
cmd.quotas[idx].quota = cpu_to_le32(0);
|
cmd.quotas[idx].quota = cpu_to_le32(0);
|
||||||
cmd.quotas[idx].max_duration = cpu_to_le32(0);
|
cmd.quotas[idx].max_duration = cpu_to_le32(0);
|
||||||
|
} else if (data.n_low_latency_bindings == 1 && n_non_lowlat &&
|
||||||
|
data.low_latency[i]) {
|
||||||
|
cmd.quotas[idx].quota = cpu_to_le32(QUOTA_LOWLAT_MIN);
|
||||||
|
cmd.quotas[idx].max_duration = cpu_to_le32(0);
|
||||||
} else {
|
} else {
|
||||||
cmd.quotas[idx].quota =
|
cmd.quotas[idx].quota =
|
||||||
cpu_to_le32(quota * data.n_interfaces[i]);
|
cpu_to_le32(quota * data.n_interfaces[i]);
|
||||||
|
|
Loading…
Reference in New Issue