linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mac80211: fix offchannel queue stop
@ 2010-08-27 11:45 Johannes Berg
  2010-08-27 12:30 ` Vasanthakumar Thiagarajan
  0 siblings, 1 reply; 4+ messages in thread
From: Johannes Berg @ 2010-08-27 11:45 UTC (permalink / raw)
  To: John Linville
  Cc: linux-wireless, Vivek Natarajan, Vasanthakumar Thiagarajan,
	Luis Rodriguez

From: Johannes Berg <johannes.berg@intel.com>

Somebody noticed this problem, and I outlined
to them how to fix it, but haven't heard back
from them. So while I was adding the state
field I figured I could use it to fix it.

The problem, as I understand it, is that when
we go offchannel while the driver has a queue
stopped, the driver will likely start draining
the queue and then enable it while offchannel.
This in turn will enable the interface queue,
and that leads to transmitting data frames on
the wrong channel.

Fix this by keeping track of offchannel status
per interface, and not enabling the interface
queues on interfaces that are offchannel when
the driver enables a queue.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
Too lazy to dig out who reported this, so CCing
a bunch of people at Atheros ...

 net/mac80211/ieee80211_i.h |    3 +++
 net/mac80211/offchannel.c  |   19 +++++++++++++++++--
 net/mac80211/util.c        |    5 ++++-
 3 files changed, 24 insertions(+), 3 deletions(-)

--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2010-08-27 13:26:38.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2010-08-27 13:29:44.000000000 +0200
@@ -477,9 +477,12 @@ enum ieee80211_sub_if_data_flags {
  * @SDATA_STATE_RUNNING: virtual interface is up & running; this
  *	mirrors netif_running() but is separate for interface type
  *	change handling while the interface is up
+ * @SDATA_STATE_OFFCHANNEL: This interface is currently in offchannel
+ *	mode, so queues are stopped
  */
 enum ieee80211_sdata_state_bits {
 	SDATA_STATE_RUNNING,
+	SDATA_STATE_OFFCHANNEL,
 };
 
 struct ieee80211_sub_if_data {
--- wireless-testing.orig/net/mac80211/offchannel.c	2010-08-27 13:26:38.000000000 +0200
+++ wireless-testing/net/mac80211/offchannel.c	2010-08-27 13:34:31.000000000 +0200
@@ -112,8 +112,10 @@ void ieee80211_offchannel_stop_beaconing
 		 * used from user space controlled off-channel operations.
 		 */
 		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
-		    sdata->vif.type != NL80211_IFTYPE_MONITOR)
+		    sdata->vif.type != NL80211_IFTYPE_MONITOR) {
+			set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
 			netif_tx_stop_all_queues(sdata->dev);
+		}
 	}
 	mutex_unlock(&local->iflist_mtx);
 }
@@ -131,6 +133,7 @@ void ieee80211_offchannel_stop_station(s
 			continue;
 
 		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+			set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
 			netif_tx_stop_all_queues(sdata->dev);
 			if (sdata->u.mgd.associated)
 				ieee80211_offchannel_ps_enable(sdata);
@@ -155,8 +158,20 @@ void ieee80211_offchannel_return(struct
 				ieee80211_offchannel_ps_disable(sdata);
 		}
 
-		if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
+		if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
+			clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
+			/*
+			 * This may wake up queues even though the driver
+			 * currently has them stopped. This is not very
+			 * likely, since the driver won't have gotten any
+			 * (or hardly any) new packets while we weren't
+			 * on the right channel, and even if it happens
+			 * it will at most lead to queueing up one more
+			 * packet per queue in mac80211 rather than on
+			 * the interface qdisc.
+			 */
 			netif_tx_wake_all_queues(sdata->dev);
+		}
 
 		/* re-enable beaconing */
 		if (enable_beaconing &&
--- wireless-testing.orig/net/mac80211/util.c	2010-08-27 13:27:34.000000000 +0200
+++ wireless-testing/net/mac80211/util.c	2010-08-27 13:29:44.000000000 +0200
@@ -283,8 +283,11 @@ static void __ieee80211_wake_queue(struc
 
 	if (skb_queue_empty(&local->pending[queue])) {
 		rcu_read_lock();
-		list_for_each_entry_rcu(sdata, &local->interfaces, list)
+		list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+			if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
+				continue;
 			netif_wake_subqueue(sdata->dev, queue);
+		}
 		rcu_read_unlock();
 	} else
 		tasklet_schedule(&local->tx_pending_tasklet);



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] mac80211: fix offchannel queue stop
  2010-08-27 11:45 [PATCH] mac80211: fix offchannel queue stop Johannes Berg
@ 2010-08-27 12:30 ` Vasanthakumar Thiagarajan
  2010-08-27 12:56   ` Johannes Berg
  0 siblings, 1 reply; 4+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-08-27 12:30 UTC (permalink / raw)
  To: Johannes Berg
  Cc: John Linville, linux-wireless, Vivek Natarajan,
	Vasanth Thiagarajan, Luis Rodriguez

On Fri, Aug 27, 2010 at 05:15:28PM +0530, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> Somebody noticed this problem, and I outlined
> to them how to fix it, but haven't heard back
> from them. So while I was adding the state
> field I figured I could use it to fix it.
> 
> The problem, as I understand it, is that when
> we go offchannel while the driver has a queue
> stopped, the driver will likely start draining
> the queue and then enable it while offchannel.
> This in turn will enable the interface queue,
> and that leads to transmitting data frames on
> the wrong channel.
> 
> Fix this by keeping track of offchannel status
> per interface, and not enabling the interface
> queues on interfaces that are offchannel when
> the driver enables a queue.
> 
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
> Too lazy to dig out who reported this, so CCing
> a bunch of people at Atheros ...


thanks for fixing, It was me only. Somehow I forgot this.

Vasanth

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] mac80211: fix offchannel queue stop
  2010-08-27 12:30 ` Vasanthakumar Thiagarajan
