[Make-wifi-fast] [PATCH 1/2] mac80211: Implement Airtime-based Queue Limit (AQL)
Toke Høiland-Jørgensen
toke at redhat.com
Fri Oct 4 11:44:30 EDT 2019
Kan Yan <kyan at google.com> writes:
> In order for the Fq_CoDel integrated in mac80211 layer operates
> effectively to control excessive queueing latency, the CoDel algorithm
> requires an accurate measure of how long the packets stays in the
> queue, aka sojourn time. The sojourn time measured at mac80211 layer
> doesn't include queueing latency in lower layer (firmware/hardware)
> and CoDel expects lower layer to have a short queue. However, most
> 802.11ac chipsets offload tasks such TX aggregation to firmware or
> hardware, thus have a deep lower layer queue. Without a mechanism to
> control the lower layer queue size, packets only stays in mac80211
> layer transiently before being released to firmware due to the deep
> queue in the lower layer. In this case, the sojourn time measured by
> CoDel in the mac80211 layer is always lower than the CoDel latency
> target hence it does little to control the latency, even when the lower
> layer queue causes excessive latency.
>
> Byte Queue limits (BQL) is commonly used to address the similar issue
> with wired network interface. However, this method can not be applied
> directly to the wireless network interface. Byte is not a suitable
> measure of queue depth in the wireless network, as the data rate can
> vary dramatically from station to station in the same network, from a
> few Mbps to over 1 Gbps.
>
> This patch implemented an Airtime-based Queue Limit (AQL) to make CoDel
> works effectively with wireless drivers that utilized firmware/hardware
> offloading. It only allows each txq to release just enough packets to
> form 1-2 large aggregations to keep hardware fully utilized and keep the
> rest of frames in mac80211 layer to be controlled by CoDel.
>
> Change-Id: I1427db2c4c7fcb4162b087514dcb06d5613fa5d2
> Signed-off-by: Kan Yan <kyan at google.com>
> ---
> include/net/cfg80211.h | 7 ++++
> include/net/mac80211.h | 34 ++++++++++++++++
> net/mac80211/debugfs.c | 79 ++++++++++++++++++++++++++++++++++++++
> net/mac80211/debugfs_sta.c | 43 +++++++++++++++------
> net/mac80211/ieee80211_i.h | 4 ++
> net/mac80211/main.c | 7 +++-
> net/mac80211/sta_info.c | 23 +++++++++++
> net/mac80211/sta_info.h | 4 ++
> net/mac80211/tx.c | 60 ++++++++++++++++++++++++-----
> 9 files changed, 239 insertions(+), 22 deletions(-)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 26e2ad2c7027..301c11be366a 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -2499,6 +2499,13 @@ enum wiphy_params_flags {
>
> #define IEEE80211_DEFAULT_AIRTIME_WEIGHT 256
>
> +/* The per TXQ firmware queue limit in airtime */
> +#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 4000
> +#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 8000
> +
> +/* The firmware's transmit queue size limit in airtime */
> +#define IEEE80211_DEFAULT_AQL_INTERFACE_LIMIT 24000
> +
> /**
> * struct cfg80211_pmksa - PMK Security Association
> *
> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
> index d26da013f7c0..4d62aba3e4b2 100644
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -5543,6 +5543,40 @@ void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid);
> void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
> u32 tx_airtime, u32 rx_airtime);
>
> +/**
> + * ieee80211_sta_register_pending_airtime - register the estimated airtime for
> + * the frames pending in lower layer (firmware/hardware) txq.
> + *
> + * Update the total pending airtime of the frames released to firmware. The
> + * pending airtime is used by AQL to control queue size in the lower layer.
> + *
> + * The airtime is estimated using frame length and the last reported data
> + * rate. The pending airtime for a txq is increased by the estimated
> + * airtime when the frame is relased to the lower layer, and decreased by the
> + * same amount at the tx completion event.
> + *
> + * @pubsta: the station
> + * @tid: the TID to register airtime for
> + * @tx_airtime: the estimated airtime (in usec)
> + * @tx_commpleted: true if called from the tx completion event.
> + */
> +void ieee80211_sta_register_pending_airtime(struct ieee80211_sta *pubsta,
> + u8 tid, u32 tx_airtime,
> + bool tx_completed);
> +
> +/**
> + * ieee80211_txq_aritme_check - check if the airtime limit of AQL (Airtime based
> + * queue limit) has been reached.
> + * @hw: pointer obtained from ieee80211_alloc_hw()
> + * @txq: pointer obtained from station or virtual interface
> + * Retrun true if the queue limit has not been reached and txq can continue to
> + * release packets to the lower layer.
> + * Return false if the queue limit has been reached and the txq should not
> + * release more frames to the lower layer.
> + */
> +bool
> +ieee80211_txq_airtime_check(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
> +
So I think it'll be better to pass up the last_rate and have mac80211
calculate the airtime (like I did in my patch set). But we can keep the
rest of your logic and just switch the calculation, I guess?
I'd like to use the new rate calculation code that Felix added to mt76.
Is the arsta->txrate info in ath10k suitable to be passed up to mac80211
and used in that, do you think? Because then that would probably be the
easiest way to go about it...
[...]
> @@ -3726,9 +3733,7 @@ void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
> * get immediately moved to the back of the list on the next
> * call to ieee80211_next_txq().
> */
> - if (txqi->txq.sta &&
> - wiphy_ext_feature_isset(local->hw.wiphy,
> - NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
> + if (txqi->txq.sta && local->airtime_flags & AIRTIME_USE_TX)
This is wrong. The USE_TX/USE_RX flags just set which types of airtime
will be subtracted from the deficit. We should still be running the
scheduler if *either* of them is set...
> list_add(&txqi->schedule_order,
> &local->active_txqs[txq->ac]);
> else
> @@ -3740,6 +3745,37 @@ void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
> }
> EXPORT_SYMBOL(__ieee80211_schedule_txq);
>
> +bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq)
> +{
> + struct sta_info *sta;
> + struct ieee80211_local *local = hw_to_local(hw);
> +
> +
> + if (!(local->airtime_flags & AIRTIME_USE_TX))
Ditto.
> + return true;
> +
> + if (!txq->sta)
> + return true;
> +
> + sta = container_of(txq->sta, struct sta_info, sta);
> + if (sta->airtime[txq->ac].deficit < 0)
> + return false;
> +
> + if (!(local->airtime_flags & AIRTIME_USE_AQL))
> + return true;
> +
> + if ((sta->airtime[txq->ac].aql_tx_pending <
> + sta->airtime[txq->ac].aql_limit_low) ||
> + (local->aql_total_pending_airtime < local->aql_interface_limit &&
> + sta->airtime[txq->ac].aql_tx_pending <
> + sta->airtime[txq->ac].aql_limit_high))
> + return true;
> + else
> + return false;
> +}
> +EXPORT_SYMBOL(ieee80211_txq_airtime_check);
> +
> bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
> struct ieee80211_txq *txq)
> {
> @@ -3748,10 +3784,13 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
> struct sta_info *sta;
> u8 ac = txq->ac;
>
> - spin_lock_bh(&local->active_txq_lock[ac]);
> -
> if (!txqi->txq.sta)
> - goto out;
> + return true;
> +
> + if (!(local->airtime_flags & AIRTIME_USE_TX))
Ditto.
-Toke
More information about the Make-wifi-fast
mailing list