Skip to content

Commit

Permalink
wifi: mac80211: switch airtime fairness back to deficit round-robin s…
Browse files Browse the repository at this point in the history
…cheduling

This reverts commits 6a789ba and
2433647.

The virtual time scheduler code has a number of issues:
- queues slowed down by hardware/firmware powersave handling were not properly
  handled.
- on ath10k in push-pull mode, tx queues that the driver tries to pull from
  were starved, causing excessive latency
- delay between tx enqueue and reported airtime use were causing excessively
  bursty tx behavior

The bursty behavior may also be present on the round-robin scheduler, but there
it is much easier to fix without introducing additional regressions

Signed-off-by: Felix Fietkau <[email protected]>
Acked-by: Toke Høiland-Jørgensen <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Johannes Berg <[email protected]>
  • Loading branch information
nbd168 authored and jmberg-intel committed Jul 1, 2022
1 parent 7f884ba commit 942741d
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 654 deletions.
17 changes: 14 additions & 3 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -6832,6 +6832,9 @@ static inline void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
{
}

void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
struct ieee80211_txq *txq, bool force);

/**
* ieee80211_schedule_txq - schedule a TXQ for transmission
*
Expand All @@ -6844,7 +6847,11 @@ static inline void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
* The driver may call this function if it has buffered packets for
* this TXQ internally.
*/
void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
static inline void
ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
{
__ieee80211_schedule_txq(hw, txq, true);
}

/**
* ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
Expand All @@ -6856,8 +6863,12 @@ void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
* The driver may set force=true if it has buffered packets for this TXQ
* internally.
*/
void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
bool force);
static inline void
ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
bool force)
{
__ieee80211_schedule_txq(hw, txq, force);
}

/**
* ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
Expand Down
35 changes: 1 addition & 34 deletions net/mac80211/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1581,38 +1581,6 @@ static void sta_apply_mesh_params(struct ieee80211_local *local,
#endif
}

static void sta_apply_airtime_params(struct ieee80211_local *local,
struct sta_info *sta,
struct station_parameters *params)
{
u8 ac;

for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
struct airtime_sched_info *air_sched = &local->airtime[ac];
struct airtime_info *air_info = &sta->airtime[ac];
struct txq_info *txqi;
u8 tid;

spin_lock_bh(&air_sched->lock);
for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
if (air_info->weight == params->airtime_weight ||
!sta->sta.txq[tid] ||
ac != ieee80211_ac_from_tid(tid))
continue;

airtime_weight_set(air_info, params->airtime_weight);

txqi = to_txq_info(sta->sta.txq[tid]);
if (RB_EMPTY_NODE(&txqi->schedule_order))
continue;

ieee80211_update_airtime_weight(local, air_sched,
0, true);
}
spin_unlock_bh(&air_sched->lock);
}
}

static int sta_apply_parameters(struct ieee80211_local *local,
struct sta_info *sta,
struct station_parameters *params)
Expand Down Expand Up @@ -1811,8 +1779,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
sta_apply_mesh_params(local, sta, params);

if (params->airtime_weight)
sta_apply_airtime_params(local, sta, params);

sta->airtime_weight = params->airtime_weight;

/* set the STA state after all sta info from usermode has been set */
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) ||
Expand Down
70 changes: 13 additions & 57 deletions net/mac80211/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,14 @@ static ssize_t aql_txq_limit_read(struct file *file,
"VI %u %u\n"
"BE %u %u\n"
"BK %u %u\n",
local->airtime[IEEE80211_AC_VO].aql_txq_limit_low,
local->airtime[IEEE80211_AC_VO].aql_txq_limit_high,
local->airtime[IEEE80211_AC_VI].aql_txq_limit_low,
local->airtime[IEEE80211_AC_VI].aql_txq_limit_high,
local->airtime[IEEE80211_AC_BE].aql_txq_limit_low,
local->airtime[IEEE80211_AC_BE].aql_txq_limit_high,
local->airtime[IEEE80211_AC_BK].aql_txq_limit_low,
local->airtime[IEEE80211_AC_BK].aql_txq_limit_high);
local->aql_txq_limit_low[IEEE80211_AC_VO],
local->aql_txq_limit_high[IEEE80211_AC_VO],
local->aql_txq_limit_low[IEEE80211_AC_VI],
local->aql_txq_limit_high[IEEE80211_AC_VI],
local->aql_txq_limit_low[IEEE80211_AC_BE],
local->aql_txq_limit_high[IEEE80211_AC_BE],
local->aql_txq_limit_low[IEEE80211_AC_BK],
local->aql_txq_limit_high[IEEE80211_AC_BK]);
return simple_read_from_buffer(user_buf, count, ppos,
buf, len);
}
Expand Down Expand Up @@ -255,11 +255,11 @@ static ssize_t aql_txq_limit_write(struct file *file,
if (ac >= IEEE80211_NUM_ACS)
return -EINVAL;

q_limit_low_old = local->airtime[ac].aql_txq_limit_low;
q_limit_high_old = local->airtime[ac].aql_txq_limit_high;
q_limit_low_old = local->aql_txq_limit_low[ac];
q_limit_high_old = local->aql_txq_limit_high[ac];

local->airtime[ac].aql_txq_limit_low = q_limit_low;
local->airtime[ac].aql_txq_limit_high = q_limit_high;
local->aql_txq_limit_low[ac] = q_limit_low;
local->aql_txq_limit_high[ac] = q_limit_high;

mutex_lock(&local->sta_mtx);
list_for_each_entry(sta, &local->sta_list, list) {
Expand Down Expand Up @@ -382,46 +382,6 @@ static const struct file_operations force_tx_status_ops = {
.llseek = default_llseek,
};

static ssize_t airtime_read(struct file *file,
char __user *user_buf,
size_t count,
loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
char buf[200];
u64 v_t[IEEE80211_NUM_ACS];
u64 wt[IEEE80211_NUM_ACS];
int len = 0, ac;

for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
spin_lock_bh(&local->airtime[ac].lock);
v_t[ac] = local->airtime[ac].v_t;
wt[ac] = local->airtime[ac].weight_sum;
spin_unlock_bh(&local->airtime[ac].lock);
}
len = scnprintf(buf, sizeof(buf),
"\tVO VI BE BK\n"
"Virt-t\t%-10llu %-10llu %-10llu %-10llu\n"
"Weight\t%-10llu %-10llu %-10llu %-10llu\n",
v_t[0],
v_t[1],
v_t[2],
v_t[3],
wt[0],
wt[1],
wt[2],
wt[3]);

return simple_read_from_buffer(user_buf, count, ppos,
buf, len);
}

static const struct file_operations airtime_ops = {
.read = airtime_read,
.open = simple_open,
.llseek = default_llseek,
};

#ifdef CONFIG_PM
static ssize_t reset_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
Expand Down Expand Up @@ -675,11 +635,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
if (local->ops->wake_tx_queue)
DEBUGFS_ADD_MODE(aqm, 0600);

if (wiphy_ext_feature_isset(local->hw.wiphy,
NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) {
DEBUGFS_ADD_MODE(airtime, 0600);
DEBUGFS_ADD_MODE(airtime_flags, 0600);
}
DEBUGFS_ADD_MODE(airtime_flags, 0600);

DEBUGFS_ADD(aql_txq_limit);
debugfs_create_u32("aql_threshold", 0600,
Expand Down
32 changes: 1 addition & 31 deletions net/mac80211/debugfs_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,34 +510,6 @@ static ssize_t ieee80211_if_fmt_aqm(
}
IEEE80211_IF_FILE_R(aqm);

static ssize_t ieee80211_if_fmt_airtime(
const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_txq *txq = sdata->vif.txq;
struct airtime_info *air_info;
int len;

if (!txq)
return 0;

spin_lock_bh(&local->airtime[txq->ac].lock);
air_info = to_airtime_info(txq);
len = scnprintf(buf,
buflen,
"RX: %llu us\nTX: %llu us\nWeight: %u\n"
"Virt-T: %lld us\n",
air_info->rx_airtime,
air_info->tx_airtime,
air_info->weight,
air_info->v_t);
spin_unlock_bh(&local->airtime[txq->ac].lock);

return len;
}

IEEE80211_IF_FILE_R(airtime);

IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX);

/* IBSS attributes */
Expand Down Expand Up @@ -683,10 +655,8 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata)

if (sdata->local->ops->wake_tx_queue &&
sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
sdata->vif.type != NL80211_IFTYPE_NAN) {
sdata->vif.type != NL80211_IFTYPE_NAN)
DEBUGFS_ADD(aqm);
DEBUGFS_ADD(airtime);
}
}

