From patchwork Fri Dec 13 07:19:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yibo Zhao X-Patchwork-Id: 11290053 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1322714BD for ; Fri, 13 Dec 2019 07:19:23 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DC98922527 for ; Fri, 13 Dec 2019 07:19:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="HsaliCJ7"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="Mz3teFvU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DC98922527 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=BWn2fE8syN+cyEOtT92pdLLfr/g67G2VAOIdjAtzF5o=; b=HsaliCJ7bfcxqj iWIY78vNWROCNAJNz/r9OipI2DBPEtO1KaXhI/Nf1sy8cOPx7LeZ0gI2JPvOEzQ/r8AcMHP8wGJwX B2J2/PI4na5efzz1v2VupmMGiTdDETD6dGYpE8VPzZIlu9qKFo1mm33KH7fUIihSfvIxLihFyGKH4 wjGplyLyO780Hrfq3IVn0fZOIQzXGuHCk5TDRlabdLwx8rCBBveoK0uI0YMGP7CvtA/rqk60i7DVR SGZIDP47Fjc9RiHaRUB7Othq8t3sJxA1ZzZ1SfyseIXzZMe7nBMagyUErJTJIXCavT2HpN2ojjiwb V5WvWADG5HHRo8aw9dMw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iffEQ-0002bc-Ci; Fri, 13 Dec 2019 07:19:22 +0000 Received: from m228-4.mailgun.net ([159.135.228.4]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iffEM-0002YL-1y for ath10k@lists.infradead.org; Fri, 13 Dec 2019 07:19:20 +0000 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1576221557; h=Content-Transfer-Encoding: Content-Type: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=g8waSKlKjg6lHTRkOcQkpZURa0Z2Cgf8vxMzu+EHZlI=; b=Mz3teFvUFUNdsPtox/YK36C6eYko4wbu8W2lRX2bwmirFX6j1MBRqDPVKhXW8JXVgZz0G68N 9afm9QB2CKoXX2hrfe6k6gl7Himt3Ik55thW5TKmX3qWOHJPu/Kde2pO2lsR1XCwguNL+kDD 1LlS2PKeEWQhAgrTSkjeNg03r/M= X-Mailgun-Sending-Ip: 159.135.228.4 X-Mailgun-Sid: WyJiZDQ3OSIsICJhdGgxMGtAbGlzdHMuaW5mcmFkZWFkLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5df33b74.7f08bad394c8-smtp-out-n02; Fri, 13 Dec 2019 07:19:16 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id A7F4CC433A2; Fri, 13 Dec 2019 07:19:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from ybzhao-HP-Z230-SFF-Workstation.ap.qualcomm.com (unknown [180.166.53.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: yiboz) by smtp.codeaurora.org (Postfix) with ESMTPSA id 3C79AC433CB; Fri, 13 Dec 2019 07:19:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 3C79AC433CB Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=yiboz@codeaurora.org From: Yibo Zhao To: linux-wireless@vger.kernel.org Subject: [PATCH 1/4] mac80211: Switch to a virtual time-based airtime scheduler Date: Fri, 13 Dec 2019 15:19:50 +0800 Message-Id: <1576221593-1086-2-git-send-email-yiboz@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1576221593-1086-1-git-send-email-yiboz@codeaurora.org> References: <1576221593-1086-1-git-send-email-yiboz@codeaurora.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191212_231918_205869_E36A292E X-CRM114-Status: GOOD ( 20.71 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [159.135.228.4 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= , ath10k@lists.infradead.org Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org From: Toke Høiland-Jørgensen This switches the airtime scheduler in mac80211 to use a virtual time-based scheduler instead of the round-robin scheduler used before. This has a couple of advantages: - No need to sync up the round-robin scheduler in firmware/hardware with the round-robin airtime scheduler. - If several stations are eligible for transmission we can schedule both of them; no need to hard-block the scheduling rotation until the head of the queue has used up its quantum. - The check of whether a station is eligible for transmission becomes simpler (in ieee80211_txq_may_transmit()). The drawback is that scheduling becomes slightly more expensive, as we need to maintain an rbtree of TXQs sorted by virtual time. This means that ieee80211_register_airtime() becomes O(logN) in the number of currently scheduled TXQs. However, hopefully this number rarely grows too big (it's only TXQs currently backlogged, not all associated stations), so it shouldn't be too big of an issue. Signed-off-by: Toke Høiland-Jørgensen --- net/mac80211/debugfs.c | 48 +++++++++- net/mac80211/debugfs_sta.c | 16 ++-- net/mac80211/ieee80211_i.h | 14 ++- net/mac80211/main.c | 2 +- net/mac80211/sta_info.c | 19 +++- net/mac80211/sta_info.h | 3 +- net/mac80211/tx.c | 217 +++++++++++++++++++++++++++++---------------- 7 files changed, 223 insertions(+), 96 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 2d43bc1..4847168 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -150,6 +150,46 @@ static ssize_t aqm_write(struct file *file, .llseek = default_llseek, }; +static ssize_t airtime_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct ieee80211_local *local = file->private_data; + char buf[200]; + u64 v_t[IEEE80211_NUM_ACS]; + u64 wt[IEEE80211_NUM_ACS]; + int len = 0, ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + spin_lock_bh(&local->active_txq_lock[ac]); + v_t[ac] = local->airtime_v_t[ac]; + wt[ac] = local->airtime_weight_sum[ac]; + spin_unlock_bh(&local->active_txq_lock[ac]); + } + len = scnprintf(buf, sizeof(buf), + "\tVO VI BE BK\n" + "Virt-t\t%-10llu %-10llu %-10llu %-10llu\n" + "Weight\t%-10llu %-10llu %-10llu %-10llu\n", + v_t[0], + v_t[1], + v_t[2], + v_t[3], + wt[0], + wt[1], + wt[2], + wt[3]); + + return simple_read_from_buffer(user_buf, count, ppos, + buf, len); +} + +static const struct file_operations airtime_ops = { + .read = airtime_read, + .open = simple_open, + .llseek = default_llseek, +}; + #ifdef CONFIG_PM static ssize_t reset_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -386,8 +426,12 @@ 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); + if (wiphy_ext_feature_isset(local->hw.wiphy, + NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { + DEBUGFS_ADD_MODE(airtime, 0600); + debugfs_create_u16("airtime_flags", 0600, + phyd, &local->airtime_flags); + } statsd = debugfs_create_dir("statistics", phyd); diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 3aa618d..80028da 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -203,7 +203,7 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf, size_t bufsz = 200; char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; u64 rx_airtime = 0, tx_airtime = 0; - s64 deficit[IEEE80211_NUM_ACS]; + u64 v_t[IEEE80211_NUM_ACS]; ssize_t rv; int ac; @@ -214,20 +214,20 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf, 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; + v_t[ac] = sta->airtime[ac].v_t; 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", + "Virt-T: 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]); + v_t[0], + v_t[1], + v_t[2], + v_t[3]); rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); kfree(buf); @@ -245,7 +245,7 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf, 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; + sta->airtime[ac].v_t = 0; spin_unlock_bh(&local->active_txq_lock[ac]); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e170f98..a4556f9 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -846,8 +846,7 @@ 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; + struct rb_node schedule_order; unsigned long flags; /* keep last! */ @@ -1141,8 +1140,10 @@ struct ieee80211_local { /* 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]; + struct rb_root_cached active_txqs[IEEE80211_NUM_ACS]; + struct rb_node *schedule_pos[IEEE80211_NUM_ACS]; + u64 airtime_v_t[IEEE80211_NUM_ACS]; + u64 airtime_weight_sum[IEEE80211_NUM_ACS]; u16 airtime_flags; @@ -1779,6 +1780,11 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, const u8 *buf, size_t len, const u8 *dest, __be16 proto, bool unencrypted); +void ieee80211_resort_txq(struct ieee80211_hw *hw, + struct ieee80211_txq *txq); +void ieee80211_unschedule_txq(struct ieee80211_hw *hw, + struct ieee80211_txq *txq); + /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, struct ieee80211_sta_ht_cap *ht_cap); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5055aeb..e9ffa8e 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -666,7 +666,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, spin_lock_init(&local->queue_stop_reason_lock); for (i = 0; i < IEEE80211_NUM_ACS; i++) { - INIT_LIST_HEAD(&local->active_txqs[i]); + local->active_txqs[i] = RB_ROOT_CACHED; spin_lock_init(&local->active_txq_lock[i]); } local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 11f0589..9d01fdd 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -389,7 +389,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 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++) @@ -1831,18 +1830,32 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, { struct sta_info *sta = container_of(pubsta, struct sta_info, sta); struct ieee80211_local *local = sta->sdata->local; + struct ieee80211_txq *txq = sta->sta.txq[tid]; u8 ac = ieee80211_ac_from_tid(tid); - u32 airtime = 0; + u64 airtime = 0, weight_sum; + + if (!txq) + return; if (sta->local->airtime_flags & AIRTIME_USE_TX) airtime += tx_airtime; if (sta->local->airtime_flags & AIRTIME_USE_RX) airtime += rx_airtime; + /* Weights scale so the unit weight is 256 */ + airtime <<= 8; + 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; + + weight_sum = local->airtime_weight_sum[ac] ?: sta->airtime_weight; + + local->airtime_v_t[ac] += airtime / weight_sum; + sta->airtime[ac].v_t += airtime / sta->airtime_weight; + ieee80211_resort_txq(&local->hw, txq); + spin_unlock_bh(&local->active_txq_lock[ac]); } EXPORT_SYMBOL(ieee80211_sta_register_airtime); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 71f7e49..5c1cac9 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -130,11 +130,12 @@ enum ieee80211_agg_stop_reason { /* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */ #define AIRTIME_USE_TX BIT(0) #define AIRTIME_USE_RX BIT(1) +#define AIRTIME_GRACE 2000 /* usec of grace period before reset */ struct airtime_info { u64 rx_airtime; u64 tx_airtime; - s64 deficit; + u64 v_t; }; struct sta_info; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 61c7ea9..d00baaa 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1449,7 +1449,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, codel_vars_init(&txqi->def_cvars); codel_stats_init(&txqi->cstats); __skb_queue_head_init(&txqi->frags); - INIT_LIST_HEAD(&txqi->schedule_order); + RB_CLEAR_NODE(&txqi->schedule_order); txqi->txq.vif = &sdata->vif; @@ -1493,9 +1493,7 @@ void ieee80211_txq_purge(struct ieee80211_local *local, 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]); + ieee80211_unschedule_txq(&local->hw, &txqi->txq); } void ieee80211_txq_set_params(struct ieee80211_local *local) @@ -3640,126 +3638,191 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) { struct ieee80211_local *local = hw_to_local(hw); + struct rb_node *node = local->schedule_pos[ac]; struct txq_info *txqi = NULL; + bool first = false; 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) + if (!node) { + node = rb_first_cached(&local->active_txqs[ac]); + first = true; + } else { + node = rb_next(node); + } + + if (!node) return NULL; + txqi = container_of(node, struct txq_info, schedule_order); + 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 (sta->airtime[ac].v_t > local->airtime_v_t[ac]) { + if (first) + local->airtime_v_t[ac] = sta->airtime[ac].v_t; + else + return NULL; } } - if (txqi->schedule_round == local->schedule_round[ac]) - return NULL; - - list_del_init(&txqi->schedule_order); - txqi->schedule_round = local->schedule_round[ac]; + local->schedule_pos[ac] = node; return &txqi->txq; } EXPORT_SYMBOL(ieee80211_next_txq); -void ieee80211_return_txq(struct ieee80211_hw *hw, +static void __ieee80211_insert_txq(struct rb_root_cached *root, + struct txq_info *txqi, u8 ac) +{ + struct rb_node **new = &root->rb_root.rb_node; + struct rb_node *parent = NULL; + struct txq_info *__txqi; + bool leftmost = true; + + while (*new) { + parent = *new; + __txqi = rb_entry(parent, struct txq_info, schedule_order); + + if (!txqi->txq.sta) { + /* new txqi has no sta - insert to the left */ + new = &parent->rb_left; + } else if (!__txqi->txq.sta) { + /* existing txqi has no sta - insert to the right */ + new = &parent->rb_right; + leftmost = false; + } else { + struct sta_info *old_sta = container_of(__txqi->txq.sta, + struct sta_info, + sta); + struct sta_info *new_sta = container_of(txqi->txq.sta, + struct sta_info, + sta); + + if (new_sta->airtime[ac].v_t <= old_sta->airtime[ac].v_t) { + new = &parent->rb_left; + } else { + new = &parent->rb_right; + leftmost = false; + } + } + } + + rb_link_node(&txqi->schedule_order, parent, new); + rb_insert_color_cached(&txqi->schedule_order, root, leftmost); +} + +void ieee80211_schedule_txq(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) + __acquires(txq_lock) __releases(txq_lock) +{ + struct ieee80211_local *local = hw_to_local(hw); + struct txq_info *txqi = to_txq_info(txq); + u8 ac = txq->ac; + + spin_lock_bh(&local->active_txq_lock[ac]); + + if (!RB_EMPTY_NODE(&txqi->schedule_order)) + goto out; + + if (txq->sta) { + struct sta_info *sta = container_of(txq->sta, + struct sta_info, sta); + + local->airtime_weight_sum[ac] += sta->airtime_weight; + if (local->airtime_v_t[ac] > AIRTIME_GRACE) + sta->airtime[ac].v_t = max(local->airtime_v_t[ac] - AIRTIME_GRACE, + sta->airtime[ac].v_t); + } + + __ieee80211_insert_txq(&local->active_txqs[ac], txqi, ac); + + out: + spin_unlock_bh(&local->active_txq_lock[ac]); +} +EXPORT_SYMBOL(ieee80211_schedule_txq); + +void ieee80211_resort_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { struct ieee80211_local *local = hw_to_local(hw); struct txq_info *txqi = to_txq_info(txq); + u8 ac = txq->ac; + + if (!RB_EMPTY_NODE(&txqi->schedule_order)) { + rb_erase_cached(&txqi->schedule_order, + &local->active_txqs[ac]); + RB_CLEAR_NODE(&txqi->schedule_order); + __ieee80211_insert_txq(&local->active_txqs[ac], txqi, ac); + } +} + +static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) +{ + struct ieee80211_local *local = hw_to_local(hw); + struct txq_info *txqi = to_txq_info(txq); + u8 ac = txq->ac; lockdep_assert_held(&local->active_txq_lock[txq->ac]); - if (list_empty(&txqi->schedule_order) && - (!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]); + if (RB_EMPTY_NODE(&txqi->schedule_order)) + return; + + if (txq->sta) { + struct sta_info *sta = container_of(txq->sta, + struct sta_info, sta); + + local->airtime_weight_sum[ac] -= sta->airtime_weight; } + + rb_erase_cached(&txqi->schedule_order, + &local->active_txqs[txq->ac]); + RB_CLEAR_NODE(&txqi->schedule_order); } -EXPORT_SYMBOL(ieee80211_return_txq); -void ieee80211_schedule_txq(struct ieee80211_hw *hw, - struct ieee80211_txq *txq) +void ieee80211_unschedule_txq(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) __acquires(txq_lock) __releases(txq_lock) { struct ieee80211_local *local = hw_to_local(hw); spin_lock_bh(&local->active_txq_lock[txq->ac]); - ieee80211_return_txq(hw, txq); + __ieee80211_unschedule_txq(hw, txq); spin_unlock_bh(&local->active_txq_lock[txq->ac]); } -EXPORT_SYMBOL(ieee80211_schedule_txq); + +void ieee80211_return_txq(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) +{ + struct ieee80211_local *local = hw_to_local(hw); + struct txq_info *txqi = to_txq_info(txq); + + lockdep_assert_held(&local->active_txq_lock[txq->ac]); + + if (!RB_EMPTY_NODE(&txqi->schedule_order) && + (skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets)) + __ieee80211_unschedule_txq(hw, txq); +} +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 txq_info *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]); - } + return true; 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; + return (sta->airtime[ac].v_t <= local->airtime_v_t[ac]); } EXPORT_SYMBOL(ieee80211_txq_may_transmit); @@ -3769,7 +3832,6 @@ void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) struct ieee80211_local *local = hw_to_local(hw); spin_lock_bh(&local->active_txq_lock[ac]); - local->schedule_round[ac]++; } EXPORT_SYMBOL(ieee80211_txq_schedule_start); @@ -3778,6 +3840,7 @@ void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac) { struct ieee80211_local *local = hw_to_local(hw); + local->schedule_pos[ac] = NULL; spin_unlock_bh(&local->active_txq_lock[ac]); } EXPORT_SYMBOL(ieee80211_txq_schedule_end); From patchwork Fri Dec 13 07:19:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yibo Zhao X-Patchwork-Id: 11290055 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A2EBB6C1 for ; Fri, 13 Dec 2019 07:19:27 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8133E22527 for ; Fri, 13 Dec 2019 07:19:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="cs2jToHs"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="AJ6p2hYA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8133E22527 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=lYUDC9qx9DohC4EX7VZ8kUrRJoFMBXCgz495n3KyLfo=; b=cs2jToHsQj6PJnrqxvHZkl4oxJ 1nsvyZacb0JZ7g2jvXcBysIDkqICerONJaxIV2NoH1esCRTKUjVgTey0pXtPvUC8q8WIx4LhHdclf JkgQtcBfN7qLjVD6YH2tt0RfxPH/4TBPlCLpfPQ1S5Drk7TqDJWYZnyXnQSHP/cL/EF6ia0A+mlXE h+zKaXmIVDWBIOS9X3waifz+cvNSod1uKECJFt1o6kS3bc1zGk5axA174DMWpk2zJeqjeZzDu1AFP QyjMMKp/bFthojebXeH1Remg83xW0LPemm/oiz96ot1aFX20DcC7ZeaoprNH0EeptqcorroxaJgJP hu/NP7PA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iffEU-0002fP-8Z; Fri, 13 Dec 2019 07:19:26 +0000 Received: from m228-5.mailgun.net ([159.135.228.5]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iffEP-0002Xj-Lm for ath10k@lists.infradead.org; Fri, 13 Dec 2019 07:19:23 +0000 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1576221561; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=YXtkS+WCDRchtLlhZcdIFPjO82KlbppU6JgdHQbzzmE=; b=AJ6p2hYAhaCVHw+b7ibgS/TStr8ujVmTTtqsrI30Q6tMJObuEH59eCEvValge2Z7wdqI6JBt bTD21ZikTcxsq4rhEubavDEpYWtR5G9xrtH5ptETUye/Gts6cvOF6eMaYRPcexdrLy/KG6Pf I1cd283QRTq1E/fDT22nk4il1vs= X-Mailgun-Sending-Ip: 159.135.228.5 X-Mailgun-Sid: WyJiZDQ3OSIsICJhdGgxMGtAbGlzdHMuaW5mcmFkZWFkLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5df33b77.7f132bbdb0a0-smtp-out-n02; Fri, 13 Dec 2019 07:19:19 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id E3CC7C4479F; Fri, 13 Dec 2019 07:19:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from ybzhao-HP-Z230-SFF-Workstation.ap.qualcomm.com (unknown [180.166.53.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: yiboz) by smtp.codeaurora.org (Postfix) with ESMTPSA id E0E0AC43383; Fri, 13 Dec 2019 07:19:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org E0E0AC43383 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=yiboz@codeaurora.org From: Yibo Zhao To: linux-wireless@vger.kernel.org Subject: [PATCH 2/4] mac80211: fix issue in loop scenario Date: Fri, 13 Dec 2019 15:19:51 +0800 Message-Id: <1576221593-1086-3-git-send-email-yiboz@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1576221593-1086-1-git-send-email-yiboz@codeaurora.org> References: <1576221593-1086-1-git-send-email-yiboz@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191212_231921_833859_02EE0D27 X-CRM114-Status: GOOD ( 13.31 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [159.135.228.5 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Yibo Zhao , ath10k@lists.infradead.org MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org In a loop txqs dequeue scenario, if the first txq in the rbtree gets removed from rbtree immediately in the ieee80211_return_txq(), the loop will break soon in the ieee80211_next_txq() due to schedule_pos not leading to the second txq in the rbtree. Thus update schedule_pos to previous node once the node of schedule_pos is either removed from rbtree or move to other location in rbtree due to airtime update. Signed-off-by: Yibo Zhao --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/tx.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a4556f9..ed85400 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -847,6 +847,7 @@ struct txq_info { struct codel_stats cstats; struct sk_buff_head frags; struct rb_node schedule_order; + u16 schedule_round; unsigned long flags; /* keep last! */ @@ -1144,6 +1145,7 @@ struct ieee80211_local { struct rb_node *schedule_pos[IEEE80211_NUM_ACS]; u64 airtime_v_t[IEEE80211_NUM_ACS]; u64 airtime_weight_sum[IEEE80211_NUM_ACS]; + u16 schedule_round[IEEE80211_NUM_ACS]; u16 airtime_flags; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d00baaa..c1444e7 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3644,6 +3644,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) lockdep_assert_held(&local->active_txq_lock[ac]); +begin: if (!node) { node = rb_first_cached(&local->active_txqs[ac]); first = true; @@ -3668,7 +3669,10 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) } } + if (txqi->schedule_round == local->schedule_round[ac]) + goto begin; + txqi->schedule_round = local->schedule_round[ac]; local->schedule_pos[ac] = node; return &txqi->txq; } @@ -3752,6 +3756,9 @@ void ieee80211_resort_txq(struct ieee80211_hw *hw, u8 ac = txq->ac; if (!RB_EMPTY_NODE(&txqi->schedule_order)) { + if (local->schedule_pos[ac] == &txqi->schedule_order) + local->schedule_pos[ac] = rb_prev(&txqi->schedule_order); + rb_erase_cached(&txqi->schedule_order, &local->active_txqs[ac]); RB_CLEAR_NODE(&txqi->schedule_order); @@ -3771,6 +3778,9 @@ static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw, if (RB_EMPTY_NODE(&txqi->schedule_order)) return; + if (local->schedule_pos[ac] == &txqi->schedule_order) + local->schedule_pos[ac] = rb_prev(&txqi->schedule_order); + if (txq->sta) { struct sta_info *sta = container_of(txq->sta, struct sta_info, sta); @@ -3803,7 +3813,7 @@ void ieee80211_return_txq(struct ieee80211_hw *hw, lockdep_assert_held(&local->active_txq_lock[txq->ac]); if (!RB_EMPTY_NODE(&txqi->schedule_order) && - (skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets)) + !txq_has_queue(&txqi->txq)) __ieee80211_unschedule_txq(hw, txq); } EXPORT_SYMBOL(ieee80211_return_txq); @@ -3832,6 +3842,8 @@ void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) struct ieee80211_local *local = hw_to_local(hw); spin_lock_bh(&local->active_txq_lock[ac]); + local->schedule_round[ac]++; + } EXPORT_SYMBOL(ieee80211_txq_schedule_start); From patchwork Fri Dec 13 07:19:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yibo Zhao X-Patchwork-Id: 11290057 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6BFC26C1 for ; Fri, 13 Dec 2019 07:19:36 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 38BF822527 for ; Fri, 13 Dec 2019 07:19:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="jLYw02J9"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="bLs5rODN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 38BF822527 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=BNtG3Jl+Zv4FJjXMeWo9tcNyTEVUoCy/LoqMCXfWCBU=; b=jLYw02J9z8Xy3za4GLWeJHR9E+ XRFVs61odLVk0JKAwHKktQWzfBE73YyUv9JRvF1PyIjPcxLkPCXNpdOb1NdHQu5+ZTqDXPc2xLDX+ qzBuBhDp5UhN4pAsLMcX/mZcUk9m36k+B9UwgoCqOVnyeymqwRAAbvG0sEmOjkHDcQmws9tcvLHti 7oRfugVwPGkDKd5Dbs5k8xTkp94qOJwYxKcbL/sOq1+Fwty11JbQDcxJ6T9M7hiKVuE+lMuEuQvFt UFnzd1xcC00n6wx9v8LvNqtNyJln8f4uS845pMlD/LHZl/Jv1y0EXL9U90ZyllGQK/TG0HMjWtNo8 YOOoI6CA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iffEd-0002nZ-Fg; Fri, 13 Dec 2019 07:19:35 +0000 Received: from m228-4.mailgun.net ([159.135.228.4]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iffER-0002YL-6c for ath10k@lists.infradead.org; Fri, 13 Dec 2019 07:19:24 +0000 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1576221563; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=XNpN3pNlMo4tSut6/1EubIcb6843QC7lvbIt+YGPNIQ=; b=bLs5rODNLj88br4FJ2tiEAvVS8zUIAi2UFO7m4qUa0Lp9F07+3Cge9ZIAdBOQB5N+9JoE3Zy cd0eQqd3D5TM1LF8iFmeMb1/J6EII4SN1WpzVItfF2zFSToeEVscedkLr4gYg8TC5d3JEP+3 xogB4pDXUg0ojBoJViaAeyAoNT8= X-Mailgun-Sending-Ip: 159.135.228.4 X-Mailgun-Sid: WyJiZDQ3OSIsICJhdGgxMGtAbGlzdHMuaW5mcmFkZWFkLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5df33b7a.7f5a99eec688-smtp-out-n02; Fri, 13 Dec 2019 07:19:22 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 298D4C433A2; Fri, 13 Dec 2019 07:19:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from ybzhao-HP-Z230-SFF-Workstation.ap.qualcomm.com (unknown [180.166.53.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: yiboz) by smtp.codeaurora.org (Postfix) with ESMTPSA id E3A9AC43383; Fri, 13 Dec 2019 07:19:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org E3A9AC43383 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=yiboz@codeaurora.org From: Yibo Zhao To: linux-wireless@vger.kernel.org Subject: [PATCH 3/4] mac80211: fix low throughput in multi-clients situation Date: Fri, 13 Dec 2019 15:19:52 +0800 Message-Id: <1576221593-1086-4-git-send-email-yiboz@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1576221593-1086-1-git-send-email-yiboz@codeaurora.org> References: <1576221593-1086-1-git-send-email-yiboz@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191212_231923_355890_BFF93142 X-CRM114-Status: GOOD ( 13.69 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [159.135.228.4 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Yibo Zhao , ath10k@lists.infradead.org MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org Not long after the start of multi-clients test, not a single station is an eligible candidate for transmission since global virtual time(g_vt) is smaller than the virtual airtime(s_vt) of all the stations. As a result, the Tx has been blocked and throughput is quite low. This may mainly due accumulative deviation from the devision calculation of g_vt. For example: Suppose we have 50 clients in first round. Round 1: STA weight Tx_time_round wt_sum s_vt g_vt valid_for_next_Tx 1 256 2048 12800 2048 2000 N 2 256 2048 2048 N . . . . . . . . . . . . . . . 50 256 2048 2048 N After this round, all the stations are not valid for next transmission due to accumulative deviation. The real situation can be more complicate, above is one of the extremely case. To avoid this situation to occur, the new proposal is: - If global virtual time is less than the virtual airtime of any station, sync it to the airtime of first station in the red-black tree - Round the division result Signed-off-by: Yibo Zhao --- net/mac80211/sta_info.c | 3 ++- net/mac80211/tx.c | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 9d01fdd..feac975 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1852,7 +1852,8 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, weight_sum = local->airtime_weight_sum[ac] ?: sta->airtime_weight; - local->airtime_v_t[ac] += airtime / weight_sum; + /* Round the calculation of global vt */ + local->airtime_v_t[ac] += (airtime + (weight_sum >> 1)) / weight_sum; sta->airtime[ac].v_t += airtime / sta->airtime_weight; ieee80211_resort_txq(&local->hw, txq); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c1444e7..b40cf91 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3822,15 +3822,29 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { struct ieee80211_local *local = hw_to_local(hw); - struct txq_info *txqi = to_txq_info(txq); + struct txq_info *first_txqi, *txqi = to_txq_info(txq); + struct rb_node *node = NULL; struct sta_info *sta; u8 ac = txq->ac; + first_txqi = NULL; lockdep_assert_held(&local->active_txq_lock[ac]); if (!txqi->txq.sta) return true; + node = rb_first_cached(&local->active_txqs[ac]); + if (node) { + first_txqi = container_of(node, struct txq_info, + schedule_order); + if (first_txqi->txq.sta) { + sta = container_of(first_txqi->txq.sta, + struct sta_info, sta); + if (local->airtime_v_t[ac] < sta->airtime[ac].v_t) + local->airtime_v_t[ac] = sta->airtime[ac].v_t; + } + } + sta = container_of(txqi->txq.sta, struct sta_info, sta); return (sta->airtime[ac].v_t <= local->airtime_v_t[ac]); } From patchwork Fri Dec 13 07:19:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yibo Zhao X-Patchwork-Id: 11290059 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1A7EF6C1 for ; Fri, 13 Dec 2019 07:19:39 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EB6ED22527 for ; Fri, 13 Dec 2019 07:19:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="hXQSnels"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="IJU6fWVs" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EB6ED22527 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=7r4tZT56F96drZENOM5qLja8mNYqBaddBbTlS82V/LI=; b=hXQSnels81ah4W6IvQ1O8fTqYO guE1THA5MqYQTBq0kzgQ2GDvuzlvfXhs4i/NmAUq6uZg6ambAa3Kltdv5KfG9NlCT5Ou+IQ/hcoY3 rjRDIOxjkmroglvri/z7a0x69AvK5zZKCa9ui0EKBcVlosf9JaiyQPOCVhD16Te4ulrB8ftgnJiO1 1chqvaII7W8dhzKVqxs+YOtPInwzFNP81ltt7qPH+XH/IIyeUr7Hs4Uyp5EI4xwRe4bus+j3S+mjc 6mUzucfKL4IvS8+YyJHrix17YBlJP4NQauhU7+TFsccj1Eniop/jA7F3NR1ggIkPgweSMtD1bIHOd moBktEgw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iffEg-0002r6-Aq; Fri, 13 Dec 2019 07:19:38 +0000 Received: from m228-4.mailgun.net ([159.135.228.4]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iffEU-0002YL-C1 for ath10k@lists.infradead.org; Fri, 13 Dec 2019 07:19:28 +0000 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1576221566; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=Qki3lzI156RHYM9ySW7PBoactPkFcQqknjTYDK3F5wQ=; b=IJU6fWVsYNJCyIbbh7XN8OWnwXgR2C7SVrBToFMkNjt0QT5ci0VGolcIA2YQWsdVTzzzrdw/ Y0khh6NjuLzaDWvNZC+89BV9KeMf8OAvnHbBNJQH1Tj/xcUU6LVJnIjMO8KXzTMT2H73H4nZ WSdPLqzB0XY+9MDvXYrvDPsXnF0= X-Mailgun-Sending-Ip: 159.135.228.4 X-Mailgun-Sid: WyJiZDQ3OSIsICJhdGgxMGtAbGlzdHMuaW5mcmFkZWFkLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5df33b7d.7f4e16fe7730-smtp-out-n03; Fri, 13 Dec 2019 07:19:25 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id A44D6C447A2; Fri, 13 Dec 2019 07:19:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from ybzhao-HP-Z230-SFF-Workstation.ap.qualcomm.com (unknown [180.166.53.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: yiboz) by smtp.codeaurora.org (Postfix) with ESMTPSA id 118F9C447A0; Fri, 13 Dec 2019 07:19:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 118F9C447A0 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=yiboz@codeaurora.org From: Yibo Zhao To: linux-wireless@vger.kernel.org Subject: [PATCH 4/4] mac80211: Sync airtime weight sum with per AC synced sta airtime weight together Date: Fri, 13 Dec 2019 15:19:53 +0800 Message-Id: <1576221593-1086-5-git-send-email-yiboz@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1576221593-1086-1-git-send-email-yiboz@codeaurora.org> References: <1576221593-1086-1-git-send-email-yiboz@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191212_231926_486590_02CBE0E6 X-CRM114-Status: GOOD ( 16.70 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [159.135.228.4 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Yibo Zhao , ath10k@lists.infradead.org MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org Global airtime weight sum is updated only when txq is added/removed from rbtree. If upper layer configures sta weight during high load, airtime weight sum will not be updated since txq is most likely on the tree. It could a little late for upper layer to reconfigure sta weight when txq is already in the rbtree. And thus, incorrect airtime weight sum will lead to incorrect global virtual time calculation as well as overflow of airtime weight sum during txq removed. Hence, need to update airtime weight sum upon receiving event for configuring sta weight once sta's txq is on the rbtree. Besides, if airtime weight sum of ACs and sta weight is synced under the same per AC lock protection, there can be a very short window causing incorrct airtime weight sum calculation as below: active_txq_lock_VO . VO weight sum is syncd . sta airtime weight sum is synced . active_txq_unlock_VO . . . active_txq_lock_VI . VI weight sum is syncd . sta airtime weight sum active_txq_lock_BE active_txq_unlock_VI Remove txq and thus sum . is calculated with synced . sta airtime weight . active_txq_unlock_BE So introduce a per ac synced station airtime weight synced with per AC synced weight sum together. And the per-AC station airtime weight is used to calculate weight sum. Signed-off-by: Yibo Zhao --- net/mac80211/cfg.c | 29 ++++++++++++++++++++++++++--- net/mac80211/debugfs_sta.c | 2 +- net/mac80211/sta_info.c | 9 ++++----- net/mac80211/sta_info.h | 5 +++-- net/mac80211/tx.c | 4 ++-- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d65aa01..298b61d 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1284,7 +1284,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, int ret = 0; struct ieee80211_supported_band *sband; struct ieee80211_sub_if_data *sdata = sta->sdata; - u32 mask, set; + u32 mask, set, tid, ac, pre_weight; + struct txq_info *txqi; sband = ieee80211_get_sband(sdata); if (!sband) @@ -1452,8 +1453,30 @@ 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; + if (params->airtime_weight) { + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + spin_lock_bh(&local->active_txq_lock[ac]); + for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) { + if (params->airtime_weight == sta->airtime_weight[ac] || + !sta->sta.txq[tid] || + ac != ieee80211_ac_from_tid(tid)) + continue; + + pre_weight = sta->airtime_weight[ac]; + sta->airtime_weight[ac] = + params->airtime_weight; + + txqi = to_txq_info(sta->sta.txq[tid]); + if (RB_EMPTY_NODE(&txqi->schedule_order)) + continue; + + local->airtime_weight_sum[ac] = local->airtime_weight_sum[ac] + + params->airtime_weight - + pre_weight; + } + spin_unlock_bh(&local->active_txq_lock[ac]); + } + } /* set the STA state after all sta info from usermode has been set */ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) || diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 80028da..43a7e6a 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -223,7 +223,7 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf, "Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", rx_airtime, tx_airtime, - sta->airtime_weight, + sta->airtime_weight[0], v_t[0], v_t[1], v_t[2], diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index feac975..e599cf1 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -384,11 +384,10 @@ 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_weight[i] = IEEE80211_DEFAULT_AIRTIME_WEIGHT; } for (i = 0; i < IEEE80211_NUM_TIDS; i++) @@ -1850,11 +1849,11 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, sta->airtime[ac].tx_airtime += tx_airtime; sta->airtime[ac].rx_airtime += rx_airtime; - weight_sum = local->airtime_weight_sum[ac] ?: sta->airtime_weight; + weight_sum = local->airtime_weight_sum[ac] ?: sta->airtime_weight[ac]; /* Round the calculation of global vt */ local->airtime_v_t[ac] += (airtime + (weight_sum >> 1)) / weight_sum; - sta->airtime[ac].v_t += airtime / sta->airtime_weight; + sta->airtime[ac].v_t += airtime / sta->airtime_weight[ac]; ieee80211_resort_txq(&local->hw, txq); spin_unlock_bh(&local->active_txq_lock[ac]); @@ -2236,7 +2235,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, } if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { - sinfo->airtime_weight = sta->airtime_weight; + sinfo->airtime_weight = sta->airtime_weight[0]; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); } diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 5c1cac9..6e831ef 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -476,7 +476,8 @@ struct ieee80211_sta_rx_stats { * @tid_seq: per-TID sequence numbers for sending to this STA * @airtime: per-AC struct airtime_info describing airtime statistics for this * station - * @airtime_weight: station weight for airtime fairness calculation purposes + * @airtime_weight: station per-AC weight for airtime fairness calculation + * purposes * @ampdu_mlme: A-MPDU state machine state * @mesh: mesh STA information * @debugfs_dir: debug filesystem directory dentry @@ -602,7 +603,7 @@ struct sta_info { u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; struct airtime_info airtime[IEEE80211_NUM_ACS]; - u16 airtime_weight; + u16 airtime_weight[IEEE80211_NUM_ACS]; /* * Aggregation information, locked with lock. diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index b40cf91..56dba27 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3735,7 +3735,7 @@ void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct sta_info *sta = container_of(txq->sta, struct sta_info, sta); - local->airtime_weight_sum[ac] += sta->airtime_weight; + local->airtime_weight_sum[ac] += sta->airtime_weight[ac]; if (local->airtime_v_t[ac] > AIRTIME_GRACE) sta->airtime[ac].v_t = max(local->airtime_v_t[ac] - AIRTIME_GRACE, sta->airtime[ac].v_t); @@ -3785,7 +3785,7 @@ static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw, struct sta_info *sta = container_of(txq->sta, struct sta_info, sta); - local->airtime_weight_sum[ac] -= sta->airtime_weight; + local->airtime_weight_sum[ac] -= sta->airtime_weight[ac]; } rb_erase_cached(&txqi->schedule_order,