* [PATCH 1/3] mac80211: Fix incorrect num_sta_ps decrement in __sta_info_destroy
@ 2012-01-27 10:02 Helmut Schaa
2012-01-27 10:02 ` [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end Helmut Schaa
0 siblings, 1 reply; 5+ messages in thread
From: Helmut Schaa @ 2012-01-27 10:02 UTC (permalink / raw)
To: linux-wireless; +Cc: linville, johannes, Helmut Schaa
When WLAN_STA_PS_DRIVER is set by ieee80211_sta_block_awake the
num_sta_ps counter is not incremented. Hence, we shouldn't decrement
it in __sta_info_destroy if only WLAN_STA_PS_DRIVER is set. This
could result in an incorrect num_sta_ps counter leading to strange side
effects with associated powersaving clients.
Fix this by only decrementing num_sta_ps when WLAN_STA_PS_STA was set
before.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
---
net/mac80211/sta_info.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 5b4ab21..70a0de3 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -750,12 +750,10 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
sta->dead = true;
- if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
- test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
+ if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
BUG_ON(!sdata->bss);
clear_sta_flag(sta, WLAN_STA_PS_STA);
- clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
atomic_dec(&sdata->bss->num_sta_ps);
sta_info_recalc_tim(sta);
--
1.7.7
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end
2012-01-27 10:02 [PATCH 1/3] mac80211: Fix incorrect num_sta_ps decrement in __sta_info_destroy Helmut Schaa
@ 2012-01-27 10:02 ` Helmut Schaa
2012-01-27 10:02 ` [PATCH 3/3] mac80211: Move num_sta_ps counter decrement after synchronize_rcu Helmut Schaa
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Helmut Schaa @ 2012-01-27 10:02 UTC (permalink / raw)
To: linux-wireless; +Cc: linville, johannes, Helmut Schaa
If the driver blocked this specific STA with the help of
ieee80211_sta_block_awake we won't clear WLAN_STA_PS_STA later but
still decrement num_sta_ps. Hence, the next data frame from this
STA will trigger ap_sta_ps_end again and also decrement num_sta_ps
again leading to an incorrect num_sta_ps counter.
This can result in problems with powersaving clients not waking up
from PS because the TIM calculation might be skipped due to the
incorrect num_sta_ps counter.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
---
net/mac80211/rx.c | 1 -
net/mac80211/sta_info.c | 4 +++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3567586..f89617a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1147,7 +1147,6 @@ static void ap_sta_ps_end(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
- atomic_dec(&sdata->bss->num_sta_ps);
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 70a0de3..92b894c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1007,9 +1007,11 @@ EXPORT_SYMBOL(ieee80211_find_sta);
static void clear_sta_ps_flags(void *_sta)
{
struct sta_info *sta = _sta;
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- clear_sta_flag(sta, WLAN_STA_PS_STA);
+ if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
+ atomic_dec(&sdata->bss->num_sta_ps);
}
/* powersave support code */
--
1.7.7
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] mac80211: Move num_sta_ps counter decrement after synchronize_rcu
2012-01-27 10:02 ` [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end Helmut Schaa
@ 2012-01-27 10:02 ` Helmut Schaa
2012-01-30 11:07 ` [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end Helmut Schaa
2012-01-30 14:18 ` [PATCHv2 " Helmut Schaa
2 siblings, 0 replies; 5+ messages in thread
From: Helmut Schaa @ 2012-01-27 10:02 UTC (permalink / raw)
To: linux-wireless; +Cc: linville, johannes, Helmut Schaa
Unted the assumption that the sta struct is still accessible before the
synchronize_rcu call we should move the num_sta_ps counter decrement
after synchronize_rcu to avoid incorrect decrements if num_sta_ps.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
---
Not sure if this really triggers in reality but it looks a bit more correct to me.
net/mac80211/sta_info.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 92b894c..3af737c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -750,15 +750,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
sta->dead = true;
- if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
- BUG_ON(!sdata->bss);
-
- clear_sta_flag(sta, WLAN_STA_PS_STA);
-
- atomic_dec(&sdata->bss->num_sta_ps);
- sta_info_recalc_tim(sta);
- }
-
local->num_sta--;
local->sta_generation++;
@@ -785,6 +776,15 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
*/
synchronize_rcu();
+ if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+ BUG_ON(!sdata->bss);
+
+ clear_sta_flag(sta, WLAN_STA_PS_STA);
+
+ atomic_dec(&sdata->bss->num_sta_ps);
+ sta_info_recalc_tim(sta);
+ }
+
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
__skb_queue_purge(&sta->ps_tx_buf[ac]);
--
1.7.7
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end
2012-01-27 10:02 ` [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end Helmut Schaa
2012-01-27 10:02 ` [PATCH 3/3] mac80211: Move num_sta_ps counter decrement after synchronize_rcu Helmut Schaa
@ 2012-01-30 11:07 ` Helmut Schaa
2012-01-30 14:18 ` [PATCHv2 " Helmut Schaa
2 siblings, 0 replies; 5+ messages in thread
From: Helmut Schaa @ 2012-01-30 11:07 UTC (permalink / raw)
To: linux-wireless; +Cc: linville, johannes, Helmut Schaa
On Fri, Jan 27, 2012 at 11:02 AM, Helmut Schaa
<helmut.schaa@googlemail.com> wrote:
> If the driver blocked this specific STA with the help of
> ieee80211_sta_block_awake we won't clear WLAN_STA_PS_STA later but
> still decrement num_sta_ps. Hence, the next data frame from this
> STA will trigger ap_sta_ps_end again and also decrement num_sta_ps
> again leading to an incorrect num_sta_ps counter.
>
> This can result in problems with powersaving clients not waking up
> from PS because the TIM calculation might be skipped due to the
> incorrect num_sta_ps counter.
John, I need to send a v2 for this since it introduces a warning:
net/mac80211/rx.c: In function ‘ap_sta_ps_end’:
net/mac80211/rx.c:1148:32: warning: unused variable ‘sdata’ [-Wunused-variable]
Helmut
> Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
> ---
> net/mac80211/rx.c | 1 -
> net/mac80211/sta_info.c | 4 +++-
> 2 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> index 3567586..f89617a 100644
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -1147,7 +1147,6 @@ static void ap_sta_ps_end(struct sta_info *sta)
> {
> struct ieee80211_sub_if_data *sdata = sta->sdata;
>
> - atomic_dec(&sdata->bss->num_sta_ps);
>
> #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
> printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
> diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
> index 70a0de3..92b894c 100644
> --- a/net/mac80211/sta_info.c
> +++ b/net/mac80211/sta_info.c
> @@ -1007,9 +1007,11 @@ EXPORT_SYMBOL(ieee80211_find_sta);
> static void clear_sta_ps_flags(void *_sta)
> {
> struct sta_info *sta = _sta;
> + struct ieee80211_sub_if_data *sdata = sta->sdata;
>
> clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
> - clear_sta_flag(sta, WLAN_STA_PS_STA);
> + if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
> + atomic_dec(&sdata->bss->num_sta_ps);
> }
>
> /* powersave support code */
> --
> 1.7.7
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCHv2 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end
2012-01-27 10:02 ` [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end Helmut Schaa
2012-01-27 10:02 ` [PATCH 3/3] mac80211: Move num_sta_ps counter decrement after synchronize_rcu Helmut Schaa
2012-01-30 11:07 ` [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end Helmut Schaa
@ 2012-01-30 14:18 ` Helmut Schaa
2 siblings, 0 replies; 5+ messages in thread
From: Helmut Schaa @ 2012-01-30 14:18 UTC (permalink / raw)
To: linux-wireless; +Cc: linville, johannes, Helmut Schaa
If the driver blocked this specific STA with the help of
ieee80211_sta_block_awake we won't clear WLAN_STA_PS_STA later but
still decrement num_sta_ps. Hence, the next data frame from this
STA will trigger ap_sta_ps_end again and also decrement num_sta_ps
again leading to an incorrect num_sta_ps counter.
This can result in problems with powersaving clients not waking up
from PS because the TIM calculation might be skipped due to the
incorrect num_sta_ps counter.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
---
v2: Fix a compiler warning
net/mac80211/rx.c: In function 'ap_sta_ps_end':
net/mac80211/rx.c:1148:32: warning: unused variable 'sdata' [-Wunused-variable]
net/mac80211/rx.c | 8 ++------
net/mac80211/sta_info.c | 4 +++-
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3567586..fe82881 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1145,19 +1145,15 @@ static void ap_sta_ps_start(struct sta_info *sta)
static void ap_sta_ps_end(struct sta_info *sta)
{
- struct ieee80211_sub_if_data *sdata = sta->sdata;
-
- atomic_dec(&sdata->bss->num_sta_ps);
-
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
- sdata->name, sta->sta.addr, sta->sta.aid);
+ sta->sdata->name, sta->sta.addr, sta->sta.aid);
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
- sdata->name, sta->sta.addr, sta->sta.aid);
+ sta->sdata->name, sta->sta.addr, sta->sta.aid);
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
return;
}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 70a0de3..92b894c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1007,9 +1007,11 @@ EXPORT_SYMBOL(ieee80211_find_sta);
static void clear_sta_ps_flags(void *_sta)
{
struct sta_info *sta = _sta;
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- clear_sta_flag(sta, WLAN_STA_PS_STA);
+ if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
+ atomic_dec(&sdata->bss->num_sta_ps);
}
/* powersave support code */
--
1.7.7
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-01-30 14:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-27 10:02 [PATCH 1/3] mac80211: Fix incorrect num_sta_ps decrement in __sta_info_destroy Helmut Schaa
2012-01-27 10:02 ` [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end Helmut Schaa
2012-01-27 10:02 ` [PATCH 3/3] mac80211: Move num_sta_ps counter decrement after synchronize_rcu Helmut Schaa
2012-01-30 11:07 ` [PATCH 2/3] mac80211: Fix incorrect num_sta_ps decrement in ap_sta_ps_end Helmut Schaa
2012-01-30 14:18 ` [PATCHv2 " Helmut Schaa
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).