2019-12-13 07:24:53

by Yibo Zhao

[permalink] [raw]
Subject: [PATCH 3/4] mac80211: fix low throughput in multi-clients situation

Not long after the start of multi-clients test, not a single station is
an eligible candidate for transmission since global virtual time(g_vt) is
smaller than the virtual airtime(s_vt) of all the stations. As a result,
the Tx has been blocked and throughput is quite low.

This may mainly due accumulative deviation from the devision calculation
of g_vt.

For example:
Suppose we have 50 clients in first round.
Round 1:
STA weight Tx_time_round wt_sum s_vt g_vt valid_for_next_Tx
1 256 2048 12800 2048 2000 N
2 256 2048 2048 N
. . . . .
. . . . .
. . . . .
50 256 2048 2048 N

After this round, all the stations are not valid for next transmission due to
accumulative deviation.

The real situation can be more complicate, above is one of the extremely case.

To avoid this situation to occur, the new proposal is:

- If global virtual time is less than the virtual airtime of any station,
sync it to the airtime of first station in the red-black tree

- Round the division result

Signed-off-by: Yibo Zhao <[email protected]>
---
net/mac80211/sta_info.c | 3 ++-
net/mac80211/tx.c | 16 +++++++++++++++-
2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 9d01fdd..feac975 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1852,7 +1852,8 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,

weight_sum = local->airtime_weight_sum[ac] ?: sta->airtime_weight;

- local->airtime_v_t[ac] += airtime / weight_sum;
+ /* Round the calculation of global vt */
+ local->airtime_v_t[ac] += (airtime + (weight_sum >> 1)) / weight_sum;
sta->airtime[ac].v_t += airtime / sta->airtime_weight;
ieee80211_resort_txq(&local->hw, txq);

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c1444e7..b40cf91 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3822,15 +3822,29 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
struct ieee80211_txq *txq)
{
struct ieee80211_local *local = hw_to_local(hw);
- struct txq_info *txqi = to_txq_info(txq);
+ struct txq_info *first_txqi, *txqi = to_txq_info(txq);
+ struct rb_node *node = NULL;
struct sta_info *sta;
u8 ac = txq->ac;
+ first_txqi = NULL;

lockdep_assert_held(&local->active_txq_lock[ac]);

if (!txqi->txq.sta)
return true;

+ node = rb_first_cached(&local->active_txqs[ac]);
+ if (node) {
+ first_txqi = container_of(node, struct txq_info,
+ schedule_order);
+ if (first_txqi->txq.sta) {
+ sta = container_of(first_txqi->txq.sta,
+ struct sta_info, sta);
+ if (local->airtime_v_t[ac] < sta->airtime[ac].v_t)
+ local->airtime_v_t[ac] = sta->airtime[ac].v_t;
+ }
+ }
+
sta = container_of(txqi->txq.sta, struct sta_info, sta);
return (sta->airtime[ac].v_t <= local->airtime_v_t[ac]);
}
--
1.9.1


2020-01-08 11:19:13

by Justin Capella

[permalink] [raw]
Subject: Re: [PATCH 3/4] mac80211: fix low throughput in multi-clients situation

Is there a risk of division by zero?

I'm curious about IEEE80211_AIRTIME_QUANTUM in this multiple sta
scenario, should weight maybe be the depth of the queue or something
like that? Using real time delta I assume is not performant?

2020-01-08 11:32:31

by Toke Høiland-Jørgensen

[permalink] [raw]
Subject: Re: [PATCH 3/4] mac80211: fix low throughput in multi-clients situation

Justin Capella <[email protected]> writes:

> Is there a risk of division by zero?

No, weights are always positive.

> I'm curious about IEEE80211_AIRTIME_QUANTUM in this multiple sta
> scenario, should weight maybe be the depth of the queue or something
> like that? Using real time delta I assume is not performant?

Eh?

-Toke