diff mbox series

[RFC,v3,1/1] mac80211: use AQL airtime for expected throughput.

Message ID 20220531100922.491344-1-gasmibal@gmail.com
State Superseded
Headers show
Series [RFC,v3,1/1] mac80211: use AQL airtime for expected throughput. | expand

Commit Message

Baligh GASMI May 31, 2022, 10:09 a.m. UTC
Since the integration of AQL, packet TX airtime estimation is
calculated and counted to be used for the dequeue limit.

Use this estimated airtime to compute expected throughput for
each station.

It will be a generic mac80211 implementation. If the driver has
get_expected_throughput implementation, it will be used instead.

Useful for L2 routing protocols, like B.A.T.M.A.N.

Signed-off-by: Baligh Gasmi <gasmibal@gmail.com>
---
 net/mac80211/driver-ops.h |  2 ++
 net/mac80211/sta_info.c   | 39 +++++++++++++++++++++++++++++++++++++++
 net/mac80211/sta_info.h   | 11 +++++++++++
 net/mac80211/status.c     |  2 ++
 net/mac80211/tx.c         |  8 +++++++-
 5 files changed, 61 insertions(+), 1 deletion(-)

Comments

Baligh GASMI May 31, 2022, 2:26 p.m. UTC | #1
Hi,
>
> On Tue, May 31, 2022 at 12:09:22PM +0200, Baligh Gasmi wrote:
> > Since the integration of AQL, packet TX airtime estimation is
> > calculated and counted to be used for the dequeue limit.
> >
> > Use this estimated airtime to compute expected throughput for
> > each station.
> >
> > It will be a generic mac80211 implementation. If the driver has
> > get_expected_throughput implementation, it will be used instead.
> >
> > Useful for L2 routing protocols, like B.A.T.M.A.N.
> >
> > Signed-off-by: Baligh Gasmi <gasmibal@gmail.com>
>
> Hi Baligh,
>
> Thanks for your work, this indeed sounds very relevant for
> batman-adv. Do you have some test results on how this compares to
> real throughput? And maybe how it compares to other methods we
> already have in the kernel, like expected throughput via
> minstrel_ht rate control or the estimates performed in 802.11s
> HWMP [0]?

I'll share a comparison between an iperf3 running and the current
value of this implementation.
What I can say, for now, is that they are close to each other.
The minstrel_ht still a better implementation for expected throughput.
That's why if there is minstrel_ht support, it will be used instead of
this implementation.
However, 802.11s metric is another story, it's a parameter used by the
HWMP routing protocol for the path selection, so it could be based on
the expected throughput, but it includes other factors that could be
mesh specific.
For me, 802.11s metric and expected throughput are not necessarily the
same values.

>
> Is there a certain minimum amount of traffic you'd suggest to have
> enough samples to get a meaningful result?

I'm using a burst of 50 ARP packets, padded to have 1024 bytes.
(to be optimized)

>
> I'm also wondering if we are starting to accumulate too many
> places to provide wifi expected throughput calculations. Do you
> see a chance that this generic mac80211 implementation could be made
> good enough to be used as the sole source for both batman-adv and
> 802.11s HWMP, for instance? Or do you see some pros and cons
> between the different methods?
>

I think that this implementation is still based on an estimation, so
it's not good as a minstrel.
It's based on the AQL airtime estimation. With a phy_rate of the last
sent packet, and average aggregated packets, and other stuff ...
The whole idea is not to replace current implementation, but to extend
other drivers (to have something is better than having nothing !)
Since batman-adv needs the expected throughput to make a decision, it
will get a value regardless of the driver implementation.

> Regards, Linus
>
>
> [0]: https://elixir.bootlin.com/linux/v5.18/source/net/mac80211/mesh_hwmp.c#L295
Kalle Valo June 1, 2022, 5:48 a.m. UTC | #2
Baligh Gasmi <gasmibal@gmail.com> writes:

> Since the integration of AQL, packet TX airtime estimation is
> calculated and counted to be used for the dequeue limit.
>
> Use this estimated airtime to compute expected throughput for
> each station.
>
> It will be a generic mac80211 implementation. If the driver has
> get_expected_throughput implementation, it will be used instead.
>
> Useful for L2 routing protocols, like B.A.T.M.A.N.
>
> Signed-off-by: Baligh Gasmi <gasmibal@gmail.com>

Please include a changelog to show what has changed since previous
versions:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#changelog_missing
diff mbox series

Patch

diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 4e2fc1a08681..fa9952154795 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1142,6 +1142,8 @@  static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
 	trace_drv_get_expected_throughput(&sta->sta);
 	if (local->ops->get_expected_throughput && sta->uploaded)
 		ret = local->ops->get_expected_throughput(&local->hw, &sta->sta);
