diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-08-21 16:07:20 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-09-26 07:21:37 -0400 |
commit | c7c71066c27f2bafb2ce3b10c407c0285f56acfa (patch) | |
tree | 183c3557d596a8ae69bf3ae9219e7ef49456052e /include/net/mac80211.h | |
parent | 272b98c6455f00884f0350f775c5342358ebb73f (diff) |
mac80211: add ieee80211_iterate_active_interfaces_rtnl()
If it is needed to disconnect multiple virtual interfaces after
(WoWLAN-) suspend, the most obvious approach would be to iterate
all interfaces by calling ieee80211_iterate_active_interfaces()
and then call ieee80211_resume_disconnect() for each one. This
is what the iwlmvm driver does.
Unfortunately, this causes a locking dependency from mac80211's
iflist_mtx to the key_mtx. This is problematic as the former is
intentionally never held while calling any driver operation to
allow drivers to iterate with their own locks held. The key_mtx
is held while installing a key into the driver though, so this
new lock dependency means drivers implementing the logic above
can no longer hold their own lock while iterating.
To fix this, add a new ieee80211_iterate_active_interfaces_rtnl()
function that iterates while the RTNL is already held. This is
true during suspend/resume, so that then the locking dependency
isn't introduced.
While at it, also refactor the various interface iterators and
keep only a single implementation called by the various cases.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'include/net/mac80211.h')
-rw-r--r-- | include/net/mac80211.h | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index cc6035f1a2f1..3411c59b636b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -3920,6 +3920,25 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, | |||
3920 | void *data); | 3920 | void *data); |
3921 | 3921 | ||
3922 | /** | 3922 | /** |
3923 | * ieee80211_iterate_active_interfaces_rtnl - iterate active interfaces | ||
3924 | * | ||
3925 | * This function iterates over the interfaces associated with a given | ||
3926 | * hardware that are currently active and calls the callback for them. | ||
3927 | * This version can only be used while holding the RTNL. | ||
3928 | * | ||
3929 | * @hw: the hardware struct of which the interfaces should be iterated over | ||
3930 | * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags | ||
3931 | * @iterator: the iterator function to call, cannot sleep | ||
3932 | * @data: first argument of the iterator function | ||
3933 | */ | ||
3934 | void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw, | ||
3935 | u32 iter_flags, | ||
3936 | void (*iterator)(void *data, | ||
3937 | u8 *mac, | ||
3938 | struct ieee80211_vif *vif), | ||
3939 | void *data); | ||
3940 | |||
3941 | /** | ||
3923 | * ieee80211_queue_work - add work onto the mac80211 workqueue | 3942 | * ieee80211_queue_work - add work onto the mac80211 workqueue |
3924 | * | 3943 | * |
3925 | * Drivers and mac80211 use this to add work onto the mac80211 workqueue. | 3944 | * Drivers and mac80211 use this to add work onto the mac80211 workqueue. |