static void add_sta_files(struct ieee80211_sub_if_data *sdata)
Expand Down
24 changes: 12 additions & 12 deletions net/mac80211/debugfs_sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,26 +202,26 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
size_t bufsz = 400;
char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
u64 rx_airtime = 0, tx_airtime = 0;
u64 v_t[IEEE80211_NUM_ACS];
s64 deficit[IEEE80211_NUM_ACS];
ssize_t rv;
int ac;

if (!buf)
return -ENOMEM;

for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
spin_lock_bh(&local->airtime[ac].lock);
spin_lock_bh(&local->active_txq_lock[ac]);
rx_airtime += sta->airtime[ac].rx_airtime;
tx_airtime += sta->airtime[ac].tx_airtime;
v_t[ac] = sta->airtime[ac].v_t;
spin_unlock_bh(&local->airtime[ac].lock);
deficit[ac] = sta->airtime[ac].deficit;
spin_unlock_bh(&local->active_txq_lock[ac]);
}

p += scnprintf(p, bufsz + buf - p,
"RX: %llu us\nTX: %llu us\nWeight: %u\n"
"Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
rx_airtime, tx_airtime, sta->airtime[0].weight,
v_t[0], v_t[1], v_t[2], v_t[3]);
"Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
rx_airtime, tx_airtime, sta->airtime_weight,
deficit[0], deficit[1], deficit[2], deficit[3]);

rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
kfree(buf);
Expand All @@ -236,11 +236,11 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
int ac;

for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
spin_lock_bh(&local->airtime[ac].lock);
spin_lock_bh(&local->active_txq_lock[ac]);
sta->airtime[ac].rx_airtime = 0;
sta->airtime[ac].tx_airtime = 0;
sta->airtime[ac].v_t = 0;
spin_unlock_bh(&local->airtime[ac].lock);
sta->airtime[ac].deficit = sta->airtime_weight;
spin_unlock_bh(&local->active_txq_lock[ac]);
}

return count;
Expand All @@ -263,10 +263,10 @@ static ssize_t sta_aql_read(struct file *file, char __user *userbuf,
return -ENOMEM;

for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
spin_lock_bh(&local->airtime[ac].lock);
spin_lock_bh(&local->active_txq_lock[ac]);
q_limit_l[ac] = sta->airtime[ac].aql_limit_low;
q_limit_h[ac] = sta->airtime[ac].aql_limit_high;
spin_unlock_bh(&local->airtime[ac].lock);
spin_unlock_bh(&local->active_txq_lock[ac]);
q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending);
}

Expand Down
Loading

0 comments on commit 942741d

Please sign in to comment.