Skip to contentSkip to conversation

Move TXQ scheduling and airtime fairness into mac80211

PATCH Superseded Rajkumar Manoharan 9 participants 28 messages Nov 12, 2018 – Dec 18, 2018 2 messages not in the archive

Subsystems (4)

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v3 cover Move TXQ scheduling and airtime fairness into mac80211

Here is the consolidated series of mac80211, ath9k and ath10k changes for moving TXQ scheduling and airtime fairness into mac80211 and support airtime fairness.

Three main APIs are defined for TXQ scheduling.
- ieee80211_next_txq
- ieee80211_return_txq
- ieee80211_txq_may_transmit

and two APIs for synchronization when the driver wants to iterate through all TXQs.
- ieee80211_txq_schedule_start
- ieee80211_txq_schedule_end

The earlier discussions:
https://patchwork.kernel.org/project/linux-wireless/list/?series=&submitter=&state=*&q=TXQ+scheduling&archive=both&delegate=

-Rajkumar

v2:
- replaced driver specific airtime default by multiplier
- fixed tab intent
- fixed author and commit log
v3:
- fixed checkpatch warnings and kbuild bot errors. few of over 80 char warnings are left.

Kan Yan (1):
ath10k: reporting estimated tx airtime for fairness

Toke Høiland-Jørgensen (5):
mac80211: Add TXQ scheduling API
cfg80211: Add airtime statistics and settings
mac80211: Add airtime accounting and scheduling to TXQs
ath9k: Switch to mac80211 TXQ scheduling and airtime APIs
ath10k: migrate to mac80211 txq scheduling

 drivers/net/wireless/ath/ath10k/core.c     |   2 -
 drivers/net/wireless/ath/ath10k/core.h     |   8 +-
 drivers/net/wireless/ath/ath10k/htc.h      |   1 -
 drivers/net/wireless/ath/ath10k/htt_rx.c   |   9 ++
 drivers/net/wireless/ath/ath10k/mac.c      | 155 +++++++++++-------
 drivers/net/wireless/ath/ath10k/txrx.c     |   4 +
 drivers/net/wireless/ath/ath9k/ath9k.h     |  14 --
 drivers/net/wireless/ath/ath9k/debug.c     |   3 -
 drivers/net/wireless/ath/ath9k/debug.h     |   8 -
 drivers/net/wireless/ath/ath9k/debug_sta.c |  70 ---------
 drivers/net/wireless/ath/ath9k/init.c      |   3 +-
 drivers/net/wireless/ath/ath9k/recv.c      |   9 +-
 drivers/net/wireless/ath/ath9k/xmit.c      | 244 +++++++++--------------------
 include/net/cfg80211.h                     |  10 +-
 include/net/mac80211.h                     | 121 +++++++++++++-
 include/uapi/linux/nl80211.h               |  15 ++
 net/mac80211/agg-tx.c                      |   2 +-
 net/mac80211/cfg.c                         |   3 +
 net/mac80211/debugfs.c                     |   3 +
 net/mac80211/debugfs_sta.c                 |  50 +++++-
 net/mac80211/driver-ops.h                  |   9 ++
 net/mac80211/ieee80211_i.h                 |  11 ++
 net/mac80211/main.c                        |   9 ++
 net/mac80211/sta_info.c                    |  46 +++++-
 net/mac80211/sta_info.h                    |  13 ++
 net/mac80211/status.c                      |   6 +
 net/mac80211/tx.c                          | 140 ++++++++++++++++-
 net/wireless/nl80211.c                     |  30 ++++
 28 files changed, 644 insertions(+), 354 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH v3 1/6 mac80211: Add TXQ scheduling API

From: Toke Høiland-Jørgensen <[email protected]>