+	else
+		ret = ewma_avg_est_tp_read(&sta->deflink.status_stats.avg_est_tp);
 	trace_drv_return_u32(local, ret);
 
 	return ret;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index e04a0905e941..201aab465234 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1993,6 +1993,45 @@  void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
 			       tx_pending, 0);
 }
 
+void ieee80211_sta_update_tp(struct ieee80211_local *local,
+			     struct sta_info *sta,
+			     struct sk_buff *skb,
+			     u16 tx_time_est,
+			     bool ack, int retry)
+{
+	unsigned long diff;
+	struct rate_control_ref *ref = NULL;
+
+	if (!skb || !sta || !tx_time_est)
+		return;
+
+	if (test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
+		ref = sta->rate_ctrl;
+
+	if (ref && ref->ops->get_expected_throughput)
+		return;
+
+	if (local->ops->get_expected_throughput)
+		return;
+
+	tx_time_est += ack ? 4 : 0;
+	tx_time_est += retry ? retry * 2 : 2;
+
+	sta->deflink.tx_stats.tp_tx_size += (skb->len * 8) * 1000;
+	sta->deflink.tx_stats.tp_tx_time_est += tx_time_est;
+
+	diff = jiffies - sta->deflink.status_stats.last_tp_update;
+	if (diff > HZ / 10) {
+		ewma_avg_est_tp_add(&sta->deflink.status_stats.avg_est_tp,
+				    sta->deflink.tx_stats.tp_tx_size /
+				    sta->deflink.tx_stats.tp_tx_time_est);
+
+		sta->deflink.tx_stats.tp_tx_size = 0;
+		sta->deflink.tx_stats.tp_tx_time_est = 0;
+		sta->deflink.status_stats.last_tp_update = jiffies;
+	}
+}
+
 int sta_info_move_state(struct sta_info *sta,
 			enum ieee80211_sta_state new_state)
 {
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 35c390bedfba..4200856fefcd 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -123,6 +123,7 @@  enum ieee80211_sta_info_flags {
 #define HT_AGG_STATE_STOP_CB		7
 #define HT_AGG_STATE_SENT_ADDBA		8
 
+DECLARE_EWMA(avg_est_tp, 8, 16)
 DECLARE_EWMA(avg_signal, 10, 8)
 enum ieee80211_agg_stop_reason {
 	AGG_STOP_DECLINED,
@@ -157,6 +158,12 @@  void ieee80211_register_airtime(struct ieee80211_txq *txq,
 
 struct sta_info;
 
+void ieee80211_sta_update_tp(struct ieee80211_local *local,
+			     struct sta_info *sta,
+			     struct sk_buff *skb,
+			     u16 tx_time_est,
+			     bool ack, int retry);
+
 /**
  * struct tid_ampdu_tx - TID aggregation information (Tx).
  *
@@ -549,6 +556,8 @@  struct link_sta_info {
 		s8 last_ack_signal;
 		bool ack_signal_filled;
 		struct ewma_avg_signal avg_ack_signal;
+		struct ewma_avg_est_tp avg_est_tp;
+		unsigned long last_tp_update;
 	} status_stats;
 
 	/* Updated from TX path only, no locking requirements */
@@ -558,6 +567,8 @@  struct link_sta_info {
 		struct ieee80211_tx_rate last_rate;
 		struct rate_info last_rate_info;
 		u64 msdu[IEEE80211_NUM_TIDS + 1];
+		u64 tp_tx_size;
+		u64 tp_tx_time_est;
 	} tx_stats;
 
 	enum ieee80211_sta_rx_bandwidth cur_max_bandwidth;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index e69272139437..1fb93abc1709 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -1152,6 +1152,8 @@  void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 	ack_signal_valid =
 		!!(info->status.flags & IEEE80211_TX_STATUS_ACK_SIGNAL_VALID);
 
+	ieee80211_sta_update_tp(local, sta, skb, tx_time_est, acked, retry_count);
+
 	if (pubsta) {
 		struct ieee80211_sub_if_data *sdata = sta->sdata;
 
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0e4efc08c762..e58d89c108a4 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3632,6 +3632,7 @@  struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 	struct ieee80211_tx_data tx;
 	ieee80211_tx_result r;
 	struct ieee80211_vif *vif = txq->vif;
+	struct rate_control_ref *ref = NULL;
 
 	WARN_ON_ONCE(softirq_count() == 0);
 
@@ -3790,8 +3791,13 @@  struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 encap_out:
 	IEEE80211_SKB_CB(skb)->control.vif = vif;
 
+	if (tx.sta && test_sta_flag(tx.sta, WLAN_STA_RATE_CONTROL))
+		ref = tx.sta->deflink.rate_ctrl;
+
 	if (vif &&
-	    wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
+	    ((!local->ops->get_expected_throughput &&
+	     (!ref || !ref->ops->get_expected_throughput)) ||
+	    wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))) {
 		bool ampdu = txq->ac != IEEE80211_AC_VO;
 		u32 airtime;