diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-12-13 22:54:58 +0100 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-03 12:59:59 +0100 |
commit | 97f97b1f5fe0878b35c8e314f98591771696321b (patch) | |
tree | d51b86324030567fe51f9112c2d9d2242e07c008 /net/mac80211/ieee80211_i.h | |
parent | b7cfcd113ac2a1e6b02afc7d283295729fc178a9 (diff) | |
download | op-kernel-dev-97f97b1f5fe0878b35c8e314f98591771696321b.zip op-kernel-dev-97f97b1f5fe0878b35c8e314f98591771696321b.tar.gz |
mac80211: fix station destruction in AP/mesh modes
Unfortunately, commit b22cfcfcae5b, intended to speed up roaming
by avoiding the synchronize_rcu() broke AP/mesh modes as it moved
some code into that work item that will still call into the driver
at a time where it's no longer expected to handle this: after the
AP or mesh has been stopped.
To fix this problem remove the per-station work struct, maintain a
station cleanup list instead and flush this list when stations are
flushed. To keep this patch smaller for stable, do this when the
stations are flushed (sta_info_flush()). This unfortunately brings
back the original roaming delay; I'll fix that again in a separate
patch.
Also, Ben reported that the original commit could sometimes (with
many interfaces) cause long delays when an interface is set down,
due to blocking on flush_workqueue(). Since we now maintain the
cleanup list, this particular change of the original patch can be
reverted.
Cc: stable@vger.kernel.org [3.7]
Reported-by: Ben Greear <greearb@candelatech.com>
Tested-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/ieee80211_i.h')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 28fc987..2fcd274 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -773,6 +773,10 @@ struct ieee80211_sub_if_data { u32 mntr_flags; } u; + spinlock_t cleanup_stations_lock; + struct list_head cleanup_stations; + struct work_struct cleanup_stations_wk; + #ifdef CONFIG_MAC80211_DEBUGFS struct { struct dentry *dir; |