From: Johannes Berg <johannes@sipsolutions.net>
To: linux-wireless@vger.kernel.org
Subject: [RFC 3/3] mac80211: also expire filtered frames
Date: Tue, 06 Sep 2011 14:14:24 +0200 [thread overview]
Message-ID: <20110906121534.774908599@sipsolutions.net> (raw)
In-Reply-To: 20110906121421.460641040@sipsolutions.net
From: Johannes Berg <johannes.berg@intel.com>
mac80211 will expire normal PS-buffered frames, but
if the device rejected some frames for a sleeping
station, these won't be on the ps_tx_buf queue but
on the tx_filtered queue instead; this is done to
avoid reordering.
However, mac80211 will not expire frames from the
filtered queue, let's fix that.
Also add a more comments to what all this expiry is
doing and how it works.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/sta_info.c | 57 +++++++++++++++++++++++++++++++++++++++++++-----
net/mac80211/status.c | 5 ++++
2 files changed, 57 insertions(+), 5 deletions(-)
--- a/net/mac80211/sta_info.c 2011-09-06 13:19:20.000000000 +0200
+++ b/net/mac80211/sta_info.c 2011-09-06 13:57:30.000000000 +0200
@@ -698,6 +698,39 @@ static bool sta_info_cleanup_expire_buff
unsigned long flags;
struct sk_buff *skb;
+ /*
+ * First check for frames that should expire on the filtered
+ * queue. Frames here were rejected by the driver and are on
+ * a separate queue to avoid reordering with normal PS-buffered
+ * frames. They also aren't accounted for right now in the
+ * total_ps_buffered counter.
+ */
+ for (;;) {
+ spin_lock_irqsave(&sta->tx_filtered.lock, flags);
+ skb = skb_peek(&sta->tx_filtered);
+ if (sta_info_buffer_expired(sta, skb))
+ skb = __skb_dequeue(&sta->tx_filtered);
+ else
+ skb = NULL;
+ spin_unlock_irqrestore(&sta->tx_filtered.lock, flags);
+
+ /*
+ * Frames are queued in order, so if this one
+ * hasn't expired yet we can stop testing. If
+ * we actually reached the end of the queue we
+ * also need to stop, of course.
+ */
+ if (!skb)
+ break;
+ dev_kfree_skb(skb);
+ }
+
+ /*
+ * Now also check the normal PS-buffered queue, this will
+ * only find something if the filtered queue was emptied
+ * since the filtered frames are all before the normal PS
+ * buffered frames.
+ */
for (;;) {
spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
skb = skb_peek(&sta->ps_tx_buf);
@@ -707,6 +740,11 @@ static bool sta_info_cleanup_expire_buff
skb = NULL;
spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags);
+ /*
+ * frames are queued in order, so if this one
+ * hasn't expired yet (or we reached the end of
+ * the queue) we can stop testing
+ */
if (!skb)
break;
@@ -716,13 +754,22 @@ static bool sta_info_cleanup_expire_buff
sta->sta.addr);
#endif
dev_kfree_skb(skb);
-
- /* if the queue is now empty recalc TIM bit */
- if (skb_queue_empty(&sta->ps_tx_buf))
- sta_info_recalc_tim(sta);
}
- return !skb_queue_empty(&sta->ps_tx_buf);
+ /*
+ * Finally, recalculate the TIM bit for this station -- it might
+ * now be clear because the station was too slow to retrieve its
+ * frames.
+ */
+ sta_info_recalc_tim(sta);
+
+ /*
+ * Return whether there are any frames still buffered, this is
+ * used to check whether the cleanup timer still needs to run,
+ * if there are no frames we don't need to rearm the timer.
+ */
+ return !(skb_queue_empty(&sta->ps_tx_buf) &&
+ skb_queue_empty(&sta->tx_filtered));
}
static int __must_check __sta_info_destroy(struct sta_info *sta)
--- a/net/mac80211/status.c 2011-09-06 13:24:28.000000000 +0200
+++ b/net/mac80211/status.c 2011-09-06 13:29:24.000000000 +0200
@@ -107,6 +107,11 @@ static void ieee80211_handle_filtered_fr
skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
skb_queue_tail(&sta->tx_filtered, skb);
sta_info_recalc_tim(sta);
+
+ if (!timer_pending(&local->sta_cleanup))
+ mod_timer(&local->sta_cleanup,
+ round_jiffies(jiffies +
+ STA_INFO_CLEANUP_INTERVAL));
return;
}
prev parent reply other threads:[~2011-09-06 12:16 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-06 12:14 [RFC 0/3] some AP PS buffering rework Johannes Berg
2011-09-06 12:14 ` [RFC 1/3] mac80211: let drivers inform it about per TID buffered frames Johannes Berg
2011-09-06 12:14 ` [RFC 2/3] mac80211: unify TIM bit handling Johannes Berg
2011-09-06 12:26 ` Johannes Berg
2011-09-06 12:14 ` Johannes Berg [this message]
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=20110906121534.774908599@sipsolutions.net \
--to=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;
as well as URLs for NNTP newsgroup(s).