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>
This commit is contained in:
@@ -3919,6 +3919,25 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif),
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* ieee80211_iterate_active_interfaces_rtnl - iterate active interfaces
|
||||
*
|
||||
* This function iterates over the interfaces associated with a given
|
||||
* hardware that are currently active and calls the callback for them.
|
||||
* This version can only be used while holding the RTNL.
|
||||
*
|
||||
* @hw: the hardware struct of which the interfaces should be iterated over
|
||||
* @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
|
||||
* @iterator: the iterator function to call, cannot sleep
|
||||
* @data: first argument of the iterator function
|
||||
*/
|
||||
void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw,
|
||||
u32 iter_flags,
|
||||
void (*iterator)(void *data,
|
||||
u8 *mac,
|
||||
struct ieee80211_vif *vif),
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* ieee80211_queue_work - add work onto the mac80211 workqueue
|
||||
*
|
||||
|
Reference in New Issue
Block a user