This adds an API to mac80211 to handle scheduling of TXQs. The interface between driver and mac80211 for TXQ handling is changed by adding two new
functions: ieee80211_next_txq(), which will return the next TXQ to schedule in the current round-robin rotation, and ieee80211_return_txq(), which the driver uses to indicate that it has finished scheduling a TXQ (which will then be put back in the scheduling rotation if it isn't empty).

The driver must call ieee80211_txq_schedule_start() at the start of each scheduling session, and ieee80211_txq_schedule_end() at the end. The API then guarantees that the same TXQ is not returned twice in the same session (so a driver can loop on ieee80211_next_txq() without worrying about breaking the loop.

Usage of the new API is optional, so drivers can be ported one at a time. In this patch, the actual scheduling performed by mac80211 is simple round-robin, but a subsequent commit adds airtime fairness awareness to the scheduler.

---
 include/net/mac80211.h     | 62 +++++++++++++++++++++++++++++++++++++++++++---
 net/mac80211/agg-tx.c      |  2 +-
 net/mac80211/driver-ops.h  |  9 +++++++
 net/mac80211/ieee80211_i.h |  9 +++++++
 net/mac80211/main.c        |  5 ++++
 net/mac80211/sta_info.c    |  2 +-
 net/mac80211/tx.c          | 58 ++++++++++++++++++++++++++++++++++++++++++-
 7 files changed, 140 insertions(+), 7 deletions(-)
include/net/mac80211.h +58 -4
index 71985e95d2d9..18b11c119b7e 100644
@@ -108,9 +108,15 @@
  * The driver is expected to initialize its private per-queue data for stations
  * and interfaces in the .add_interface and .sta_add ops.
  *
- * The driver can't access the queue directly. To dequeue a frame, it calls
- * ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a queue, it
- * calls the .wake_tx_queue driver op.
+ * The driver can't access the queue directly. To dequeue a frame from a
+ * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a
+ * queue, it calls the .wake_tx_queue driver op.
+ *
+ * Drivers can optionally delegate responsibility for scheduling queues to
+ * mac80211, to take advantage of airtime fairness accounting. In this case, to
+ * obtain the next queue to pull frames from, the driver calls
+ * ieee80211_next_txq(). The driver is then expected to return the txq using
+ * ieee80211_return_txq().
  *
  * For AP powersave TIM handling, the driver only needs to indicate if it has
  * buffered packets in the driver specific data structures by calling
@@ -6088,7 +6094,8 @@ void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
  * ieee80211_tx_dequeue - dequeue a packet from a software tx queue
  *
  * @hw: pointer as obtained from ieee80211_alloc_hw()
- * @txq: pointer obtained from station or virtual interface
+ * @txq: pointer obtained from station or virtual interface, or from
+ *	ieee80211_next_txq()
  *
  * Returns the skb if successful, %NULL if no frame was available.
  */
@@ -6096,6 +6103,53 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 				     struct ieee80211_txq *txq);
 
 /**
+ * ieee80211_next_txq - get next tx queue to pull packets from
+ *
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @ac: AC number to return packets from.
+ *
+ * Should only be called between calls to ieee80211_txq_schedule_start()
+ * and ieee80211_txq_schedule_end().
+ * Returns the next txq if successful, %NULL if no queue is eligible. If a txq
+ * is returned, it should be returned with ieee80211_return_txq() after the
+ * driver has finished scheduling it.
+ */
+struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac);
+
+/**
+ * ieee80211_return_txq - return a TXQ previously acquired by
+ * ieee80211_next_txq()
+ *
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @txq: pointer obtained from station or virtual interface
+ *
+ * Should only be called between calls to ieee80211_txq_schedule_start()
+ * and ieee80211_txq_schedule_end().
+ */
+void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
+
+/**
+ * ieee80211_txq_schedule_start - acquire locks for safe scheduling of an AC
+ *
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @ac: AC number to acquire locks for
+ *
+ * Acquire locks needed to schedule TXQs from the given AC. Should be called
+ * before ieee80211_next_txq() or ieee80211_return_txq().
+ */
+void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac);
+
+/**
+ * ieee80211_txq_schedule_end - release locks for safe scheduling of an AC
+ *
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @ac: AC number to acquire locks for
+ *
+ * Release locks previously acquired by ieee80211_txq_schedule_end().
+ */
+void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac);
+
+/**
  * ieee80211_txq_get_depth - get pending frame/byte count of given txq
  *
  * The values are not guaranteed to be coherent with regard to each other, i.e.
net/mac80211/agg-tx.c +1 -1
index 69e831bc317b..e94b1a0407af 100644
@@ -229,7 +229,7 @@ static void __releases(agg_queue)
 	clear_bit(IEEE80211_TXQ_STOP, &txqi->flags);
 	local_bh_disable();
 	rcu_read_lock();
-	drv_wake_tx_queue(sta->sdata->local, txqi);
+	schedule_and_wake_txq(sta->sdata->local, txqi);
 	rcu_read_unlock();
 	local_bh_enable();
 }
net/mac80211/driver-ops.h +9 -0
index 0b1747a2313d..ce4138323820 100644
@@ -1173,6 +1173,15 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local,
 	local->ops->wake_tx_queue(&local->hw, &txq->txq);
 }
 
+static inline void schedule_and_wake_txq(struct ieee80211_local *local,
+					 struct txq_info *txqi)
+{
+	spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
+	ieee80211_return_txq(&local->hw, &txqi->txq);
+	spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
+	drv_wake_tx_queue(local, txqi);
+}
+
 static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local,
 					     struct sk_buff *head,
 					     struct sk_buff *skb)
net/mac80211/ieee80211_i.h +9 -0
index 10a05062e4a0..33763a2eac81 100644
@@ -830,6 +830,8 @@ enum txq_info_flags {
  *	a fq_flow which is already owned by a different tin
  * @def_cvars: codel vars for @def_flow
  * @frags: used to keep fragments created after dequeue
+ * @schedule_order: used with ieee80211_local->active_txqs
+ * @schedule_round: counter to prevent infinite loops on TXQ scheduling
  */
 struct txq_info {
 	struct fq_tin tin;
@@ -837,6 +839,8 @@ struct txq_info {
 	struct codel_vars def_cvars;
 	struct codel_stats cstats;
 	struct sk_buff_head frags;
+	struct list_head schedule_order;
+	u16 schedule_round;
 	unsigned long flags;
 
 	/* keep last! */
@@ -1128,6 +1132,11 @@ struct ieee80211_local {
 	struct codel_vars *cvars;
 	struct codel_params cparams;
 
+	/* protects active_txqs and txqi->schedule_order */
+	spinlock_t active_txq_lock[IEEE80211_NUM_ACS];
+	struct list_head active_txqs[IEEE80211_NUM_ACS];
+	u16 schedule_round[IEEE80211_NUM_ACS];
+
 	const struct ieee80211_ops *ops;
 
 	/*
net/mac80211/main.c +5 -0
index 83e71e6b2ebe..ba64757afea4 100644
@@ -663,6 +663,11 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 	spin_lock_init(&local->rx_path_lock);
 	spin_lock_init(&local->queue_stop_reason_lock);
 
+	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+		INIT_LIST_HEAD(&local->active_txqs[i]);
+		spin_lock_init(&local->active_txq_lock[i]);
+	}
+
 	INIT_LIST_HEAD(&local->chanctx_list);
 	mutex_init(&local->chanctx_mtx);
 
net/mac80211/sta_info.c +1 -1
index fb8c2252ac0e..c2f5cb7df54f 100644
@@ -1249,7 +1249,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
 		if (!sta->sta.txq[i] || !txq_has_queue(sta->sta.txq[i]))
 			continue;
 
-		drv_wake_tx_queue(local, to_txq_info(sta->sta.txq[i]));
+		schedule_and_wake_txq(local, to_txq_info(sta->sta.txq[i]));
 	}
 
 	skb_queue_head_init(&pending);
net/mac80211/tx.c +57 -1

82 lines not on this page · raw message

Signature · 1 line
1.9.1
#2 lore raw

PATCH v3 2/6 cfg80211: Add airtime statistics and settings

In reply to Rajkumar Manoharan

From: Toke Høiland-Jørgensen <[email protected]>

This adds TX airtime statistics to the cfg80211 station dump (to go along with the RX info already present), and adds a new parameter to set the airtime weight of each station. The latter allows userspace to implement policies for different stations by varying their weights.

---
 include/net/cfg80211.h       | 10 +++++++++-
 include/uapi/linux/nl80211.h | 15 +++++++++++++++
 net/wireless/nl80211.c       | 30 ++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 1 deletion(-)
include/net/cfg80211.h +9 -1
index 1fa41b7a1be3..f1312f17fbef 100644
@@ -1001,6 +1001,7 @@ enum station_parameters_apply_mask {
  * @support_p2p_ps: information if station supports P2P PS mechanism
  * @he_capa: HE capabilities of station
  * @he_capa_len: the length of the HE capabilities
+ * @airtime_weight: airtime scheduler weight for this station
  */
 struct station_parameters {
 	const u8 *supported_rates;
@@ -1030,6 +1031,7 @@ struct station_parameters {
 	int support_p2p_ps;
 	const struct ieee80211_he_cap_elem *he_capa;
 	u8 he_capa_len;
+	u16 airtime_weight;
 };
 
 /**
@@ -1297,6 +1299,8 @@ struct cfg80211_tid_stats {
  * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received
  *	from this peer
  * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer
+ * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer
+ * @airtime_weight: current airtime scheduling weight
  * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last
  *	(IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs.
  *	Note that this doesn't use the @filled bit, but is used if non-NULL.
@@ -1347,10 +1351,12 @@ struct station_info {
 
 	u32 expected_throughput;
 
-	u64 rx_beacon;
+	u64 tx_duration;
 	u64 rx_duration;
+	u64 rx_beacon;
 	u8 rx_beacon_signal_avg;
 	struct cfg80211_tid_stats *pertid;
+	u16 airtime_weight;
 	s8 ack_signal;
 	s8 avg_ack_signal;
 
@@ -2381,6 +2387,8 @@ enum wiphy_params_flags {
 	WIPHY_PARAM_TXQ_QUANTUM		= 1 << 8,
 };
 
+#define IEEE80211_DEFAULT_AIRTIME_WEIGHT	256
+
 /**
  * struct cfg80211_pmksa - PMK Security Association
  *
include/uapi/linux/nl80211.h +15 -0
index 6d610bae30a9..9428bd0ebb1a 100644
@@ -2254,6 +2254,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_FTM_RESPONDER_STATS: Nested attribute with FTM responder
  *	statistics, see &enum nl80211_ftm_responder_stats.
  *
+ * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime
+ *	scheduler.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2699,6 +2702,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_FTM_RESPONDER_STATS,
 
+	NL80211_ATTR_AIRTIME_WEIGHT,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -3074,6 +3079,9 @@ enum nl80211_sta_bss_param {
  *	with an FCS error (u32, from this station). This count may not include
  *	some packets with an FCS error due to TA corruption. Hence this counter
  *	might not be fully accurate.
+ * @NL80211_STA_INFO_TX_DURATION: aggregate PPDU duration for all frames
+ *	sent to the station (u64, usec)
+ * @NL80211_STA_INFO_AIRTIME_WEIGHT: current airtime weight for station (u16)
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
@@ -3116,6 +3124,8 @@ enum nl80211_sta_info {
 	NL80211_STA_INFO_ACK_SIGNAL_AVG,
 	NL80211_STA_INFO_RX_MPDUS,
 	NL80211_STA_INFO_FCS_ERROR_COUNT,
+	NL80211_STA_INFO_TX_DURATION,
+	NL80211_STA_INFO_AIRTIME_WEIGHT,
 
 	/* keep last */
 	__NL80211_STA_INFO_AFTER_LAST,
@@ -5258,6 +5268,10 @@ enum nl80211_feature_flags {
  *      if this flag is not set. Ignoring this can leak clear text packets and/or
  *      freeze the connection.
  *
+ * @NL80211_EXT_FEATURE_AIRTIME_FAIRNESS: Driver supports getting airtime
+ *	fairness for transmitted packets and has enabled airtime fairness
+ *	scheduling.
+ *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
  */
@@ -5297,6 +5311,7 @@ enum nl80211_ext_feature_index {
 	NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
 	NL80211_EXT_FEATURE_CAN_REPLACE_PTK0,
 	NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
+	NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
 
 	/* add new features before the definition below */
 	NUM_NL80211_EXT_FEATURES,
net/wireless/nl80211.c +30 -0
index 8d763725498c..ec7c80c01008 100644
@@ -497,6 +497,7 @@ static int validate_ie_attr(const struct nlattr *attr,
 		.type = NLA_NESTED,
 		.validation_data = nl80211_ftm_responder_policy,
 	},
+	[NL80211_ATTR_AIRTIME_WEIGHT] = { .type = NLA_U16 },
 };
 
 /* policy for the key attributes */
@@ -4690,6 +4691,11 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
 	PUT_SINFO(PLID, plid, u16);
 	PUT_SINFO(PLINK_STATE, plink_state, u8);
 	PUT_SINFO_U64(RX_DURATION, rx_duration);
+	PUT_SINFO_U64(TX_DURATION, tx_duration);
+
+	if (wiphy_ext_feature_isset(&rdev->wiphy,
+				    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+		PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
 
 	switch (rdev->wiphy.signal_type) {
 	case CFG80211_SIGNAL_TYPE_MBM:
@@ -5308,6 +5314,18 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 			nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
 	}
 
+	if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]) {
+		params.airtime_weight =
+			nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
+		if (!params.airtime_weight)
+			return -EINVAL;
+	}
+
+	if (params.airtime_weight &&
+	    !wiphy_ext_feature_isset(&rdev->wiphy,
+				     NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+		return -EOPNOTSUPP;
+
 	/* Include parameters for TDLS peer (will check later) */
 	err = nl80211_set_station_tdls(info, &params);
 	if (err)
@@ -5436,6 +5454,18 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 		params.plink_action =
 			nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
 
+	if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]) {
+		params.airtime_weight =
+			nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
+		if (!params.airtime_weight)
+			return -EINVAL;
+	}
+
+	if (params.airtime_weight &&
+	    !wiphy_ext_feature_isset(&rdev->wiphy,
+				     NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+		return -EOPNOTSUPP;
+
 	err = nl80211_parse_sta_channel_info(info, &params);
 	if (err)
 		return err;
Signature · 1 line
1.9.1
#3 lore raw

PATCH v3 3/6 mac80211: Add airtime accounting and scheduling to TXQs

In reply to Rajkumar Manoharan

From: Toke Høiland-Jørgensen <[email protected]>

This adds airtime accounting and scheduling to the mac80211 TXQ scheduler. A new callback, ieee80211_sta_register_airtime(), is added that drivers can call to report airtime usage for stations.

When airtime information is present, mac80211 will schedule TXQs (through ieee80211_next_txq()) in a way that enforces airtime fairness between active stations. This scheduling works the same way as the ath9k in-driver airtime fairness scheduling. If no airtime usage is reported by the driver, the scheduler will default to round-robin scheduling.

For drivers that don't control TXQ scheduling in software, a new API function, ieee80211_txq_may_transmit(), is added which the driver can use to check if the TXQ is eligible for transmission, or should be throttled to enforce fairness. Calls to this function must also be enclosed in ieee80211_txq_schedule_{start,end}() calls to ensure proper locking.

The API ieee80211_txq_may_transmit() also ensures that TXQ list will be aligned aginst driver's own round-robin scheduler list. i.e it rotates the TXQ list till it makes the requested node becomes the first entry in TXQ list. Thus both the TXQ list and driver's list are in sync.

---
 include/net/mac80211.h     | 59 ++++++++++++++++++++++++++++++
 net/mac80211/cfg.c         |  3 ++
 net/mac80211/debugfs.c     |  3 ++
 net/mac80211/debugfs_sta.c | 50 ++++++++++++++++++++++++--
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/main.c        |  4 +++
 net/mac80211/sta_info.c    | 44 +++++++++++++++++++++--
 net/mac80211/sta_info.h    | 13 +++++++
 net/mac80211/status.c      |  6 ++++
 net/mac80211/tx.c          | 90 +++++++++++++++++++++++++++++++++++++++++++---
 10 files changed, 264 insertions(+), 10 deletions(-)
include/net/mac80211.h +59 -0
index 18b11c119b7e..c43d615ee9b1 100644
@@ -2357,6 +2357,9 @@ enum ieee80211_hw_flags {
  * @tx_sk_pacing_shift: Pacing shift to set on TCP sockets when frames from
  *	them are encountered. The default should typically not be changed,
  *	unless the driver has good reasons for needing more buffers.
+ *
+ * @weight_multipler: Driver specific airtime weight multiplier used while
+ *	refilling deficit of each TXQ.
  */
 struct ieee80211_hw {
 	struct ieee80211_conf conf;
@@ -2393,6 +2396,7 @@ struct ieee80211_hw {
 	const struct ieee80211_cipher_scheme *cipher_schemes;
 	u8 max_nan_de_entries;
 	u8 tx_sk_pacing_shift;
+	u8 weight_multiplier;
 };
 
 static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw,
@@ -5393,6 +5397,34 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
 void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid);
 
 /**
+ * ieee80211_sta_register_airtime - register airtime usage for a sta/tid
+ *
+ * Register airtime usage for a given sta on a given tid. The driver can call
+ * this function to notify mac80211 that a station used a certain amount of
+ * airtime. This information will be used by the TXQ scheduler to schedule
+ * stations in a way that ensures airtime fairness.
+ *
+ * The reported airtime should as a minimum include all time that is spent
+ * transmitting to the remote station, including overhead and padding, but not
+ * including time spent waiting for a TXOP. If the time is not reported by the
+ * hardware it can in some cases be calculated from the rate and known frame
+ * composition. When possible, the time should include any failed transmission
+ * attempts.
+ *
+ * The driver can either call this function synchronously for every packet or
+ * aggregate, or asynchronously as airtime usage information becomes available.
+ * TX and RX airtime can be reported together, or separately by setting one of
+ * them to 0.
+ *
+ * @pubsta: the station
+ * @tid: the TID to register airtime for
+ * @tx_airtime: airtime used during TX (in usec)
+ * @rx_airtime: airtime used during RX (in usec)
+ */
+void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
+				    u32 tx_airtime, u32 rx_airtime);
+
+/**
  * ieee80211_iter_keys - iterate keys programmed into the device
  * @hw: pointer obtained from ieee80211_alloc_hw()
  * @vif: virtual interface to iterate, may be %NULL for all
@@ -6150,6 +6182,33 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac);
 
 /**
+ * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
+ *
+ * This function is used to check whether given txq is allowed to transmit by
+ * the airtime scheduler, and can be used by drivers to access the airtime
+ * fairness accounting without going using the scheduling order enfored by
+ * next_txq().
+ *
+ * Returns %true if the airtime scheduler thinks the TXQ should be allowed to
+ * transmit, and %false if it should be throttled. This function can also have
+ * the side effect of rotating the TXQ in the scheduler rotation, which will
+ * eventually bring the deficit to positive and allow the station to transmit
+ * again.
+ *
+ * The API ieee80211_txq_may_transmit() also ensures that TXQ list will be
+ * aligned aginst driver's own round-robin scheduler list. i.e it rotates
+ * the TXQ list till it makes the requested node becomes the first entry
+ * in TXQ list. Thus both the TXQ list and driver's list are in sync. If this
+ * function returns %true, the driver is expected to schedule packets
+ * for transmission, and then return the TXQ through ieee80211_return_txq().
+ *
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @txq: pointer obtained from station or virtual interface
+ */
+bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
+				struct ieee80211_txq *txq);
+
+/**
  * ieee80211_txq_get_depth - get pending frame/byte count of given txq
  *
  * The values are not guaranteed to be coherent with regard to each other, i.e.
net/mac80211/cfg.c +3 -0
index 818aa0060349..57c59e5ceb98 100644
@@ -1447,6 +1447,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 	if (ieee80211_vif_is_mesh(&sdata->vif))
 		sta_apply_mesh_params(local, sta, params);
 
+	if (params->airtime_weight)
+		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) ||
 	    set & BIT(NL80211_STA_FLAG_ASSOCIATED)) {
net/mac80211/debugfs.c +3 -0
index 3fe541e358f3..81c5fec2eae7 100644
@@ -383,6 +383,9 @@ void debugfs_hw_add(struct ieee80211_local *local)
 	if (local->ops->wake_tx_queue)
 		DEBUGFS_ADD_MODE(aqm, 0600);
 
+	debugfs_create_u16("airtime_flags", 0600,
+			   phyd, &local->airtime_flags);
+
 	statsd = debugfs_create_dir("statistics", phyd);
 
 	/* if the dir failed, don't put all the other things into the root! */
net/mac80211/debugfs_sta.c +47 -3

68 lines not on this page · raw message

net/mac80211/ieee80211_i.h +2 -0
index 33763a2eac81..c5b6ba571288 100644
@@ -1137,6 +1137,8 @@ struct ieee80211_local {
 	struct list_head active_txqs[IEEE80211_NUM_ACS];
 	u16 schedule_round[IEEE80211_NUM_ACS];
 
+	u16 airtime_flags;
+
 	const struct ieee80211_ops *ops;
 
 	/*
net/mac80211/main.c +4 -0
index ba64757afea4..3710727fa9c1 100644
@@ -667,6 +667,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 		INIT_LIST_HEAD(&local->active_txqs[i]);
 		spin_lock_init(&local->active_txq_lock[i]);
 	}
+	local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
 
 	INIT_LIST_HEAD(&local->chanctx_list);
 	mutex_init(&local->chanctx_mtx);
@@ -1153,6 +1154,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 	if (!local->hw.max_nan_de_entries)
 		local->hw.max_nan_de_entries = IEEE80211_MAX_NAN_INSTANCE_ID;
 
+	if (!local->hw.weight_multiplier)
+		local->hw.weight_multiplier = 1;
+
 	result = ieee80211_wep_init(local);
 	if (result < 0)
 		wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
net/mac80211/sta_info.c +41 -3

78 lines not on this page · raw message

net/mac80211/sta_info.h +13 -0
index 9a04327d71d1..b1b0fd6a2e21 100644
@@ -127,6 +127,16 @@ enum ieee80211_agg_stop_reason {
 	AGG_STOP_DESTROY_STA,
 };
 
+/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
+#define AIRTIME_USE_TX		BIT(0)
+#define AIRTIME_USE_RX		BIT(1)
+
+struct airtime_info {
+	u64 rx_airtime;
+	u64 tx_airtime;
+	s64 deficit;
+};
+
 struct sta_info;
 
 /**
@@ -563,6 +573,9 @@ struct sta_info {
 	} tx_stats;
 	u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
 
+	struct airtime_info airtime[IEEE80211_NUM_ACS];
+	u16 airtime_weight;
+
 	/*
 	 * Aggregation information, locked with lock.
 	 */
net/mac80211/status.c +6 -0
index aa4afbf0abaf..a1f1256448f5 100644
@@ -818,6 +818,12 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
 			ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
 						acked, info->status.tx_time);
 
+		if (info->status.tx_time &&
+		    wiphy_ext_feature_isset(local->hw.wiphy,
+					    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+			ieee80211_sta_register_airtime(&sta->sta, tid,
+						       info->status.tx_time, 0);
+
 		if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
 			if (info->flags & IEEE80211_TX_STAT_ACK) {
 				if (sta->status_stats.lost_packets)
net/mac80211/tx.c +86 -4

117 lines not on this page · raw message

Signature · 1 line
1.9.1
#4 lore raw

Re: [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 46 lines · Rajkumar Manoharan

From: Toke Høiland-Jørgensen <[email protected]>

This adds airtime accounting and scheduling to the mac80211 TXQ scheduler. A new callback, ieee80211_sta_register_airtime(), is added that drivers can call to report airtime usage for stations.

When airtime information is present, mac80211 will schedule TXQs (through ieee80211_next_txq()) in a way that enforces airtime fairness between active stations. This scheduling works the same way as the ath9k in-driver airtime fairness scheduling. If no airtime usage is reported by the driver, the scheduler will default to round-robin scheduling.

For drivers that don't control TXQ scheduling in software, a new API function, ieee80211_txq_may_transmit(), is added which the driver can use to check if the TXQ is eligible for transmission, or should be throttled to enforce fairness. Calls to this function must also be enclosed in ieee80211_txq_schedule_{start,end}() calls to ensure proper locking.

The API ieee80211_txq_may_transmit() also ensures that TXQ list will be aligned aginst driver's own round-robin scheduler list. i.e it rotates the TXQ list till it makes the requested node becomes the first entry in TXQ list. Thus both the TXQ list and driver's list are in sync.

---
 include/net/mac80211.h     | 59 ++++++++++++++++++++++++++++++
 net/mac80211/cfg.c         |  3 ++
 net/mac80211/debugfs.c     |  3 ++
 net/mac80211/debugfs_sta.c | 50 ++++++++++++++++++++++++--
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/main.c        |  4 +++
 net/mac80211/sta_info.c    | 44 +++++++++++++++++++++--
 net/mac80211/sta_info.h    | 13 +++++++
 net/mac80211/status.c      |  6 ++++
 net/mac80211/tx.c          | 90 +++++++++++++++++++++++++++++++++++++++++++---
 10 files changed, 264 insertions(+), 10 deletions(-)
net/mac80211/status.c +0 -0
index aa4afbf0abaf..a1f1256448f5 100644
@@ -818,6 +818,12 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
 			ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
 						acked, info->status.tx_time);

net/mac80211/status.c static void __ieee80211_tx_status(struct ieee80211_hw *hw, · line 829

Quoted 10 lines
net/mac80211/status.c +6 -0
 
+		if (info->status.tx_time &&
+		    wiphy_ext_feature_isset(local->hw.wiphy,
+					    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+			ieee80211_sta_register_airtime(&sta->sta, tid,
+						       info->status.tx_time, 0);
+
 		if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
 			if (info->flags & IEEE80211_TX_STAT_ACK) {
 				if (sta->status_stats.lost_packets)

I think the same is needed in ieee80211_tx_status_ext.

Quoted 19 lines
net/mac80211/tx.c +8 -3
index 305965283506..3f417e80e041 100644
@@ -3660,12 +3680,74 @@ void ieee80211_return_txq(struct ieee80211_hw *hw,
 	lockdep_assert_held(&local->active_txq_lock[txq->ac]);
 
 	if (list_empty(&txqi->schedule_order) &&
-	    (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets))
-		list_add_tail(&txqi->schedule_order,
-			      &local->active_txqs[txq->ac]);
+	    (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
+		/* If airtime accounting is active, always enqueue STAs at the
+		 * head of the list to ensure that they only get moved to the
+		 * back by the airtime DRR scheduler once they have a negative
+		 * deficit. A station that already has a negative deficit will
+		 * get immediately moved to the back of the list on the next
+		 * call to ieee80211_next_txq().
+		 */

net/mac80211/tx.c void ieee80211_return_txq(struct ieee80211_hw *hw, · line 3700

Quoted 10 lines
net/mac80211/tx.c +9 -0
+		if (txqi->txq.sta &&
+		    wiphy_ext_feature_isset(local->hw.wiphy,
+					    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+			list_add(&txqi->schedule_order,
+				 &local->active_txqs[txq->ac]);
+		else
+			list_add_tail(&txqi->schedule_order,
+				      &local->active_txqs[txq->ac]);
+	}
 }

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a number of aggregates in the hardware queue, and the hardware queue is currently empty.
If the current txq entry is kept at the head of the schedule list, wouldn't the code just pull from that one over and over again, until enough packets are transmitted by the hardware and their tx status processed?
It seems to me that while fairness is still preserved in the long run, this could lead to rather bursty scheduling, which may not be particularly latency friendly.

- Felix

#5 lore raw

Re: [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 48 lines · Felix Fietkau
Quoted 47 lines · Rajkumar Manoharan

From: Toke Høiland-Jørgensen <[email protected]>

This adds airtime accounting and scheduling to the mac80211 TXQ scheduler. A new callback, ieee80211_sta_register_airtime(), is added that drivers can call to report airtime usage for stations.

When airtime information is present, mac80211 will schedule TXQs (through ieee80211_next_txq()) in a way that enforces airtime fairness between active stations. This scheduling works the same way as the ath9k in-driver airtime fairness scheduling. If no airtime usage is reported by the driver, the scheduler will default to round-robin scheduling.

For drivers that don't control TXQ scheduling in software, a new API function, ieee80211_txq_may_transmit(), is added which the driver can use to check if the TXQ is eligible for transmission, or should be throttled to enforce fairness. Calls to this function must also be enclosed in ieee80211_txq_schedule_{start,end}() calls to ensure proper locking.

The API ieee80211_txq_may_transmit() also ensures that TXQ list will be aligned aginst driver's own round-robin scheduler list. i.e it rotates the TXQ list till it makes the requested node becomes the first entry in TXQ list. Thus both the TXQ list and driver's list are in sync.

---
 include/net/mac80211.h     | 59 ++++++++++++++++++++++++++++++
 net/mac80211/cfg.c         |  3 ++
 net/mac80211/debugfs.c     |  3 ++
 net/mac80211/debugfs_sta.c | 50 ++++++++++++++++++++++++--
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/main.c        |  4 +++
 net/mac80211/sta_info.c    | 44 +++++++++++++++++++++--
 net/mac80211/sta_info.h    | 13 +++++++
 net/mac80211/status.c      |  6 ++++
 net/mac80211/tx.c          | 90 +++++++++++++++++++++++++++++++++++++++++++---
 10 files changed, 264 insertions(+), 10 deletions(-)
net/mac80211/status.c +0 -0
index aa4afbf0abaf..a1f1256448f5 100644
@@ -818,6 +818,12 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
 			ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
 						acked, info->status.tx_time);
 
Quoted 10 lines

net/mac80211/status.c static void __ieee80211_tx_status(struct ieee80211_hw *hw, · line 829

Quoted 9 lines
net/mac80211/status.c +6 -0
+		if (info->status.tx_time &&
+		    wiphy_ext_feature_isset(local->hw.wiphy,
+					    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+			ieee80211_sta_register_airtime(&sta->sta, tid,
+						       info->status.tx_time, 0);
+
 		if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
 			if (info->flags & IEEE80211_TX_STAT_ACK) {
 				if (sta->status_stats.lost_packets)

I think the same is needed in ieee80211_tx_status_ext.

Right, good point.

Quoted 33 lines
Quoted 19 lines
net/mac80211/tx.c +8 -3
index 305965283506..3f417e80e041 100644
@@ -3660,12 +3680,74 @@ void ieee80211_return_txq(struct ieee80211_hw *hw,
 	lockdep_assert_held(&local->active_txq_lock[txq->ac]);
 
 	if (list_empty(&txqi->schedule_order) &&
-	    (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets))
-		list_add_tail(&txqi->schedule_order,
-			      &local->active_txqs[txq->ac]);
+	    (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
+		/* If airtime accounting is active, always enqueue STAs at the
+		 * head of the list to ensure that they only get moved to the
+		 * back by the airtime DRR scheduler once they have a negative
+		 * deficit. A station that already has a negative deficit will
+		 * get immediately moved to the back of the list on the next
+		 * call to ieee80211_next_txq().
+		 */

net/mac80211/tx.c void ieee80211_return_txq(struct ieee80211_hw *hw, · line 3700

Quoted 10 lines
net/mac80211/tx.c +9 -0
+		if (txqi->txq.sta &&
+		    wiphy_ext_feature_isset(local->hw.wiphy,
+					    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+			list_add(&txqi->schedule_order,
+				 &local->active_txqs[txq->ac]);
+		else
+			list_add_tail(&txqi->schedule_order,
+				      &local->active_txqs[txq->ac]);
+	}
 }

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a number of aggregates in the hardware queue, and the hardware queue is

Quoted 8 lines

currently empty.
If the current txq entry is kept at the head of the schedule list, wouldn't the code just pull from that one over and over again, until enough packets are transmitted by the hardware and their tx status processed?
It seems to me that while fairness is still preserved in the long run, this could lead to rather bursty scheduling, which may not be particularly latency friendly.

Yes, it'll be a bit more bursty when the hardware queue is completely empty. However, when a TX completion comes back, that will adjust the deficit of that sta and cause it to be rotated on the next dequeue. This obviously relies on the fact that the lower-level hardware queue is sufficiently shallow to not add a lot of latency. But we want that to be the case anyway. In practice, it works quite well for ath9k, but not so well for ath10k because it has a large buffer in firmware.

If we requeue the TXQ at the end of the list, a station that is taking up too much airtime will fail to be throttled properly, so the queue-at-head is kinda needed to ensure fairness...

-Toke

#6 lore raw

Re: [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 21 lines · Toke Høiland-Jørgensen
Quoted 4 lines

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a number of aggregates in the hardware queue, and the hardware queue is

Quoted 8 lines

currently empty.
If the current txq entry is kept at the head of the schedule list, wouldn't the code just pull from that one over and over again, until enough packets are transmitted by the hardware and their tx status processed?
It seems to me that while fairness is still preserved in the long run, this could lead to rather bursty scheduling, which may not be particularly latency friendly.

Yes, it'll be a bit more bursty when the hardware queue is completely empty. However, when a TX completion comes back, that will adjust the deficit of that sta and cause it to be rotated on the next dequeue. This obviously relies on the fact that the lower-level hardware queue is sufficiently shallow to not add a lot of latency. But we want that to be the case anyway. In practice, it works quite well for ath9k, but not so well for ath10k because it has a large buffer in firmware.

Quoted 3 lines

If we requeue the TXQ at the end of the list, a station that is taking up too much airtime will fail to be throttled properly, so the queue-at-head is kinda needed to ensure fairness...

Thanks for the explanation, that makes sense to me. I have an idea on how to mitigate the burstiness within the driver. I'll write it down in pseudocode, please let me know if you think that'll work.

do {
	struct ieee80211_txq *pending_txq[4];
	int n_pending_txq = 0;
	int i;

	if (hwq->pending < 4)
		break;

	nframes = 0;

	ieee80211_txq_schedule_start(hw, ac)
	do {
		bool requeue = false;

		struct ieee80211_txq *txq;

		txq = ieee80211_next_txq(hw, ac);
		if (!txq)
			break;

		nframes += schedule_txq(txq, &requeue);
		if (requeue)
			pending_txq[n_pending_txq++] = txq;

	} while (n_pending_txq < ARRAY_SIZE(pending_txq));

	for (i = n_pending_txq; i > 0; i--)
		ieee80211_return_txq(hw, pending_txq[i - 1]);

	ieee80211_txq_schedule_end(hw, ac)
} while (nframes);

- Felix

#7 lore raw

Re: [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 22 lines · Felix Fietkau
Quoted 21 lines · Toke Høiland-Jørgensen
Quoted 4 lines

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a number of aggregates in the hardware queue, and the hardware queue is

Quoted 8 lines

currently empty.
If the current txq entry is kept at the head of the schedule list, wouldn't the code just pull from that one over and over again, until enough packets are transmitted by the hardware and their tx status processed?
It seems to me that while fairness is still preserved in the long run, this could lead to rather bursty scheduling, which may not be particularly latency friendly.

Yes, it'll be a bit more bursty when the hardware queue is completely empty. However, when a TX completion comes back, that will adjust the deficit of that sta and cause it to be rotated on the next dequeue. This obviously relies on the fact that the lower-level hardware queue is sufficiently shallow to not add a lot of latency. But we want that to be the case anyway. In practice, it works quite well for ath9k, but not so well for ath10k because it has a large buffer in firmware.

Quoted 6 lines
Quoted 3 lines

If we requeue the TXQ at the end of the list, a station that is taking up too much airtime will fail to be throttled properly, so the queue-at-head is kinda needed to ensure fairness...

Thanks for the explanation, that makes sense to me. I have an idea on how to mitigate the burstiness within the driver. I'll write it down in pseudocode, please let me know if you think that'll work.

I don't think it will, unfortunately. For example, consider the case where there are two stations queued; one with a large negative deficit (say, -10ms), and one with a positive deficit.

In this case, we really need to throttle the station with a negative deficit. But if the driver loops and caches txqs, we'll get something like the following:

- First driver loop iteration: returns TXQ with positive deficit.
- Second driver loop iteration: Only the negative-deficit TXQ is in the mac80211 list, so it will loop until that TXQ's deficit turns positive and return it.

Because of this, the negative-deficit station won't be throttled, and we won't get fairness.

How many frames will mt76 queue up below the driver point? I.e., how much burstiness are you expecting this will introduce on that driver?

Taking a step back, it's clear that it would be good to be able to dequeue packets to multiple STAs at once (we need that for MU-MIMO on ath10k as well). However, I don't think we can do that with the round-robin fairness scheduler; so we are going to need a different algorithm. I *think* it may be possible to do this with a virtual-time scheduler, but I haven't sat down and worked out the details yet...

-Toke

#8 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 27 lines · Toke Høiland-Jørgensen
Quoted 25 lines · Felix Fietkau
Quoted 24 lines · Toke Høiland-Jørgensen
Quoted 4 lines

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a number of aggregates in the hardware queue, and the hardware queue is

Quoted 8 lines

currently empty.
If the current txq entry is kept at the head of the schedule list, wouldn't the code just pull from that one over and over again, until enough packets are transmitted by the hardware and their tx status processed?
It seems to me that while fairness is still preserved in the long run, this could lead to rather bursty scheduling, which may not be particularly latency friendly.

Yes, it'll be a bit more bursty when the hardware queue is completely empty. However, when a TX completion comes back, that will adjust the deficit of that sta and cause it to be rotated on the next dequeue. This obviously relies on the fact that the lower-level hardware queue is sufficiently shallow to not add a lot of latency. But we want that to be the case anyway. In practice, it works quite well for ath9k, but not so well for ath10k because it has a large buffer in firmware.

If we requeue the TXQ at the end of the list, a station that is taking up too much airtime will fail to be throttled properly, so the queue-at-head is kinda needed to ensure fairness...

Quoted 7 lines
Quoted 3 lines

Thanks for the explanation, that makes sense to me. I have an idea on how to mitigate the burstiness within the driver. I'll write it down in pseudocode, please let me know if you think that'll work.

I don't think it will, unfortunately. For example, consider the case where there are two stations queued; one with a large negative deficit (say, -10ms), and one with a positive deficit.

Perhaps a flag for one way or the other?

if(driver->has_absurd_hardware_queue_depth) doitthisway(); else doitabetterway();

Quoted 16 lines

In this case, we really need to throttle the station with a negative deficit. But if the driver loops and caches txqs, we'll get something like the following:

- First driver loop iteration: returns TXQ with positive deficit.
- Second driver loop iteration: Only the negative-deficit TXQ is in the mac80211 list, so it will loop until that TXQ's deficit turns positive and return it.

Because of this, the negative-deficit station won't be throttled, and we won't get fairness.

How many frames will mt76 queue up below the driver point? I.e., how much burstiness are you expecting this will introduce on that driver?

Quoted 6 lines

Taking a step back, it's clear that it would be good to be able to dequeue packets to multiple STAs at once (we need that for MU-MIMO on ath10k as well). However, I don't think we can do that with the round-robin fairness scheduler; so we are going to need a different algorithm. I *think* it may be possible to do this with a virtual-time scheduler, but I haven't sat down and worked out the details yet...

The answer to which did not fit on the margins of your thesis. :)

I too have been trying to come up with a better means of gang scheduling... for about 2 years now. In terms of bitmaps it looks a bit like QFQ, but honestly...

Is there going to be some point where whatever we have here is significantly better than what we had? Or not significantly worse? Or handwavy enough to fix the rest once enlightenment arrives?

The perfect is the enemy of the good.

I'd rather like the intel folk to be weighing in on this stuff, too, trying to get an API right requires use cases.

Quoted 6 lines

-Toke
_______________________________________________
Make-wifi-fast mailing list
[email protected]
https://lists.bufferbloat.net/listinfo/make-wifi-fast

_______________________________________________
ath10k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath10k

#9 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 33 lines · Dave Taht
Quoted 31 lines · Toke Høiland-Jørgensen
Quoted 28 lines · Felix Fietkau
Quoted 21 lines · Toke Høiland-Jørgensen
Quoted 4 lines

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a number of aggregates in the hardware queue, and the hardware queue is

Quoted 8 lines

currently empty.
If the current txq entry is kept at the head of the schedule list, wouldn't the code just pull from that one over and over again, until enough packets are transmitted by the hardware and their tx status processed?
It seems to me that while fairness is still preserved in the long run, this could lead to rather bursty scheduling, which may not be particularly latency friendly.

Yes, it'll be a bit more bursty when the hardware queue is completely empty. However, when a TX completion comes back, that will adjust the deficit of that sta and cause it to be rotated on the next dequeue. This obviously relies on the fact that the lower-level hardware queue is sufficiently shallow to not add a lot of latency. But we want that to be the case anyway. In practice, it works quite well for ath9k, but not so well for ath10k because it has a large buffer in firmware.

Quoted 3 lines

If we requeue the TXQ at the end of the list, a station that is taking up too much airtime will fail to be throttled properly, so the queue-at-head is kinda needed to ensure fairness...

Thanks for the explanation, that makes sense to me. I have an idea on how to mitigate the burstiness within the driver. I'll write it down in pseudocode, please let me know if you think that'll work.

Quoted 8 lines
Quoted 3 lines

I don't think it will, unfortunately. For example, consider the case where there are two stations queued; one with a large negative deficit (say, -10ms), and one with a positive deficit.

Perhaps a flag for one way or the other?

if(driver->has_absurd_hardware_queue_depth) doitthisway(); else doitabetterway();

Well, there's going to be a BQL-like queue limit (but for airtime) on top, which drivers can opt-in to if the hardware has too much queueing.

Quoted 22 lines
Quoted 15 lines

In this case, we really need to throttle the station with a negative deficit. But if the driver loops and caches txqs, we'll get something like the following:

- First driver loop iteration: returns TXQ with positive deficit.
- Second driver loop iteration: Only the negative-deficit TXQ is in the mac80211 list, so it will loop until that TXQ's deficit turns positive and return it.

Because of this, the negative-deficit station won't be throttled, and we won't get fairness.

How many frames will mt76 queue up below the driver point? I.e., how much burstiness are you expecting this will introduce on that driver?

Quoted 6 lines

Taking a step back, it's clear that it would be good to be able to dequeue packets to multiple STAs at once (we need that for MU-MIMO on ath10k as well). However, I don't think we can do that with the round-robin fairness scheduler; so we are going to need a different algorithm. I *think* it may be possible to do this with a virtual-time scheduler, but I haven't sat down and worked out the details yet...

Quoted 5 lines

The answer to which did not fit on the margins of your thesis. :)

I too have been trying to come up with a better means of gang scheduling... for about 2 years now. In terms of bitmaps it looks a bit like QFQ, but honestly...

It's not the gang scheduling we need, deciding which devices to send to at once is generally done in firmware anyway. We just need to be able to dequeue packets for more than one station when possible. I don't think we need the fancy bitmap stuff from QFQ since we don't have that many stations to schedule at once; so we can probably live with O(log(n)) in the number of active stations.

Quoted 5 lines

Is there going to be some point where whatever we have here is significantly better than what we had? Or not significantly worse? Or handwavy enough to fix the rest once enlightenment arrives?

The perfect is the enemy of the good.

Well, what we have now works for ath9k, works reasonably well for ath10k in pull mode, not so well for ath10k in push mode, and then there's Felix' comments in this thread...

Quoted 2 lines

I'd rather like the intel folk to be weighing in on this stuff, too, trying to get an API right requires use cases.

Johannes has already reviewed a previous version, and I do believe he said he'd review it again once we have converged on something :)

-Toke

#10 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 69 lines · Toke Høiland-Jørgensen
Quoted 33 lines · Dave Taht
Quoted 31 lines · Toke Høiland-Jørgensen
Quoted 28 lines · Felix Fietkau
Quoted 21 lines · Toke Høiland-Jørgensen
Quoted 4 lines

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a number of aggregates in the hardware queue, and the hardware queue is

Quoted 8 lines

currently empty.
If the current txq entry is kept at the head of the schedule list, wouldn't the code just pull from that one over and over again, until enough packets are transmitted by the hardware and their tx status processed?
It seems to me that while fairness is still preserved in the long run, this could lead to rather bursty scheduling, which may not be particularly latency friendly.

Yes, it'll be a bit more bursty when the hardware queue is completely empty. However, when a TX completion comes back, that will adjust the deficit of that sta and cause it to be rotated on the next dequeue. This obviously relies on the fact that the lower-level hardware queue is sufficiently shallow to not add a lot of latency. But we want that to be the case anyway. In practice, it works quite well for ath9k, but not so well for ath10k because it has a large buffer in firmware.

Quoted 3 lines

If we requeue the TXQ at the end of the list, a station that is taking up too much airtime will fail to be throttled properly, so the queue-at-head is kinda needed to ensure fairness...

Thanks for the explanation, that makes sense to me. I have an idea on how to mitigate the burstiness within the driver. I'll write it down in pseudocode, please let me know if you think that'll work.

Quoted 8 lines
Quoted 3 lines

I don't think it will, unfortunately. For example, consider the case where there are two stations queued; one with a large negative deficit (say, -10ms), and one with a positive deficit.

Perhaps a flag for one way or the other?

if(driver->has_absurd_hardware_queue_depth) doitthisway(); else doitabetterway();

Well, there's going to be a BQL-like queue limit (but for airtime) on top, which drivers can opt-in to if the hardware has too much queueing.

Quoted 22 lines
Quoted 21 lines

In this case, we really need to throttle the station with a negative deficit. But if the driver loops and caches txqs, we'll get something like the following:

- First driver loop iteration: returns TXQ with positive deficit.
- Second driver loop iteration: Only the negative-deficit TXQ is in the mac80211 list, so it will loop until that TXQ's deficit turns positive and return it.

Because of this, the negative-deficit station won't be throttled, and we won't get fairness.

How many frames will mt76 queue up below the driver point? I.e., how much burstiness are you expecting this will introduce on that driver?

Taking a step back, it's clear that it would be good to be able to dequeue packets to multiple STAs at once (we need that for MU-MIMO on ath10k as well). However, I don't think we can do that with the round-robin fairness scheduler; so we are going to need a different algorithm. I *think* it may be possible to do this with a virtual-time scheduler, but I haven't sat down and worked out the details yet...

Quoted 8 lines
Quoted 5 lines

The answer to which did not fit on the margins of your thesis. :)

I too have been trying to come up with a better means of gang scheduling... for about 2 years now. In terms of bitmaps it looks a bit like QFQ, but honestly...

It's not the gang scheduling we need, deciding which devices to send to at once is generally done in firmware anyway.

I have a long held dream that one day some firmware will be able to send an interrupt and some information along...

"Hi, I'll be done transmitting/receiving in about 1ms, here's who I think I can talk to next, and here's who else I maybe could gang schedule".

That would let us get away from 5ms wasted in the "ready to go" portion of the algo, and share the highest likelyhood "groups" with the higher layer.

Quoted 2 lines

We just need to be able to
dequeue packets for more than one station when possible.

And a huge fantasy is in some future 802.11ZZZ standard the on-board firmware and the linux drivers can be co-designed, even, dare I say, open sourced, to better evolve to meet real world requirements.

mbox's per station would be nice, with scatter/gather I/O... I can think of a zillion things I'd want the firmware to handle (other than buffering)

Quoted 4 lines

I don't think
we need the fancy bitmap stuff from QFQ since we don't have that many stations to schedule at once; so we can probably live with O(log(n)) in the number of active stations.

Best of two or three "groups", per above, from the firmware.

Quoted 9 lines
Quoted 5 lines

Is there going to be some point where whatever we have here is significantly better than what we had? Or not significantly worse? Or handwavy enough to fix the rest once enlightenment arrives?

The perfect is the enemy of the good.

Well, what we have now works for ath9k, works reasonably well for ath10k in pull mode, not so well for ath10k in push mode, and then there's Felix' comments in this thread...

So how about, an ath10k in a friggin "co-operative" mode?

What are the performance differences in ath10k in push mode? Why do we care if this mode works at all?

Perfect, verses "good".

Quoted 5 lines
Quoted 2 lines

I'd rather like the intel folk to be weighing in on this stuff, too, trying to get an API right requires use cases.

Johannes has already reviewed a previous version, and I do believe he said he'd review it again once we have converged on something :)

Would intel care if only the pull mode worked well on their hardware? Do they have a pull or push mode?

A message that is not in the archive (sent off-list or not yet received): [email protected]

#12 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 17 lines · Simon Barber

On Nov 19, 2018, at 2:44 PM, Toke Høiland-Jørgensen <[email protected]> wrote:

Dave Taht <[email protected]> writes:

Toke Høiland-Jørgensen <[email protected]> writes:

Felix Fietkau <[email protected]> writes:

On 2018-11-14 18:40, Toke Høiland-Jørgensen wrote:

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a

Quoted 8 lines

….

Well, there's going to be a BQL-like queue limit (but for airtime) on top, which drivers can opt-in to if the hardware has too much queueing.

Very happy to read this - I first talked to Dave Taht about the need for Time Queue Limits more than 5 years ago!

Michal faked up a dql estimator 3 (?) years ago. it worked.

http://blog.cerowrt.org/post/dql_on_wifi_2/

As a side note, in *any* real world working mu-mimo situation at any scale, on any equipment, does anyone have any stats on how often the feature is actually used and useful?

My personal guess, from looking at the standard, was in home scenarios, usage would be about... 0, and in a controlled environment in a football stadium, quite a lot.

In a office or apartment complex, I figured interference and so forth would make it a negative benefit due to retransmits.

I felt when that part of the standard rolled around... that mu-mimo was an idea that should never have escaped the lab. I can be convinced by data, that we can aim for a higher goal here. But it would be comforting to have a measured non-lab, real-world, at real world rates, result for it, on some platform, of it actually being useful.

Quoted 6 lines

Simon

_______________________________________________
Make-wifi-fast mailing list
[email protected]
https://lists.bufferbloat.net/listinfo/make-wifi-fast

Signature · 4 lines
Dave Täht
CTO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-831-205-9740
#13 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 39 lines · Dave Taht
Quoted 17 lines · Simon Barber

On Nov 19, 2018, at 2:44 PM, Toke Høiland-Jørgensen <[email protected]> wrote:

Dave Taht <[email protected]> writes:

Toke Høiland-Jørgensen <[email protected]> writes:

Felix Fietkau <[email protected]> writes:

On 2018-11-14 18:40, Toke Høiland-Jørgensen wrote:

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a

Quoted 8 lines

….

Well, there's going to be a BQL-like queue limit (but for airtime) on top, which drivers can opt-in to if the hardware has too much queueing.

Very happy to read this - I first talked to Dave Taht about the need for Time Queue Limits more than 5 years ago!

Michal faked up a dql estimator 3 (?) years ago. it worked.

http://blog.cerowrt.org/post/dql_on_wifi_2/

As a side note, in *any* real world working mu-mimo situation at any scale, on any equipment, does anyone have any stats on how often the feature is actually used and useful?

My personal guess, from looking at the standard, was in home scenarios, usage would be about... 0, and in a controlled environment in a football stadium, quite a lot.

Quoted 8 lines

In a office or apartment complex, I figured interference and so forth would make it a negative benefit due to retransmits.

I felt when that part of the standard rolled around... that mu-mimo was an idea that should never have escaped the lab. I can be convinced by data, that we can aim for a higher goal here. But it would be comforting to have a measured non-lab, real-world, at real world rates, result for it, on some platform, of it actually being useful.

We're working on building a lab with 20 or 30 mixed 'real' devices
using various different /AC NICs (QCA wave2 on OpenWRT, Fedora, realtek USB 8812au on OpenWRT, Fedora, and some Intel NICs in NUCs on Windows, and maybe more). I'm not actually sure if that realtek
or the NUCs can do MU-MIMO or not, but the QCA NICs will be able to. It should be at least somewhat similar
to a classroom environment or coffee shop. I'll let you know what we find
as far as how well MU-MIMO improves things or not.

At least in simple test cases (one 1x1 stations, one 2x2 station, with 4x4 MU-MIMO AP), it works very well for increased download throughput.

In home setups, I'd guess that the DSL or Cable Modem or other uplink is the bottleneck way more often than the wifi is, even if your are just running /n. But, maybe that is just my experience living out at the end of a long skinny phone line all these years.

Thanks,
Ben

Signature · 2 lines
Ben Greear <[email protected]>
Candela Technologies Inc  http://www.candelatech.com
#14 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 50 lines · Ben Greear
Quoted 39 lines · Dave Taht
Quoted 17 lines · Simon Barber

On Nov 19, 2018, at 2:44 PM, Toke Høiland-Jørgensen <[email protected]> wrote:

Dave Taht <[email protected]> writes:

Toke Høiland-Jørgensen <[email protected]> writes:

Felix Fietkau <[email protected]> writes:

On 2018-11-14 18:40, Toke Høiland-Jørgensen wrote:

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a

Quoted 8 lines

….

Well, there's going to be a BQL-like queue limit (but for airtime) on top, which drivers can opt-in to if the hardware has too much queueing.

Very happy to read this - I first talked to Dave Taht about the need for Time Queue Limits more than 5 years ago!

Michal faked up a dql estimator 3 (?) years ago. it worked.

http://blog.cerowrt.org/post/dql_on_wifi_2/

As a side note, in *any* real world working mu-mimo situation at any scale, on any equipment, does anyone have any stats on how often the feature is actually used and useful?

My personal guess, from looking at the standard, was in home scenarios, usage would be about... 0, and in a controlled environment in a football stadium, quite a lot.

Quoted 8 lines

In a office or apartment complex, I figured interference and so forth would make it a negative benefit due to retransmits.

I felt when that part of the standard rolled around... that mu-mimo was an idea that should never have escaped the lab. I can be convinced by data, that we can aim for a higher goal here. But it would be comforting to have a measured non-lab, real-world, at real world rates, result for it, on some platform, of it actually being useful.

Quoted 5 lines

We're working on building a lab with 20 or 30 mixed 'real' devices
using various different /AC NICs (QCA wave2 on OpenWRT, Fedora, realtek USB 8812au on OpenWRT, Fedora, and some Intel NICs in NUCs on Windows, and maybe more). I'm not actually sure if that realtek
or the NUCs can do MU-MIMO or not, but the QCA NICs will be able to. It should be at least somewhat similar
to a classroom environment or coffee shop.

In the last 3 coffee shops I went to, I could hear over 30 APs on competing SSIDs, running G, N, and AC,
occupying every available channel.

Quoted 2 lines

I'll let you know what we find
as far as how well MU-MIMO improves things or not.

Thank you. My lab is shut down and I'm selling off the gear, so all I can do anymore is be grumpy.

Quoted 3 lines

At least in simple test cases (one 1x1 stations, one 2x2 station, with 4x4 MU-MIMO AP), it works very well for increased download throughput.

Is that a UDP or TCP test?

My specific "most important" benchmark for wifi is web PLT with lots of stations. That's the most common wifi use case, IMHO.
Some videoconferencing, voip, ssh, etc. One big upload, one big download, going on somewhere, sometimes. Slashdot
for me is 78 separate ssl'd tcp flows, a dozen + dns lookups, over 2.2 seconds.

bulk downloads rarely figure in except for streaming video, and that peaks out generally at 20Mbit/sec for most people.

So while I do like the potential in mu-mimo to, schedule lower service times on a per station basis, I see too many
variable rates and interference in the real world, and not enough simultaneity between schedulable stations, and a ton of acks, for me to imagine there's much of a real-world difference from mu-mimo in anything other than a well managed office or stadium.

People going for the max download throughput with the max number of stations... PLT, PLT is a way better benchmark.

I can certainly be convinced by data, and I look forward to your experiments.

Quoted 1 line

In home setups, I'd guess that the DSL or Cable Modem or other uplink is the bottleneck

Offices too. Wifi - aside from interference and range issues lowering the rate, only becomes the bottleneck at internet speeds > 40Mbits/sec.

We are certainly starting to see wifi become more of the bottleneck, while running at rates, generally, far lower than what people bench at.

Quoted 2 lines

way more often than the wifi is, even if your are just running /n. But, maybe that is just my experience living out at the end of a long skinny phone line all these years.

Fiber networks and newer cable connections now crack 100mbits, and there you do see all that nifty fq_codel-ly chocolatey goodness kicking in....

but I do tend to think the optimization focus should be at low rates with lots of stations for plt more than bandwidth.

Quoted 9 lines

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com

Signature · 4 lines
Dave Täht
CTO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-831-205-9740
#15 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 57 lines · Dave Taht
Quoted 50 lines · Ben Greear
Quoted 39 lines · Dave Taht
Quoted 17 lines · Simon Barber

On Nov 19, 2018, at 2:44 PM, Toke Høiland-Jørgensen <[email protected]> wrote:

Dave Taht <[email protected]> writes:

Toke Høiland-Jørgensen <[email protected]> writes:

Felix Fietkau <[email protected]> writes:

On 2018-11-14 18:40, Toke Høiland-Jørgensen wrote:

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a

Quoted 8 lines

….

Well, there's going to be a BQL-like queue limit (but for airtime) on top, which drivers can opt-in to if the hardware has too much queueing.

Very happy to read this - I first talked to Dave Taht about the need for Time Queue Limits more than 5 years ago!

Michal faked up a dql estimator 3 (?) years ago. it worked.

http://blog.cerowrt.org/post/dql_on_wifi_2/

As a side note, in *any* real world working mu-mimo situation at any scale, on any equipment, does anyone have any stats on how often the feature is actually used and useful?

My personal guess, from looking at the standard, was in home scenarios, usage would be about... 0, and in a controlled environment in a football stadium, quite a lot.

Quoted 8 lines

In a office or apartment complex, I figured interference and so forth would make it a negative benefit due to retransmits.

I felt when that part of the standard rolled around... that mu-mimo was an idea that should never have escaped the lab. I can be convinced by data, that we can aim for a higher goal here. But it would be comforting to have a measured non-lab, real-world, at real world rates, result for it, on some platform, of it actually being useful.

Quoted 5 lines

We're working on building a lab with 20 or 30 mixed 'real' devices
using various different /AC NICs (QCA wave2 on OpenWRT, Fedora, realtek USB 8812au on OpenWRT, Fedora, and some Intel NICs in NUCs on Windows, and maybe more). I'm not actually sure if that realtek
or the NUCs can do MU-MIMO or not, but the QCA NICs will be able to. It should be at least somewhat similar
to a classroom environment or coffee shop.

Quoted 3 lines

In the last 3 coffee shops I went to, I could hear over 30 APs on competing SSIDs, running G, N, and AC,
occupying every available channel.

I especially like when someone uses channel 3 because, I guess, they think it is un-used :)

I'm not sure if this was a fluke or not, but at Starbucks recently I sat outside, right next to their window, and could not scan their AP at all. Previously, I sat inside, 3 feet away through the glass, and got great signal. I wonder what that was all about! Maybe special tinting that blocks RF? Or just dumb luck of some sort.

Thanks,
Ben

Signature · 2 lines
Ben Greear <[email protected]>
Candela Technologies Inc  http://www.candelatech.com
#16 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 59 lines · Ben Greear
Quoted 57 lines · Dave Taht
Quoted 55 lines · Ben Greear
Quoted 39 lines · Dave Taht
Quoted 17 lines · Simon Barber

On Nov 19, 2018, at 2:44 PM, Toke Høiland-Jørgensen <[email protected]> wrote:

Dave Taht <[email protected]> writes:

Toke Høiland-Jørgensen <[email protected]> writes:

Felix Fietkau <[email protected]> writes:

On 2018-11-14 18:40, Toke Høiland-Jørgensen wrote:

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a

Quoted 8 lines

….

Well, there's going to be a BQL-like queue limit (but for airtime) on top, which drivers can opt-in to if the hardware has too much queueing.

Very happy to read this - I first talked to Dave Taht about the need for Time Queue Limits more than 5 years ago!

Michal faked up a dql estimator 3 (?) years ago. it worked.

http://blog.cerowrt.org/post/dql_on_wifi_2/

As a side note, in *any* real world working mu-mimo situation at any scale, on any equipment, does anyone have any stats on how often the feature is actually used and useful?

My personal guess, from looking at the standard, was in home scenarios, usage would be about... 0, and in a controlled environment in a football stadium, quite a lot.

Quoted 8 lines

In a office or apartment complex, I figured interference and so forth would make it a negative benefit due to retransmits.

I felt when that part of the standard rolled around... that mu-mimo was an idea that should never have escaped the lab. I can be convinced by data, that we can aim for a higher goal here. But it would be comforting to have a measured non-lab, real-world, at real world rates, result for it, on some platform, of it actually being useful.

We're working on building a lab with 20 or 30 mixed 'real' devices
using various different /AC NICs (QCA wave2 on OpenWRT, Fedora, realtek USB 8812au on OpenWRT, Fedora, and some Intel NICs in NUCs on Windows, and maybe more). I'm not actually sure if that realtek
or the NUCs can do MU-MIMO or not, but the QCA NICs will be able to. It should be at least somewhat similar
to a classroom environment or coffee shop.

Quoted 6 lines
Quoted 3 lines

In the last 3 coffee shops I went to, I could hear over 30 APs on competing SSIDs, running G, N, and AC,
occupying every available channel.

I especially like when someone uses channel 3 because, I guess, they think it is un-used :)

I think avery actually found a case where that was a benefit, in an apartment building that had each per-apartment AP located at exactly the same place on every floor.

I do wish I could go back in time and explain the four colour theorem to whoever allocated the 2.4ghz wifi band, and then explain even that was a planar rather than 3D problem.

The 3D coloring problem I visualize as the scene in Aliens 2, where the monsters just waltz in over the ceiling panels. To me it's an indelible image kind of superimposed over the interfering waves in the air, full of gore, goo, and blood...

Quoted 5 lines

I'm not sure if this was a fluke or not, but at Starbucks recently I sat outside, right next to their window, and could not scan their AP at all. Previously, I sat inside, 3 feet away through the glass, and got great signal. I wonder what that was all about! Maybe special tinting that blocks RF? Or just dumb luck of some sort.

Ya know, I could definitely see a market for a material like that! I'd like it for my car, so bluetooth wouldn't escape.

anyway, just blowing off steam. :) When v4 of this rolls around + BQL? I can get some results back on it too. One less than perfect option or the other would be better than continuing to have lousy wifi in all cases on all platforms.

Quoted 8 lines

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com

Signature · 4 lines
Dave Täht
CTO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-831-205-9740
#17 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 7 lines · Dave Taht
Quoted 4 lines

I'm not sure if this was a fluke or not, but at Starbucks recently I sat outside, right next to their window, and could not scan their AP at all. Previously, I sat inside, 3 feet away through the glass, and got great signal. I wonder what that was all about! Maybe special tinting that blocks RF? Or just dumb luck of some sort.

Ya know, I could definitely see a market for a material like that! I'd like it for my car, so bluetooth wouldn't escape.

That would break your tire pressure sensors (each car is rolling around broadcasting 4 unique bluetooth IDs, not hard to track)

David Lang

_______________________________________________
ath10k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath10k

A message that is not in the archive (sent off-list or not yet received): [email protected]

#19 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 2 lines · Simon Barber

Low-e glass, it’s a thin metallic film used to reflect infra-red to keep heat in or out. Totally blocks/reflects RF.

Very cool. I imagine it's hell on cell too?

I can see this stuff becoming very popular in places where keeping the good wifi in is important. Could cover floors and ceilings with it to. Cars could be tempest rated...

/me goes looking for stock to buy

Quoted 91 lines

Simon

On Nov 19, 2018, at 4:20 PM, Ben Greear <[email protected]> wrote:

On 11/19/2018 04:13 PM, Dave Taht wrote:

On Mon, Nov 19, 2018 at 3:56 PM Ben Greear <[email protected]> wrote:

On 11/19/2018 03:47 PM, Dave Taht wrote:

On Mon, Nov 19, 2018 at 3:30 PM Simon Barber <[email protected]> wrote:

On Nov 19, 2018, at 2:44 PM, Toke Høiland-Jørgensen <[email protected]> wrote:

Dave Taht <[email protected]> writes:

Toke Høiland-Jørgensen <[email protected]> writes:

Felix Fietkau <[email protected]> writes:

On 2018-11-14 18:40, Toke Høiland-Jørgensen wrote:

This part doesn't really make much sense to me, but maybe I'm misunderstanding how the code works.
Let's assume we have a driver like ath9k or mt76, which tries to keep a

….

Well, there's going to be a BQL-like queue limit (but for airtime) on top, which drivers can opt-in to if the hardware has too much queueing.

Very happy to read this - I first talked to Dave Taht about the need for Time Queue Limits more than 5 years ago!

Michal faked up a dql estimator 3 (?) years ago. it worked.

http://blog.cerowrt.org/post/dql_on_wifi_2/

As a side note, in *any* real world working mu-mimo situation at any scale, on any equipment, does anyone have any stats on how often the feature is actually used and useful?

My personal guess, from looking at the standard, was in home scenarios, usage would be about... 0, and in a controlled environment in a football stadium, quite a lot.

In a office or apartment complex, I figured interference and so forth would make it a negative benefit due to retransmits.

I felt when that part of the standard rolled around... that mu-mimo was an idea that should never have escaped the lab. I can be convinced by data, that we can aim for a higher goal here. But it would be comforting to have a measured non-lab, real-world, at real world rates, result for it, on some platform, of it actually being useful.

We're working on building a lab with 20 or 30 mixed 'real' devices
using various different /AC NICs (QCA wave2 on OpenWRT, Fedora, realtek USB 8812au on OpenWRT, Fedora, and some Intel NICs in NUCs on Windows, and maybe more). I'm not actually sure if that realtek
or the NUCs can do MU-MIMO or not, but the QCA NICs will be able to. It should be at least somewhat similar
to a classroom environment or coffee shop.

In the last 3 coffee shops I went to, I could hear over 30 APs on competing SSIDs, running G, N, and AC,
occupying every available channel.

I especially like when someone uses channel 3 because, I guess, they think it is un-used :)

I'm not sure if this was a fluke or not, but at Starbucks recently I sat outside, right next to their window, and could not scan their AP at all. Previously, I sat inside, 3 feet away through the glass, and got great signal. I wonder what that was all about! Maybe special tinting that blocks RF? Or just dumb luck of some sort.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com

Signature · 4 lines
Dave Täht
CTO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-831-205-9740
#20 lore raw

Re: [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

In reply to Felix Fietkau

Hi Felix

Thinking a bit more about this, I think that rather than having the driver work around the API as in your example...

Quoted 24 lines
do {
	struct ieee80211_txq *pending_txq[4];
	int n_pending_txq = 0;
	int i;

	if (hwq->pending < 4)
		break;p

	nframes = 0;

	ieee80211_txq_schedule_start(hw, ac)
	do {
		bool requeue = false;

		struct ieee80211_txq *txq;

		txq = ieee80211_next_txq(hw, ac);
		if (!txq)
			break;

		nframes += schedule_txq(txq, &requeue);
		if (requeue)
			pending_txq[n_pending_txq++] = txq;
Quoted 7 lines
	} while (n_pending_txq < ARRAY_SIZE(pending_txq));

	for (i = n_pending_txq; i > 0; i--)
		ieee80211_return_txq(hw, pending_txq[i - 1]);

	ieee80211_txq_schedule_end(hw, ac)
} while (nframes);

... really what we want is that the driver can just do this:

ieee80211_txq_schedule_start(hw, ac);

while ((txq = ieee80211_next_txq(hw, ac)) {
	schedule_txq(txq, &requeue);
        return_txq(txq);
}

ieee80211_txq_schedule_end(hw, ac);

and expect so get through all eligible TXQs. Note that there will be cases where there is only a single eligible TXQ (such as the example I gave in the other email); in which case the current version is fine. But there is (probably) also going to be cases where more than one TXQ is eligible at the same time, which we cannot handle with the current RR scheduler.

However, I think that assuming we can get the scheduler to guarantee that it will return all eligible TXQs between each pair of calls to schedule_start()/schedule_end(), we should be fine with the current API. Do you agree with this?

-Toke

#21 lore raw

Re: [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

In reply to Felix Fietkau
Quoted 8 lines · Felix Fietkau
Quoted 8 lines
net/mac80211/status.c +0 -0
index aa4afbf0abaf..a1f1256448f5 100644
@@ -818,6 +818,12 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
 			ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
 						acked, info->status.tx_time);
 
Quoted 10 lines

net/mac80211/status.c static void __ieee80211_tx_status(struct ieee80211_hw *hw, · line 829

Quoted 9 lines
net/mac80211/status.c +6 -0
+		if (info->status.tx_time &&
+		    wiphy_ext_feature_isset(local->hw.wiphy,
+					    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+			ieee80211_sta_register_airtime(&sta->sta, tid,
+						       info->status.tx_time, 0);
+
 		if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
 			if (info->flags & IEEE80211_TX_STAT_ACK) {
 				if (sta->status_stats.lost_packets)

I think the same is needed in ieee80211_tx_status_ext.

So finally circled back to this. In ieee80211_tx_status_ext() we don't have an skb, so we don't know which TID the packet was sent to; what airtime information would the driver actually provide in this case? Is it an aggregate of all ACs, or?

-Toke

#22 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

In reply to Rajkumar Manoharan

Hi Rajkumar, Toke,

I found the series (v3,4/6) remove the debugfs remove reset station's airtime method, and didn't added at here.

Not sure how to help this kind of situation, do I need a separate patch to fix this, or posting the patch here is fine?

----

From 3a4a856c397345311c9d7f3679828cadc40e6a80 Mon Sep 17 00:00:00 2001
From: Louie Lu <[email protected]>
Date: Thu, 15 Nov 2018 16:13:57 +0800
Subject: [PATCH] mac80211: Add reset for station's airtime

Let user can reset station airtime status by debugfs, it will reset all airtime deficit to sta->airtime_weight and reset rx/tx airtime accumulate to 0.

net/mac80211/debugfs_sta.c +0 -0
index 446908ab3f5d..d84d2369a76e 100644
@@ -233,7 +233,28 @@ static ssize_t sta_airtime_read(struct file

*file, char __user *userbuf,

     kfree(buf);
     return rv;

}
-STA_OPS(airtime);
+
+/*
+ * FIXME: This *only* reset station airtime, didn't accept input
+ */
+static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{

+    struct sta_info *sta = file->private_data;
+    struct ieee80211_local *local = sta->sdata->local;
+    int ac;
+
+    for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+        spin_lock_bh(&local->active_txq_lock[ac]);
+        sta->airtime[ac].rx_airtime = 0;
+        sta->airtime[ac].tx_airtime = 0;
+        sta->airtime[ac].deficit = sta->airtime_weight;
+        spin_unlock_bh(&local->active_txq_lock[ac]);

+ }
+
+ return count;
+}
+STA_OPS_RW(airtime);

static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)

Signature · 4 lines
2.18.0


Rajkumar Manoharan <[email protected]> 於 2018年11月13日 週二 上午6:52寫道:
Quoted 531 lines

From: Toke Høiland-Jørgensen <[email protected]>

This adds airtime accounting and scheduling to the mac80211 TXQ scheduler. A new callback, ieee80211_sta_register_airtime(), is added that drivers can call to report airtime usage for stations.

When airtime information is present, mac80211 will schedule TXQs (through ieee80211_next_txq()) in a way that enforces airtime fairness between active stations. This scheduling works the same way as the ath9k in-driver airtime fairness scheduling. If no airtime usage is reported by the driver, the scheduler will default to round-robin scheduling.

For drivers that don't control TXQ scheduling in software, a new API function, ieee80211_txq_may_transmit(), is added which the driver can use to check if the TXQ is eligible for transmission, or should be throttled to enforce fairness. Calls to this function must also be enclosed in ieee80211_txq_schedule_{start,end}() calls to ensure proper locking.

The API ieee80211_txq_may_transmit() also ensures that TXQ list will be aligned aginst driver's own round-robin scheduler list. i.e it rotates the TXQ list till it makes the requested node becomes the first entry in TXQ list. Thus both the TXQ list and driver's list are in sync.

---
 include/net/mac80211.h     | 59 ++++++++++++++++++++++++++++++
 net/mac80211/cfg.c         |  3 ++
 net/mac80211/debugfs.c     |  3 ++
 net/mac80211/debugfs_sta.c | 50 ++++++++++++++++++++++++--
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/main.c        |  4 +++
 net/mac80211/sta_info.c    | 44 +++++++++++++++++++++--
 net/mac80211/sta_info.h    | 13 +++++++
 net/mac80211/status.c      |  6 ++++
 net/mac80211/tx.c          | 90 +++++++++++++++++++++++++++++++++++++++++++---
 10 files changed, 264 insertions(+), 10 deletions(-)
include/net/mac80211.h +59 -0
index 18b11c119b7e..c43d615ee9b1 100644
@@ -2357,6 +2357,9 @@ enum ieee80211_hw_flags {
  * @tx_sk_pacing_shift: Pacing shift to set on TCP sockets when frames from
  *     them are encountered. The default should typically not be changed,
  *     unless the driver has good reasons for needing more buffers.
+ *
+ * @weight_multipler: Driver specific airtime weight multiplier used while
+ *     refilling deficit of each TXQ.
  */
 struct ieee80211_hw {
        struct ieee80211_conf conf;
@@ -2393,6 +2396,7 @@ struct ieee80211_hw {
        const struct ieee80211_cipher_scheme *cipher_schemes;
        u8 max_nan_de_entries;
        u8 tx_sk_pacing_shift;
+       u8 weight_multiplier;
 };
 
 static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw,
@@ -5393,6 +5397,34 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
 void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid);
 
 /**
+ * ieee80211_sta_register_airtime - register airtime usage for a sta/tid
+ *
+ * Register airtime usage for a given sta on a given tid. The driver can call
+ * this function to notify mac80211 that a station used a certain amount of
+ * airtime. This information will be used by the TXQ scheduler to schedule
+ * stations in a way that ensures airtime fairness.
+ *
+ * The reported airtime should as a minimum include all time that is spent
+ * transmitting to the remote station, including overhead and padding, but not
+ * including time spent waiting for a TXOP. If the time is not reported by the
+ * hardware it can in some cases be calculated from the rate and known frame
+ * composition. When possible, the time should include any failed transmission
+ * attempts.
+ *
+ * The driver can either call this function synchronously for every packet or
+ * aggregate, or asynchronously as airtime usage information becomes available.
+ * TX and RX airtime can be reported together, or separately by setting one of
+ * them to 0.
+ *
+ * @pubsta: the station
+ * @tid: the TID to register airtime for
+ * @tx_airtime: airtime used during TX (in usec)
+ * @rx_airtime: airtime used during RX (in usec)
+ */
+void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
+                                   u32 tx_airtime, u32 rx_airtime);
+
+/**
  * ieee80211_iter_keys - iterate keys programmed into the device
  * @hw: pointer obtained from ieee80211_alloc_hw()
  * @vif: virtual interface to iterate, may be %NULL for all
@@ -6150,6 +6182,33 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac);
 
 /**
+ * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
+ *
+ * This function is used to check whether given txq is allowed to transmit by
+ * the airtime scheduler, and can be used by drivers to access the airtime
+ * fairness accounting without going using the scheduling order enfored by
+ * next_txq().
+ *
+ * Returns %true if the airtime scheduler thinks the TXQ should be allowed to
+ * transmit, and %false if it should be throttled. This function can also have
+ * the side effect of rotating the TXQ in the scheduler rotation, which will
+ * eventually bring the deficit to positive and allow the station to transmit
+ * again.
+ *
+ * The API ieee80211_txq_may_transmit() also ensures that TXQ list will be
+ * aligned aginst driver's own round-robin scheduler list. i.e it rotates
+ * the TXQ list till it makes the requested node becomes the first entry
+ * in TXQ list. Thus both the TXQ list and driver's list are in sync. If this
+ * function returns %true, the driver is expected to schedule packets
+ * for transmission, and then return the TXQ through ieee80211_return_txq().
+ *
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @txq: pointer obtained from station or virtual interface
+ */
+bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
+                               struct ieee80211_txq *txq);
+
+/**
  * ieee80211_txq_get_depth - get pending frame/byte count of given txq
  *
  * The values are not guaranteed to be coherent with regard to each other, i.e.
net/mac80211/cfg.c +3 -0
index 818aa0060349..57c59e5ceb98 100644
@@ -1447,6 +1447,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
        if (ieee80211_vif_is_mesh(&sdata->vif))
                sta_apply_mesh_params(local, sta, params);
 
+       if (params->airtime_weight)
+               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) ||
            set & BIT(NL80211_STA_FLAG_ASSOCIATED)) {
net/mac80211/debugfs.c +3 -0
index 3fe541e358f3..81c5fec2eae7 100644
@@ -383,6 +383,9 @@ void debugfs_hw_add(struct ieee80211_local *local)
        if (local->ops->wake_tx_queue)
                DEBUGFS_ADD_MODE(aqm, 0600);
 
+       debugfs_create_u16("airtime_flags", 0600,
+                          phyd, &local->airtime_flags);
+
        statsd = debugfs_create_dir("statistics", phyd);
 
        /* if the dir failed, don't put all the other things into the root! */
net/mac80211/debugfs_sta.c +47 -3
index af5185a836e5..446908ab3f5d 100644
@@ -181,9 +181,9 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
                               txqi->tin.tx_bytes,
                               txqi->tin.tx_packets,
                               txqi->flags,
-                              txqi->flags & (1<<IEEE80211_TXQ_STOP) ? "STOP" : "RUN",
-                              txqi->flags & (1<<IEEE80211_TXQ_AMPDU) ? " AMPDU" : "",
-                              txqi->flags & (1<<IEEE80211_TXQ_NO_AMSDU) ? " NO-AMSDU" : "");
+                              test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ? "STOP" : "RUN",
+                              test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags) ? " AMPDU" : "",
+                              test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags) ? " NO-AMSDU" : "");
        }
 
        rcu_read_unlock();
@@ -195,6 +195,46 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf,
 }
 STA_OPS(aqm);
 
+static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
+                               size_t count, loff_t *ppos)
+{
+       struct sta_info *sta = file->private_data;
+       struct ieee80211_local *local = sta->sdata->local;
+       size_t bufsz = 200;
+       char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
+       u64 rx_airtime = 0, tx_airtime = 0;
+       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->active_txq_lock[ac]);
+               rx_airtime += sta->airtime[ac].rx_airtime;
+               tx_airtime += sta->airtime[ac].tx_airtime;
+               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"
+               "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);
+       return rv;
+}
+STA_OPS(airtime);
+
 static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
                                        size_t count, loff_t *ppos)
 {
@@ -906,6 +946,10 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
        if (local->ops->wake_tx_queue)
                DEBUGFS_ADD(aqm);
 
+       if (wiphy_ext_feature_isset(local->hw.wiphy,
+                                   NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+               DEBUGFS_ADD(airtime);
+
        if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
                debugfs_create_x32("driver_buffered_tids", 0400,
                                   sta->debugfs_dir,
net/mac80211/ieee80211_i.h +2 -0
index 33763a2eac81..c5b6ba571288 100644
@@ -1137,6 +1137,8 @@ struct ieee80211_local {
        struct list_head active_txqs[IEEE80211_NUM_ACS];
        u16 schedule_round[IEEE80211_NUM_ACS];
 
+       u16 airtime_flags;
+
        const struct ieee80211_ops *ops;
 
        /*
net/mac80211/main.c +4 -0
index ba64757afea4..3710727fa9c1 100644
@@ -667,6 +667,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
                INIT_LIST_HEAD(&local->active_txqs[i]);
                spin_lock_init(&local->active_txq_lock[i]);
        }
+       local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
 
        INIT_LIST_HEAD(&local->chanctx_list);
        mutex_init(&local->chanctx_mtx);
@@ -1153,6 +1154,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        if (!local->hw.max_nan_de_entries)
                local->hw.max_nan_de_entries = IEEE80211_MAX_NAN_INSTANCE_ID;
 
+       if (!local->hw.weight_multiplier)
+               local->hw.weight_multiplier = 1;
+
        result = ieee80211_wep_init(local);
        if (result < 0)
                wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
net/mac80211/sta_info.c +41 -3
index c2f5cb7df54f..25d47b2af7a9 100644
@@ -90,7 +90,6 @@ static void __cleanup_single_sta(struct sta_info *sta)
        struct tid_ampdu_tx *tid_tx;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        struct ieee80211_local *local = sdata->local;
-       struct fq *fq = &local->fq;
        struct ps_data *ps;
 
        if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
@@ -120,9 +119,7 @@ static void __cleanup_single_sta(struct sta_info *sta)
 
                        txqi = to_txq_info(sta->sta.txq[i]);
 
-                       spin_lock_bh(&fq->lock);
                        ieee80211_txq_purge(local, txqi);
-                       spin_unlock_bh(&fq->lock);
                }
        }
 
@@ -387,9 +384,12 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        if (sta_prepare_rate_control(local, sta, gfp))
                goto free_txq;
 
+       sta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT;
+
        for (i = 0; i < IEEE80211_NUM_ACS; i++) {
                skb_queue_head_init(&sta->ps_tx_buf[i]);
                skb_queue_head_init(&sta->tx_filtered[i]);
+               sta->airtime[i].deficit = sta->airtime_weight;
        }
 
        for (i = 0; i < IEEE80211_NUM_TIDS; i++)
@@ -1826,6 +1826,27 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
 }
 EXPORT_SYMBOL(ieee80211_sta_set_buffered);
 
+void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
+                                   u32 tx_airtime, u32 rx_airtime)
+{
+       struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+       struct ieee80211_local *local = sta->sdata->local;
+       u8 ac = ieee80211_ac_from_tid(tid);
+       u32 airtime = 0;
+
+       if (sta->local->airtime_flags & AIRTIME_USE_TX)
+               airtime += tx_airtime;
+       if (sta->local->airtime_flags & AIRTIME_USE_RX)
+               airtime += rx_airtime;
+
+       spin_lock_bh(&local->active_txq_lock[ac]);
+       sta->airtime[ac].tx_airtime += tx_airtime;
+       sta->airtime[ac].rx_airtime += rx_airtime;
+       sta->airtime[ac].deficit -= airtime;
+       spin_unlock_bh(&local->active_txq_lock[ac]);
+}
+EXPORT_SYMBOL(ieee80211_sta_register_airtime);
+
 int sta_info_move_state(struct sta_info *sta,
                        enum ieee80211_sta_state new_state)
 {
@@ -2188,6 +2209,23 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
        }
 
+       if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_DURATION))) {
+               for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
+                       sinfo->rx_duration += sta->airtime[ac].rx_airtime;
+               sinfo->filled |= BIT(NL80211_STA_INFO_RX_DURATION);
+       }
+
+       if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_DURATION))) {
+               for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
+                       sinfo->tx_duration += sta->airtime[ac].tx_airtime;
+               sinfo->filled |= BIT(NL80211_STA_INFO_TX_DURATION);
+       }
+
+       if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) {
+               sinfo->airtime_weight = sta->airtime_weight;
+               sinfo->filled |= BIT(NL80211_STA_INFO_AIRTIME_WEIGHT);
+       }
+
        sinfo->rx_dropped_misc = sta->rx_stats.dropped;
        if (sta->pcpu_rx_stats) {
                for_each_possible_cpu(cpu) {
net/mac80211/sta_info.h +13 -0
index 9a04327d71d1..b1b0fd6a2e21 100644
@@ -127,6 +127,16 @@ enum ieee80211_agg_stop_reason {
        AGG_STOP_DESTROY_STA,
 };
 
+/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
+#define AIRTIME_USE_TX         BIT(0)
+#define AIRTIME_USE_RX         BIT(1)
+
+struct airtime_info {
+       u64 rx_airtime;
+       u64 tx_airtime;
+       s64 deficit;
+};
+
 struct sta_info;
 
 /**
@@ -563,6 +573,9 @@ struct sta_info {
        } tx_stats;
        u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
 
+       struct airtime_info airtime[IEEE80211_NUM_ACS];
+       u16 airtime_weight;
+
        /*
         * Aggregation information, locked with lock.
         */
net/mac80211/status.c +6 -0
index aa4afbf0abaf..a1f1256448f5 100644
@@ -818,6 +818,12 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
                        ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data,
                                                acked, info->status.tx_time);
 
+               if (info->status.tx_time &&
+                   wiphy_ext_feature_isset(local->hw.wiphy,
+                                           NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
+                       ieee80211_sta_register_airtime(&sta->sta, tid,
+                                                      info->status.tx_time, 0);
+
                if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
                        if (info->flags & IEEE80211_TX_STAT_ACK) {
                                if (sta->status_stats.lost_packets)
net/mac80211/tx.c +86 -5
index 305965283506..3f417e80e041 100644
@@ -1488,8 +1488,11 @@ void ieee80211_txq_purge(struct ieee80211_local *local,
        struct fq *fq = &local->fq;
        struct fq_tin *tin = &txqi->tin;
 
+       spin_lock_bh(&fq->lock);
        fq_tin_reset(fq, tin, fq_skb_free_func);
        ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
+       spin_unlock_bh(&fq->lock);
+
        spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
        list_del_init(&txqi->schedule_order);
        spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
@@ -3638,11 +3641,28 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
 
        lockdep_assert_held(&local->active_txq_lock[ac]);
 
+ begin:
        txqi = list_first_entry_or_null(&local->active_txqs[ac],
                                        struct txq_info,
                                        schedule_order);
+       if (!txqi)
+               return NULL;
+
+       if (txqi->txq.sta) {
+               struct sta_info *sta = container_of(txqi->txq.sta,
+                                               struct sta_info, sta);
+
+               if (sta->airtime[txqi->txq.ac].deficit < 0) {
+                       sta->airtime[txqi->txq.ac].deficit +=
+                               sta->airtime_weight;
+                       list_move_tail(&txqi->schedule_order,
+                                      &local->active_txqs[txqi->txq.ac]);
+                       goto begin;
+               }
+       }
+
 
-       if (!txqi || txqi->schedule_round == local->schedule_round[ac])
+       if (txqi->schedule_round == local->schedule_round[ac])
                return NULL;
 
        list_del_init(&txqi->schedule_order);
@@ -3660,12 +3680,74 @@ void ieee80211_return_txq(struct ieee80211_hw *hw,
        lockdep_assert_held(&local->active_txq_lock[txq->ac]);
 
        if (list_empty(&txqi->schedule_order) &&
-           (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets))
-               list_add_tail(&txqi->schedule_order,
-                             &local->active_txqs[txq->ac]);
+           (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
+               /* If airtime accounting is active, always enqueue STAs at the
+                * head of the list to ensure that they only get moved to the
+                * back by the airtime DRR scheduler once they have a negative
+                * deficit. A station that already has a negative deficit will
+                * 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))
+                       list_add(&txqi->schedule_order,
+                                &local->active_txqs[txq->ac]);
+               else
+                       list_add_tail(&txqi->schedule_order,
+                                     &local->active_txqs[txq->ac]);
+       }
 }
 EXPORT_SYMBOL(ieee80211_return_txq);
 
+bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
+                               struct ieee80211_txq *txq)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+       struct txq_info *iter, *tmp, *txqi = to_txq_info(txq);
+       struct sta_info *sta;
+       u8 ac = txq->ac;
+
+       lockdep_assert_held(&local->active_txq_lock[ac]);
+
+       if (!txqi->txq.sta)
+               goto out;
+
+       if (list_empty(&txqi->schedule_order))
+               goto out;
+
+       list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
+                                schedule_order) {
+               if (iter == txqi)
+                       break;
+
+               if (!iter->txq.sta) {
+                       list_move_tail(&iter->schedule_order,
+                                      &local->active_txqs[ac]);
+                       continue;
+               }
+               sta = container_of(iter->txq.sta, struct sta_info, sta);
+               if (sta->airtime[ac].deficit < 0)
+                       sta->airtime[ac].deficit += sta->airtime_weight;
+               list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
+       }
+
+       sta = container_of(txqi->txq.sta, struct sta_info, sta);
+       if (sta->airtime[ac].deficit >= 0)
+               goto out;
+
+       sta->airtime[ac].deficit += sta->airtime_weight;
+       list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
+
+       return false;
+out:
+       if (!list_empty(&txqi->schedule_order))
+               list_del_init(&txqi->schedule_order);
+
+       return true;
+}
+EXPORT_SYMBOL(ieee80211_txq_may_transmit);
+
 void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
 {
        struct ieee80211_local *local = hw_to_local(hw);
--

1.9.1

Quoted 4 lines

_______________________________________________
Make-wifi-fast mailing list
[email protected]
https://lists.bufferbloat.net/listinfo/make-wifi-fast

_______________________________________________
ath10k mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/ath10k

#23 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 7 lines · Louie Lu

Hi Rajkumar, Toke,

I found the series (v3,4/6) remove the debugfs remove reset station's airtime method, and didn't added at here.

Not sure how to help this kind of situation, do I need a separate patch to fix this, or posting the patch here is fine?

This is fine; we can fold it into the next version. Thanks :)

-Toke

maintainer
#24 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 11 lines · Toke Høiland-Jørgensen
Quoted 7 lines · Louie Lu

Hi Rajkumar, Toke,

I found the series (v3,4/6) remove the debugfs remove reset station's airtime method, and didn't added at here.

Not sure how to help this kind of situation, do I need a separate patch to fix this, or posting the patch here is fine?

This is fine; we can fold it into the next version. Thanks :)

Just FYI - I'm going to assume, given this comment and the long discussion, that there will be a next version :)

johannes

#25 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

Quoted 9 lines · Johannes Berg
Quoted 8 lines · Toke Høiland-Jørgensen
Quoted 6 lines · Louie Lu

Hi Rajkumar, Toke,

I found the series (v3,4/6) remove the debugfs remove reset station's
airtime method, and didn't added at here.

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

Not sure how to help this kind of situation, do I need a separate patch to fix this, or posting the patch here is fine?

This is fine; we can fold it into the next version. Thanks :)

Just FYI - I'm going to assume, given this comment and the long discussion, that there will be a next version :)

I think toke's still sleeping off the post graduation hangover.

Quoted 7 lines

johannes

_______________________________________________
Make-wifi-fast mailing list
[email protected]
https://lists.bufferbloat.net/listinfo/make-wifi-fast

#26 lore raw

Re: [Make-wifi-fast] [PATCH v3 3/6] mac80211: Add airtime accounting and scheduling to TXQs

In reply to Johannes Berg
Quoted 8 lines · Johannes Berg
Quoted 7 lines · Toke Høiland-Jørgensen
Quoted 5 lines · Louie Lu

Hi Rajkumar, Toke,

I found the series (v3,4/6) remove the debugfs remove reset station's airtime method, and didn't added at here.

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

Not sure how to help this kind of situation, do I need a separate patch to fix this, or posting the patch here is fine?

This is fine; we can fold it into the next version. Thanks :)

Just FYI - I'm going to assume, given this comment and the long discussion, that there will be a next version :)

Yes. Got caught up in moving before I managed to get another version out. Will get around to it eventually, promise! :)

-Toke

#27 lore raw

PATCH v3 4/6 ath9k: Switch to mac80211 TXQ scheduling and airtime APIs

In reply to Rajkumar Manoharan

From: Toke Høiland-Jørgensen <[email protected]>

This moves the ath9k driver to use the mac80211 TXQ scheduling and airtime accounting APIs, removing the corresponding state tracking inside the driver.

---
 drivers/net/wireless/ath/ath9k/ath9k.h     |  14 --
 drivers/net/wireless/ath/ath9k/debug.c     |   3 -
 drivers/net/wireless/ath/ath9k/debug.h     |   8 -
 drivers/net/wireless/ath/ath9k/debug_sta.c |  70 ---------
 drivers/net/wireless/ath/ath9k/init.c      |   3 +-
 drivers/net/wireless/ath/ath9k/recv.c      |   9 +-
 drivers/net/wireless/ath/ath9k/xmit.c      | 244 +++++++++--------------------
 7 files changed, 75 insertions(+), 276 deletions(-)
drivers/net/wireless/ath/ath9k/ath9k.h +0 -14
index 21ba20981a80..90b56766dab1 100644
@@ -112,8 +112,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 #define ATH_TXFIFO_DEPTH           8
 #define ATH_TX_ERROR               0x01
 
-#define ATH_AIRTIME_QUANTUM        300 /* usec */
-
 /* Stop tx traffic 1ms before the GO goes away */
 #define ATH_P2P_PS_STOP_TIME       1000
 
@@ -246,10 +244,8 @@ struct ath_atx_tid {
 	s8 bar_index;
 	bool active;
 	bool clear_ps_filter;
-	bool has_queued;
 };
 
-void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
 void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
 
 struct ath_node {
@@ -263,12 +259,9 @@ struct ath_node {
 
 	bool sleeping;
 	bool no_ps_filter;
-	s64 airtime_deficit[IEEE80211_NUM_ACS];
-	u32 airtime_rx_start;
 
 #ifdef CONFIG_ATH9K_STATION_STATISTICS
 	struct ath_rx_rate_stats rx_rate_stats;
-	struct ath_airtime_stats airtime_stats;
 #endif
 	u8 key_idx[4];
 
@@ -986,11 +979,6 @@ struct ath_ant_comb {
 
 #define ATH9K_NUM_CHANCTX  2 /* supports 2 operating channels */
 
-#define AIRTIME_USE_TX		BIT(0)
-#define AIRTIME_USE_RX		BIT(1)
-#define AIRTIME_USE_NEW_QUEUES	BIT(2)
-#define AIRTIME_ACTIVE(flags) (!!(flags & (AIRTIME_USE_TX|AIRTIME_USE_RX)))
-
 struct ath_softc {
 	struct ieee80211_hw *hw;
 	struct device *dev;
@@ -1034,8 +1022,6 @@ struct ath_softc {
 	short nbcnvifs;
 	unsigned long ps_usecount;
 
-	u16 airtime_flags; /* AIRTIME_* */
-
 	struct ath_rx rx;
 	struct ath_tx tx;
 	struct ath_beacon beacon;
drivers/net/wireless/ath/ath9k/debug.c +0 -3
index 4399e9ad058f..0dfea5d6e949 100644
@@ -1443,9 +1443,6 @@ int ath9k_init_debug(struct ath_hw *ah)
 #endif
 	debugfs_create_file("tpc", 0600, sc->debug.debugfs_phy, sc, &fops_tpc);
 
-	debugfs_create_u16("airtime_flags", 0600,
-			   sc->debug.debugfs_phy, &sc->airtime_flags);
-
 	debugfs_create_file("nf_override", 0600,
 			    sc->debug.debugfs_phy, sc, &fops_nf_override);
 
drivers/net/wireless/ath/ath9k/debug.h +0 -8
index 79607db14387..33826aa13687 100644
@@ -319,20 +319,12 @@ static inline void ath9k_debug_stat_ant(struct ath_softc *sc,
 void ath_debug_rate_stats(struct ath_softc *sc,
 			  struct ath_rx_status *rs,
 			  struct sk_buff *skb);
-void ath_debug_airtime(struct ath_softc *sc,
-		       struct ath_node *an,
-		       u32 rx, u32 tx);
 #else
 static inline void ath_debug_rate_stats(struct ath_softc *sc,
 					struct ath_rx_status *rs,
 					struct sk_buff *skb)
 {
 }
-static inline void ath_debug_airtime(struct ath_softc *sc,
-			      struct ath_node *an,
-			      u32 rx, u32 tx)
-{
-}
 #endif /* CONFIG_ATH9K_STATION_STATISTICS */
 
 #endif /* DEBUG_H */
drivers/net/wireless/ath/ath9k/debug_sta.c +0 -70

80 lines not on this page · raw message

drivers/net/wireless/ath/ath9k/init.c +1 -2
index c070a9e51ebf..45a31f8a1514 100644
@@ -676,8 +676,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
 
 	/* Will be cleared in ath9k_start() */
 	set_bit(ATH_OP_INVALID, &common->op_flags);
-	sc->airtime_flags = (AIRTIME_USE_TX | AIRTIME_USE_RX |
-			     AIRTIME_USE_NEW_QUEUES);
 
 	sc->sc_ah = ah;
 	sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
@@ -1013,6 +1011,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
 
 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
 }
 
 int ath9k_init_device(u16 devid, struct ath_softc *sc,
drivers/net/wireless/ath/ath9k/recv.c +1 -8
index 30d1bd832d90..285a62d3019d 100644
@@ -1054,14 +1054,7 @@ static void ath_rx_count_airtime(struct ath_softc *sc,
 						len, rxs->rate_idx, is_sp);
 	}
 
- 	if (!!(sc->airtime_flags & AIRTIME_USE_RX)) {
-		spin_lock_bh(&acq->lock);
-		an->airtime_deficit[acno] -= airtime;
-		if (an->airtime_deficit[acno] <= 0)
-			__ath_tx_queue_tid(sc, ATH_AN_2_TID(an, tidno));
-		spin_unlock_bh(&acq->lock);
-	}
-	ath_debug_airtime(sc, an, airtime, 0);
+	ieee80211_sta_register_airtime(sta, tidno, 0, airtime);
 exit:
 	rcu_read_unlock();
 }
drivers/net/wireless/ath/ath9k/xmit.c +73 -171

491 lines not on this page · raw message

Signature · 1 line
1.9.1
#28 lore raw

PATCH v3 5/6 ath10k: migrate to mac80211 txq scheduling

In reply to Rajkumar Manoharan

From: Toke Høiland-Jørgensen <[email protected]>

ath10k maintains common txqs list for all stations. This txq management can be removed by migrating to mac80211 txq APIs and let mac80211 handle txqs reordering based on reported airtime. By doing this, txq fairness maintained in ath10k i.e processing N frames per txq is removed. By adapting to mac80211 APIs, ath10k will support mac80211 based airtime fairness algorithm.

---
 drivers/net/wireless/ath/ath10k/core.c   |  2 -
 drivers/net/wireless/ath/ath10k/core.h   |  6 +-
 drivers/net/wireless/ath/ath10k/htc.h    |  1 -
 drivers/net/wireless/ath/ath10k/htt_rx.c |  8 +++
 drivers/net/wireless/ath/ath10k/mac.c    | 98 ++++++++++++++------------------
 5 files changed, 54 insertions(+), 61 deletions(-)
drivers/net/wireless/ath/ath10k/core.c +0 -2
index da607febfd82..c8dbbfa901af 100644
@@ -3065,9 +3065,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
 
 	mutex_init(&ar->conf_mutex);
 	spin_lock_init(&ar->data_lock);
-	spin_lock_init(&ar->txqs_lock);
 
-	INIT_LIST_HEAD(&ar->txqs);
 	INIT_LIST_HEAD(&ar->peers);
 	init_waitqueue_head(&ar->peer_mapping_wq);
 	init_waitqueue_head(&ar->htt.empty_tx_wq);
drivers/net/wireless/ath/ath10k/core.h +3 -3
index 042418097cf9..45afa813555c 100644
@@ -90,6 +90,9 @@
 /* The magic used by QCA spec */
 #define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_"
 
+/* Default Airtime weight multipler (Tuned for multiclient performance) */
+#define ATH10K_AIRTIME_WEIGHT_MULTIPLIER  4
+
 struct ath10k;
 
 static inline const char *ath10k_bus_str(enum ath10k_bus bus)
@@ -1062,10 +1065,7 @@ struct ath10k {
 
 	/* protects shared structure data */
 	spinlock_t data_lock;
-	/* protects: ar->txqs, artxq->list */
-	spinlock_t txqs_lock;
 
-	struct list_head txqs;
 	struct list_head arvifs;
 	struct list_head peers;
 	struct ath10k_peer *peer_map[ATH10K_MAX_NUM_PEER_IDS];
drivers/net/wireless/ath/ath10k/htc.h +0 -1
index 51fda6c23f69..cb30add7dd33 100644
@@ -51,7 +51,6 @@
  */
 
 #define HTC_HOST_MAX_MSG_PER_RX_BUNDLE        8
-#define HTC_HOST_MAX_MSG_PER_TX_BUNDLE        16
 
 enum ath10k_htc_tx_flags {
 	ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE = 0x01,
drivers/net/wireless/ath/ath10k/htt_rx.c +8 -0
index ffec98f7be50..35738fc84271 100644
@@ -2379,6 +2379,7 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb)
 	u8 tid;
 	int ret;
 	int i;
+	bool may_tx;
 
 	ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch ind\n");
 
@@ -2451,8 +2452,13 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb)
 		num_msdus = 0;
 		num_bytes = 0;
 
+		ieee80211_txq_schedule_start(hw, txq->ac);
+		may_tx = ieee80211_txq_may_transmit(hw, txq);
 		while (num_msdus < max_num_msdus &&
 		       num_bytes < max_num_bytes) {
+			if (!may_tx)
+				break;
+
 			ret = ath10k_mac_tx_push_txq(hw, txq);
 			if (ret < 0)
 				break;
@@ -2460,6 +2466,8 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb)
 			num_msdus++;
 			num_bytes += ret;
 		}
+		ieee80211_return_txq(hw, txq);
+		ieee80211_txq_schedule_end(hw, txq->ac);
 
 		record->num_msdus = cpu_to_le16(num_msdus);
 		record->num_bytes = cpu_to_le32(num_bytes);
drivers/net/wireless/ath/ath10k/mac.c +43 -55

154 lines not on this page · raw message

Signature · 1 line
1.9.1
#29 lore raw

PATCH v3 6/6 ath10k: reporting estimated tx airtime for fairness

In reply to Rajkumar Manoharan

From: Kan Yan <[email protected]>

Transmit airtime will be estimated from last tx rate used. Firmware report tx rate by peer stats. Airtime is computed on tx path and the same will be reported to mac80211 upon tx completion.

This change is based on Kan's orginal commit in Chromium tree ("CHROMIUM: ath10k: Implementing airtime fairness based TX scheduler")
ref: https://chromium-review.googlesource.com/588190

[[email protected]: ported only the airtime computation]
---
 drivers/net/wireless/ath/ath10k/core.h   |  2 ++
 drivers/net/wireless/ath/ath10k/htt_rx.c |  1 +
 drivers/net/wireless/ath/ath10k/mac.c    | 57 ++++++++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath10k/txrx.c   |  4 +++
 4 files changed, 61 insertions(+), 3 deletions(-)
drivers/net/wireless/ath/ath10k/core.h +2 -0
index 45afa813555c..883bf4613ab3 100644
@@ -126,6 +126,7 @@ struct ath10k_skb_cb {
 	u8 flags;
 	u8 eid;
 	u16 msdu_id;
+	u16 airtime_est;
 	struct ieee80211_vif *vif;
 	struct ieee80211_txq *txq;
 } __packed;
@@ -496,6 +497,7 @@ struct ath10k_sta {
 	u32 smps;
 	u16 peer_id;
 	struct rate_info txrate;
+	u32 last_tx_bitrate;
 
 	struct work_struct update_wk;
 	u64 rx_duration;
drivers/net/wireless/ath/ath10k/htt_rx.c +1 -0
index 35738fc84271..26134bed52d2 100644
@@ -2808,6 +2808,7 @@ static inline int ath10k_get_legacy_rate_idx(struct ath10k *ar, u8 rate)
 
 	arsta->txrate.nss = txrate.nss;
 	arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw);
+	arsta->last_tx_bitrate = cfg80211_calculate_bitrate(&arsta->txrate);
 
 	if (ath10k_debug_is_extd_tx_stats_enabled(ar))
 		ath10k_accumulate_per_peer_tx_stats(ar, arsta, peer_stats,
drivers/net/wireless/ath/ath10k/mac.c +54 -3

100 lines not on this page · raw message

drivers/net/wireless/ath/ath10k/txrx.c +4 -0
index 23606b6972d0..8e7c416cd330 100644
@@ -95,6 +95,10 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
 		wake_up(&htt->empty_tx_wq);
 	spin_unlock_bh(&htt->tx_lock);
 
+	if (txq && txq->sta)
+		ieee80211_sta_register_airtime(txq->sta, txq->tid,
+					       skb_cb->airtime_est, 0);
+
 	if (ar->dev_type != ATH10K_DEV_TYPE_HL)
 		dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
 
Signature · 1 line
1.9.1