This contains the following commits: ``` git log --oneline v6.12.52...v6.12.61 -- drivers/net/wireless/ net/mac80211/ net/wireless/ a1eb56723b32 wifi: ath12k: correctly handle mcast packets for clients c0a9c2c1b7b9 wifi: mac80211: use wiphy_hrtimer_work for csa.switch_work d4caee32a9f8 wifi: cfg80211: add an hrtimer based delayed work item 6455948c8aab wifi: mac80211: reject address change while connecting 80dc5a2ce5b7 wifi: ath11k: Clear affinity hint before calling ath11k_pcic_free_irq() in error path acd24d509227 wifi: mac80211: skip rate verification for not captured PSDUs 53cf801b8555 wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp() e8fa86b0bd96 wifi: mac80211_hwsim: Limit destroy_on_close radio removal to netgroup 77d4afd6c78b Revert "wifi: ath10k: avoid unnecessary wait for service ready message" 07d862c7de3d wifi: ath12k: Increase DP_REO_CMD_RING_SIZE to 256 522734fc807c wifi: mac80211: Track NAN interface start/stop 8db790c2491e wifi: ath10k: Fix connection after GTK rekeying 72f1984246e6 wifi: rtw89: renew a completion for each H2C command waiting C2H event 336da4414300 wifi: rtw89: obtain RX path from ppdu status IE00 da91687f01f4 wifi: mt76: mt7996: fix memory leak on mt7996_mcu_sta_key_tlv error a534dd44b70e wifi: mt76: mt76_eeprom_override to int aa5ed215cfe8 wifi: mt76: mt7996: Temporarily disable EPCS efe2ef24feab wifi: mt76: mt7921: Add 160MHz beamformee capability for mt7922 device 5de410dfb4d9 wifi: mac80211: Fix HE capabilities element check f157d1cb2cdc wifi: iwlwifi: fw: Add ASUS to PPAG and TAS list c9df78e84e85 wifi: mac80211: Fix 6 GHz Band capabilities element advertisement in lower bands 958234997dd5 wifi: rtw89: fix BSSID comparison for non-transmitted BSSID ca18975c4de2 wifi: rtw89: wow: remove notify during WoWLAN net-detect bc1ca06998c1 wifi: rtw88: sdio: use indirect IO for device registers before power-on 8ebef59d0294 wifi: rtw89: print just once for unknown C2H events 5596a90c8952 wifi: mac80211: fix key tailroom accounting leak 23b8682f05ec wifi: mac80211: don't mark keys for inactive links as uploaded e3373f10c6a6 wifi: ath11k: avoid bit operation on key flags 50f50dd024b4 wifi: ath11k: add support for MU EDCA 2a6cd5951ba8 wifi: ath12k: free skb during idr cleanup callback 775e37df2acc wifi: ath11k: Add missing platform IDs for quirk table c4840991ee4c wifi: ath10k: Fix memory leak on unsupported WMI command a6eed58249e7 wifi: brcmfmac: fix crash while sending Action Frames in standalone AP Mode 57100b87c778 wifi: ath12k: fix read pointer after free in ath12k_mac_assign_vif_to_vdev() 4a63523d3541 wifi: cfg80211: Add missing lock in cfg80211_check_and_end_cac() e9fd43b799d2 wifi: rtw89: avoid possible TX wait initialization race b419093e5e42 wifi: mt76: mt7921u: Add VID/PID for Netgear A7500 feb1774aaf85 wifi: mt76: mt7925u: Add VID/PID for Netgear A9000 bd3ac455a88d wifi: ath11k: HAL SRNG: don't deinitialize and re-initialize again 8055133a9f64 wifi: rtw89: avoid circular locking dependency in ser_state_run() 1c873416758f wifi: mac80211: fix Rx packet handling when pubsta information is not available 6e7d9fa61d7d wifi: ath10k: avoid unnecessary wait for service ready message 8d4f6ab4c53e wifi: ath12k: fix wrong logging ID used for CE fc00890c55e3 wifi: mt76: mt7915: fix mt7981 pre-calibration e18c4e6ba36c wifi: mt76: mt7996: Convert mt7996_wed_rro_addr to LE f481404a9826 wifi: mt76: mt7996: Fix RX packets configuration for primary WED device 57519239c76c wifi: mt76: fix potential memory leak in mt76_wmac_probe() 27c8e2e4b56f wifi: iwlwifi: Remove redundant header files 605402433eb8 wifi: mwifiex: send world regulatory domain to driver ``` The removed patch was added upstream. Link: https://github.com/openwrt/openwrt/pull/21134 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
294 lines
8.7 KiB
Diff
294 lines
8.7 KiB
Diff
From: Felix Fietkau <nbd@nbd.name>
|
|
Date: Fri, 9 Feb 2024 19:43:40 +0100
|
|
Subject: [PATCH] mac80211: add AQL support for broadcast packets
|
|
|
|
Excessive broadcast traffic with little competing unicast traffic can easily
|
|
flood hardware queues, leading to throughput issues. Additionally, filling
|
|
the hardware queues with too many packets breaks FQ for broadcast data.
|
|
Fix this by enabling AQL for broadcast packets.
|
|
|
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
---
|
|
|
|
--- a/include/net/cfg80211.h
|
|
+++ b/include/net/cfg80211.h
|
|
@@ -3426,6 +3426,7 @@ enum wiphy_params_flags {
|
|
/* The per TXQ device queue limit in airtime */
|
|
#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 5000
|
|
#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 12000
|
|
+#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC 50000
|
|
|
|
/* The per interface airtime threshold to switch to lower queue limit */
|
|
#define IEEE80211_AQL_THRESHOLD 24000
|
|
--- a/net/mac80211/debugfs.c
|
|
+++ b/net/mac80211/debugfs.c
|
|
@@ -215,11 +215,13 @@ static ssize_t aql_pending_read(struct f
|
|
"VI %u us\n"
|
|
"BE %u us\n"
|
|
"BK %u us\n"
|
|
+ "BC/MC %u us\n"
|
|
"total %u us\n",
|
|
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]),
|
|
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]),
|
|
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]),
|
|
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]),
|
|
+ atomic_read(&local->aql_bc_pending_airtime),
|
|
atomic_read(&local->aql_total_pending_airtime));
|
|
return simple_read_from_buffer(user_buf, count, ppos,
|
|
buf, len);
|
|
@@ -245,7 +247,8 @@ static ssize_t aql_txq_limit_read(struct
|
|
"VO %u %u\n"
|
|
"VI %u %u\n"
|
|
"BE %u %u\n"
|
|
- "BK %u %u\n",
|
|
+ "BK %u %u\n"
|
|
+ "BC/MC %u\n",
|
|
local->aql_txq_limit_low[IEEE80211_AC_VO],
|
|
local->aql_txq_limit_high[IEEE80211_AC_VO],
|
|
local->aql_txq_limit_low[IEEE80211_AC_VI],
|
|
@@ -253,7 +256,8 @@ static ssize_t aql_txq_limit_read(struct
|
|
local->aql_txq_limit_low[IEEE80211_AC_BE],
|
|
local->aql_txq_limit_high[IEEE80211_AC_BE],
|
|
local->aql_txq_limit_low[IEEE80211_AC_BK],
|
|
- local->aql_txq_limit_high[IEEE80211_AC_BK]);
|
|
+ local->aql_txq_limit_high[IEEE80211_AC_BK],
|
|
+ local->aql_txq_limit_bc);
|
|
return simple_read_from_buffer(user_buf, count, ppos,
|
|
buf, len);
|
|
}
|
|
@@ -279,6 +283,11 @@ static ssize_t aql_txq_limit_write(struc
|
|
else
|
|
buf[count] = '\0';
|
|
|
|
+ if (sscanf(buf, "mcast %u", &q_limit_low) == 1) {
|
|
+ local->aql_txq_limit_bc = q_limit_low;
|
|
+ return count;
|
|
+ }
|
|
+
|
|
if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
|
|
return -EINVAL;
|
|
|
|
--- a/net/mac80211/ieee80211_i.h
|
|
+++ b/net/mac80211/ieee80211_i.h
|
|
@@ -1362,10 +1362,12 @@ struct ieee80211_local {
|
|
spinlock_t handle_wake_tx_queue_lock;
|
|
|
|
u16 airtime_flags;
|
|
+ u32 aql_txq_limit_bc;
|
|
u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
|
|
u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
|
|
u32 aql_threshold;
|
|
atomic_t aql_total_pending_airtime;
|
|
+ atomic_t aql_bc_pending_airtime;
|
|
atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS];
|
|
|
|
const struct ieee80211_ops *ops;
|
|
--- a/net/mac80211/main.c
|
|
+++ b/net/mac80211/main.c
|
|
@@ -954,6 +954,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
|
spin_lock_init(&local->rx_path_lock);
|
|
spin_lock_init(&local->queue_stop_reason_lock);
|
|
|
|
+ local->aql_txq_limit_bc = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC;
|
|
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
|
INIT_LIST_HEAD(&local->active_txqs[i]);
|
|
spin_lock_init(&local->active_txq_lock[i]);
|
|
--- a/net/mac80211/sta_info.c
|
|
+++ b/net/mac80211/sta_info.c
|
|
@@ -2360,13 +2360,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggre
|
|
|
|
void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
|
|
struct sta_info *sta, u8 ac,
|
|
- u16 tx_airtime, bool tx_completed)
|
|
+ u16 tx_airtime, bool tx_completed,
|
|
+ bool mcast)
|
|
{
|
|
int tx_pending;
|
|
|
|
if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
|
|
return;
|
|
|
|
+ if (mcast) {
|
|
+ if (!tx_completed) {
|
|
+ atomic_add(tx_airtime, &local->aql_bc_pending_airtime);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ tx_pending = atomic_sub_return(tx_airtime,
|
|
+ &local->aql_bc_pending_airtime);
|
|
+ if (tx_pending < 0)
|
|
+ atomic_cmpxchg(&local->aql_bc_pending_airtime,
|
|
+ tx_pending, 0);
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (!tx_completed) {
|
|
if (sta)
|
|
atomic_add(tx_airtime,
|
|
--- a/net/mac80211/tx.c
|
|
+++ b/net/mac80211/tx.c
|
|
@@ -2554,7 +2554,7 @@ static u16 ieee80211_store_ack_skb(struc
|
|
|
|
spin_lock_irqsave(&local->ack_status_lock, flags);
|
|
id = idr_alloc(&local->ack_status_frames, ack_skb,
|
|
- 1, 0x2000, GFP_ATOMIC);
|
|
+ 1, 0x1000, GFP_ATOMIC);
|
|
spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
|
|
|
if (id >= 0) {
|
|
@@ -3983,20 +3983,20 @@ begin:
|
|
encap_out:
|
|
info->control.vif = vif;
|
|
|
|
- if (tx.sta &&
|
|
- wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
|
|
- bool ampdu = txq->ac != IEEE80211_AC_VO;
|
|
+ if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
|
|
+ bool ampdu = txq->sta && txq->ac != IEEE80211_AC_VO;
|
|
u32 airtime;
|
|
|
|
airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
|
|
skb->len, ampdu);
|
|
- if (airtime) {
|
|
- airtime = ieee80211_info_set_tx_time_est(info, airtime);
|
|
- ieee80211_sta_update_pending_airtime(local, tx.sta,
|
|
- txq->ac,
|
|
- airtime,
|
|
- false);
|
|
- }
|
|
+ if (!airtime)
|
|
+ return skb;
|
|
+
|
|
+ airtime = ieee80211_info_set_tx_time_est(info, airtime);
|
|
+ info->tx_time_mc = !tx.sta;
|
|
+ ieee80211_sta_update_pending_airtime(local, tx.sta, txq->ac,
|
|
+ airtime, false,
|
|
+ info->tx_time_mc);
|
|
}
|
|
|
|
return skb;
|
|
@@ -4048,6 +4048,7 @@ struct ieee80211_txq *ieee80211_next_txq
|
|
struct ieee80211_txq *ret = NULL;
|
|
struct txq_info *txqi = NULL, *head = NULL;
|
|
bool found_eligible_txq = false;
|
|
+ bool aql_check;
|
|
|
|
spin_lock_bh(&local->active_txq_lock[ac]);
|
|
|
|
@@ -4071,26 +4072,26 @@ struct ieee80211_txq *ieee80211_next_txq
|
|
if (!head)
|
|
head = txqi;
|
|
|
|
+ aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
|
|
+ if (aql_check)
|
|
+ found_eligible_txq = true;
|
|
+
|
|
if (txqi->txq.sta) {
|
|
struct sta_info *sta = container_of(txqi->txq.sta,
|
|
struct sta_info, sta);
|
|
- bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
|
|
- s32 deficit = ieee80211_sta_deficit(sta, txqi->txq.ac);
|
|
-
|
|
- if (aql_check)
|
|
- found_eligible_txq = true;
|
|
-
|
|
- if (deficit < 0)
|
|
+ if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
|
|
sta->airtime[txqi->txq.ac].deficit +=
|
|
sta->airtime_weight << AIRTIME_QUANTUM_SHIFT;
|
|
-
|
|
- if (deficit < 0 || !aql_check) {
|
|
- list_move_tail(&txqi->schedule_order,
|
|
- &local->active_txqs[txqi->txq.ac]);
|
|
- goto begin;
|
|
+ aql_check = false;
|
|
}
|
|
}
|
|
|
|
+ if (!aql_check) {
|
|
+ list_move_tail(&txqi->schedule_order,
|
|
+ &local->active_txqs[txqi->txq.ac]);
|
|
+ goto begin;
|
|
+ }
|
|
+
|
|
if (txqi->schedule_round == local->schedule_round[ac])
|
|
goto out;
|
|
|
|
@@ -4157,7 +4158,8 @@ bool ieee80211_txq_airtime_check(struct
|
|
return true;
|
|
|
|
if (!txq->sta)
|
|
- return true;
|
|
+ return atomic_read(&local->aql_bc_pending_airtime) <
|
|
+ local->aql_txq_limit_bc;
|
|
|
|
if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
|
|
return true;
|
|
@@ -4206,15 +4208,15 @@ bool ieee80211_txq_may_transmit(struct i
|
|
|
|
spin_lock_bh(&local->active_txq_lock[ac]);
|
|
|
|
- if (!txqi->txq.sta)
|
|
- goto out;
|
|
-
|
|
if (list_empty(&txqi->schedule_order))
|
|
goto out;
|
|
|
|
if (!ieee80211_txq_schedule_airtime_check(local, ac))
|
|
goto out;
|
|
|
|
+ if (!txqi->txq.sta)
|
|
+ goto out;
|
|
+
|
|
list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
|
|
schedule_order) {
|
|
if (iter == txqi)
|
|
--- a/include/net/mac80211.h
|
|
+++ b/include/net/mac80211.h
|
|
@@ -1222,8 +1222,8 @@ struct ieee80211_tx_info {
|
|
status_data_idr:1,
|
|
status_data:13,
|
|
hw_queue:4,
|
|
+ tx_time_mc:1,
|
|
tx_time_est:10;
|
|
- /* 1 free bit */
|
|
|
|
union {
|
|
struct {
|
|
--- a/net/mac80211/sta_info.h
|
|
+++ b/net/mac80211/sta_info.h
|
|
@@ -147,7 +147,8 @@ struct airtime_info {
|
|
|
|
void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
|
|
struct sta_info *sta, u8 ac,
|
|
- u16 tx_airtime, bool tx_completed);
|
|
+ u16 tx_airtime, bool tx_completed,
|
|
+ bool mcast);
|
|
|
|
struct sta_info;
|
|
|
|
--- a/net/mac80211/status.c
|
|
+++ b/net/mac80211/status.c
|
|
@@ -734,7 +734,7 @@ static void ieee80211_report_used_skb(st
|
|
ieee80211_sta_update_pending_airtime(local, sta,
|
|
skb_get_queue_mapping(skb),
|
|
tx_time_est,
|
|
- true);
|
|
+ true, info->tx_time_mc);
|
|
rcu_read_unlock();
|
|
}
|
|
|
|
@@ -1158,10 +1158,11 @@ void ieee80211_tx_status_ext(struct ieee
|
|
/* Do this here to avoid the expensive lookup of the sta
|
|
* in ieee80211_report_used_skb().
|
|
*/
|
|
+ bool mcast = IEEE80211_SKB_CB(skb)->tx_time_mc;
|
|
ieee80211_sta_update_pending_airtime(local, sta,
|
|
skb_get_queue_mapping(skb),
|
|
tx_time_est,
|
|
- true);
|
|
+ true, mcast);
|
|
ieee80211_info_set_tx_time_est(IEEE80211_SKB_CB(skb), 0);
|
|
}
|
|
|