If station is ineligible for transmission in ieee80211_txq_may_transmit(),
no packet will be delivered to FW. During the tests in push-pull mode with
many clients, after several seconds, not a single station is an eligible
candidate for transmission since global time is smaller than all the
station's virtual airtime. As a consequence, the Tx has been blocked and
throughput is quite low.

To avoid this situation to occur in push-pull mode, the new proposal is:

- Increase the airtime grace period a little more to reduce the
  unexpected sync

- 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 since the process of global virtual time
  involves the division calculation

Co-developed-by: Yibo Zhao <yi...@codeaurora.org>
Signed-off-by: Yibo Zhao <yi...@codeaurora.org>
Signed-off-by: Toke Høiland-Jørgensen <t...@toke.dk>
---
 net/mac80211/sta_info.c |  3 ++-
 net/mac80211/sta_info.h |  2 +-
 net/mac80211/tx.c       | 16 +++++++++++++++-
 3 files changed, 18 insertions(+), 3 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/sta_info.h b/net/mac80211/sta_info.h
index 5c1cac9..5055f94 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -130,7 +130,7 @@ 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 500 /* usec of grace period before reset */
+#define AIRTIME_GRACE 2000 /* usec of grace period before reset */
 
 struct airtime_info {
        u64 rx_airtime;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 42ca010..60cf569 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3867,15 +3867,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]);
 }
-- 
1.9.1


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

Reply via email to