@ 2010-08-27 12:56   ` Johannes Berg
  2010-08-27 13:45     ` Vasanthakumar Thiagarajan
  0 siblings, 1 reply; 4+ messages in thread
From: Johannes Berg @ 2010-08-27 12:56 UTC (permalink / raw)
  To: Vasanthakumar Thiagarajan
  Cc: John Linville, linux-wireless, Vivek Natarajan,
	Vasanth Thiagarajan, Luis Rodriguez

On Fri, 2010-08-27 at 18:00 +0530, Vasanthakumar Thiagarajan wrote:

> > The problem, as I understand it, is that when
> > we go offchannel while the driver has a queue
> > stopped, the driver will likely start draining
> > the queue and then enable it while offchannel.
> > This in turn will enable the interface queue,
> > and that leads to transmitting data frames on
> > the wrong channel.

> thanks for fixing, It was me only. Somehow I forgot this.

Did I understand the issue correctly then?

johannes


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] mac80211: fix offchannel queue stop
  2010-08-27 12:56   ` Johannes Berg
@ 2010-08-27 13:45     ` Vasanthakumar Thiagarajan
  0 siblings, 0 replies; 4+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-08-27 13:45 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Vasanth Thiagarajan, John Linville, linux-wireless,
	Vivek Natarajan, Luis Rodriguez

On Fri, Aug 27, 2010 at 06:26:56PM +0530, Johannes Berg wrote:
> On Fri, 2010-08-27 at 18:00 +0530, Vasanthakumar Thiagarajan wrote:
> 
> > > The problem, as I understand it, is that when
> > > we go offchannel while the driver has a queue
> > > stopped, the driver will likely start draining
> > > the queue and then enable it while offchannel.
> > > This in turn will enable the interface queue,
> > > and that leads to transmitting data frames on
> > > the wrong channel.
> 
> > thanks for fixing, It was me only. Somehow I forgot this.
> 
> Did I understand the issue correctly then?

Yes, you got it right.

Vasanth

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-08-27 13:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-27 11:45 [PATCH] mac80211: fix offchannel queue stop Johannes Berg
2010-08-27 12:30 ` Vasanthakumar Thiagarajan
2010-08-27 12:56   ` Johannes Berg
2010-08-27 13:45     ` Vasanthakumar Thiagarajan

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).