From: "Toke Høiland-Jørgensen" <toke@toke.dk>
To: Johannes Berg <johannes@sipsolutions.net>,
linux-wireless@vger.kernel.org
Cc: Johannes Berg <johannes.berg@intel.com>
Subject: Re: [PATCH 13/30] wifi: mac80211: don't apply CoDel to PS-buffered frames
Date: Fri, 06 Nov 2026 13:22:42 +0100 [thread overview]
Message-ID: <87cxsip2st.fsf@toke.dk> (raw)
In-Reply-To: <20261102203831.1058362-45-johannes@sipsolutions.net>
Johannes Berg <johannes@sipsolutions.net> writes:
> From: Johannes Berg <johannes.berg@intel.com>
>
> Frames for sleeping stations remain on the TXQs now, applying
> CoDel to them would start dropping them due to a long wait on
> dequeue, but for PS STAs they will be on the queues for a while.
> Bypass CoDel while a STA is sleeping and for a while (10s) or
> when the queue drains after it wakes up, and for frames that
> were enqueued after the wakeup as well, which really is the
> common case.
>
> Assisted-by: LLM
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
> net/mac80211/ieee80211_i.h | 7 +++++
> net/mac80211/sta_info.c | 6 ++++-
> net/mac80211/tx.c | 52 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 64 insertions(+), 1 deletion(-)
>
> diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
> index 5045144641a4..cb947341fee6 100644
> --- a/net/mac80211/ieee80211_i.h
> +++ b/net/mac80211/ieee80211_i.h
> @@ -978,6 +978,7 @@ enum txq_info_flags {
> IEEE80211_TXQ_AMPDU,
> IEEE80211_TXQ_NO_AMSDU,
> IEEE80211_TXQ_DIRTY,
> + IEEE80211_TXQ_PS_BACKLOG,
> };
>
> /**
> @@ -990,6 +991,9 @@ enum txq_info_flags {
> * @schedule_order: used with ieee80211_local->active_txqs
> * @schedule_round: counter to prevent infinite loops on TXQ scheduling
> * @flags: TXQ flags from &enum txq_info_flags
> + * @ps_backlog_end: with %IEEE80211_TXQ_PS_BACKLOG, indicates when
> + * the station woke up, i.e. frames before this were just queued
> + * due to powersave
> * @txq: the driver visible part
> */
> struct txq_info {
> @@ -1003,6 +1007,7 @@ struct txq_info {
> struct sk_buff_head frags;
>
> unsigned long flags;
> + codel_time_t ps_backlog_end;
>
> /* keep last! */
> struct ieee80211_txq txq;
> @@ -2724,6 +2729,8 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
> struct txq_info *txq, int tid);
> struct sk_buff *ieee80211_tx_dequeue_ps_release(struct ieee80211_local *local,
> struct txq_info *txqi);
> +void ieee80211_txq_ps_backlog_start(struct ieee80211_local *local,
> + struct txq_info *txqi);
The variable above is called ps_backlog_end, the function is called
ps_backlog_start. Seems a tad confusing? :)
> void ieee80211_txq_purge(struct ieee80211_local *local,
> struct txq_info *txqi);
> void ieee80211_purge_sta_txqs(struct sta_info *sta);
> diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
> index 51504f57128f..8d79e532b109 100644
> --- a/net/mac80211/sta_info.c
> +++ b/net/mac80211/sta_info.c
> @@ -1889,10 +1889,14 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
> /* this can be called in process context, e.g. for mesh */
> local_bh_disable();
> for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
> + struct txq_info *txqi;
> +
> if (!sta->sta.txq[i] || !txq_has_queue(sta->sta.txq[i]))
> continue;
>
> - schedule_and_wake_txq(local, to_txq_info(sta->sta.txq[i]));
> + txqi = to_txq_info(sta->sta.txq[i]);
> + ieee80211_txq_ps_backlog_start(local, txqi);
> + schedule_and_wake_txq(local, txqi);
> }
> local_bh_enable();
>
> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> index 0bd324a4d4cb..856018cdb617 100644
> --- a/net/mac80211/tx.c
> +++ b/net/mac80211/tx.c
> @@ -1380,6 +1380,55 @@ static void codel_drop_func(struct sk_buff *skb,
> ieee80211_free_txskb(hw, skb);
> }
>
> +/* bypass codel since PS can last a long time */
> +static bool ieee80211_txq_codel_bypass(struct txq_info *txqi,
> + const struct fq_flow *flow)
> +{
> + struct sta_info *sta;
> + struct sk_buff *skb;
> +
> + if (!txqi->txq.sta)
> + return false;
> +
> + sta = container_of(txqi->txq.sta, struct sta_info, sta);
> + if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
> + test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
> + test_sta_flag(sta, WLAN_STA_PS_DELIVER))
> + return true;
> +
> + if (likely(!test_bit(IEEE80211_TXQ_PS_BACKLOG, &txqi->flags)))
> + return false;
> +
> + /*
> + * Stop treating as backlog after it cleared or after 1s
> + * (the latter to avoid time wrap and issues from that).
> + */
> +#define IEEE80211_TXQ_MAX_PS_BACKLOG MS2TIME(MSEC_PER_SEC)
> +
> + if (!txqi->tin.backlog_packets ||
> + codel_time_after(codel_get_time(),
> + (codel_time_t)(txqi->ps_backlog_end +
> + IEEE80211_TXQ_MAX_PS_BACKLOG))) {
> + clear_bit(IEEE80211_TXQ_PS_BACKLOG, &txqi->flags);
> + return false;
> + }
> +
> + skb = skb_peek(&flow->queue);
> + return skb && codel_time_before(codel_skb_time_func(skb),
> + txqi->ps_backlog_end);
> +}
> +
> +void ieee80211_txq_ps_backlog_start(struct ieee80211_local *local,
> + struct txq_info *txqi)
> +{
> + spin_lock_bh(&local->fq.lock);
> + if (txqi->tin.backlog_packets) {
> + txqi->ps_backlog_end = codel_get_time();
> + set_bit(IEEE80211_TXQ_PS_BACKLOG, &txqi->flags);
We should probably clear the codel variables here as well? Otherwise, if
CoDel was already in a dropping state when this happens, that can carry
over to after the bypass ends.
-Toke
next prev parent reply other threads:[~2026-11-06 12:22 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 20:22 [PATCH 00/30] wifi: mac80211: unify frame queueing Johannes Berg
2026-11-02 20:22 ` [PATCH 01/30] wifi: mac80211: mesh: clear PS_STA flag when peer wakes up Johannes Berg
2026-11-02 20:22 ` [PATCH 02/30] wifi: mac80211: disable BHs when waking TXQs on PS wakeup Johannes Berg
2026-11-02 20:22 ` [PATCH 03/30] wifi: mt76: correctly set more-data flag on PS release Johannes Berg
2026-11-02 20:22 ` [PATCH 04/30] wifi: mac80211: remove dead aggregation TX code Johannes Berg
2026-11-02 20:22 ` [PATCH 05/30] wifi: mac80211: remove tid_tx->pending Johannes Berg
2026-11-02 20:22 ` [PATCH 06/30] wifi: mac80211: remove aggregation queue stop reason Johannes Berg
2026-11-02 20:22 ` [PATCH 07/30] wifi: mac80211: rename vif->txq_mgmt to vif->txq_nan_dw Johannes Berg
2026-11-02 20:22 ` [PATCH 08/30] wifi: mac80211: use vlan-aware station lookup for pending TX Johannes Berg
2026-11-02 20:22 ` [PATCH 09/30] wifi: mac80211: stop tracking TXQ-buffered TIDs for PS STAs Johannes Berg
2026-11-02 20:23 ` [PATCH 10/30] wifi: mac80211: release frames from TXQs to PS stations Johannes Berg
2026-11-02 20:23 ` [PATCH 11/30] wifi: mac80211: mesh: release frames from TXQs sleeping peers Johannes Berg
2026-11-02 20:23 ` [PATCH 12/30] wifi: mac80211: don't TX from TXQs of sleeping STAs Johannes Berg
2026-11-02 20:23 ` [PATCH 13/30] wifi: mac80211: don't apply CoDel to PS-buffered frames Johannes Berg
2026-11-06 12:22 ` Toke Høiland-Jørgensen [this message]
2026-11-02 20:23 ` [PATCH 14/30] wifi: mac80211: put filtered data frames back on TXQs Johannes Berg
2026-11-06 12:23 ` Toke Høiland-Jørgensen
2026-11-02 20:23 ` [PATCH 15/30] wifi: mac80211: handle the mgmt TXQ of sleeping STAs Johannes Berg
2026-11-02 20:23 ` [PATCH 16/30] wifi: mac80211: hold frames for sleeping STAs on TXQs Johannes Berg
2026-11-02 20:23 ` [PATCH 17/30] wifi: mac80211: move ieee80211_txq_enqueue() up Johannes Berg
2026-11-02 20:23 ` [PATCH 18/30] wifi: mac80211: always use per-STA MMPDU TXQ Johannes Berg
2026-11-02 20:23 ` [PATCH 19/30] wifi: mac80211: use MMPDU TXQ for filtered mgmt frames Johannes Berg
2026-11-02 20:23 ` [PATCH 20/30] wifi: mac80211: avoid reordering PS-release MMPDUs Johannes Berg
2026-11-02 20:23 ` [PATCH 21/30] wifi: mac80211: buffer multicast frames on vif TXQ Johannes Berg
2026-11-02 20:23 ` [PATCH 22/30] wifi: mac80211: always use TXQ for mcast data frames Johannes Berg
2026-11-02 20:23 ` [PATCH 23/30] wifi: mac80211: refactor fast-xmit header encapsulation Johannes Berg
2026-11-02 20:23 ` [PATCH 24/30] wifi: mac80211: encapsulate fast-xmit frames at TXQ dequeue Johannes Berg
2026-11-02 20:23 ` [PATCH 25/30] net/fq_impl: allow pulling packets from the same flow Johannes Berg
2026-11-02 20:23 ` [PATCH 26/30] wifi: mac80211: build A-MSDUs at dequeue Johannes Berg
2026-11-02 20:23 ` [PATCH 27/30] wifi: mac80211: handle 802.11 encap at TXQ dequeue Johannes Berg
2026-11-02 20:23 ` [PATCH 28/30] wifi: mac80211: split some TX code into helpers Johannes Berg
2026-11-02 20:23 ` [PATCH 29/30] wifi: mac80211: queue unicast data frames as ethernet Johannes Berg
2026-11-02 20:23 ` [PATCH 30/30] wifi: mac80211: keep fast-xmit for sleeping STAs Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87cxsip2st.fsf@toke.dk \
--to=toke@toke.dk \
--cc=johannes.berg@intel.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox