On Tue, 2008-05-06 at 23:50 +0200, Ivo van Doorn wrote: > Since commit e38bad4766a110b61fa6038f10be16ced8c6cc38 > mac80211: make ieee80211_iterate_active_interfaces not need rtnl > rt2500usb and rt73usb broke down due to attempting register access > in atomic context (which is not possible for USB hardware). > > This patch restores ieee80211_iterate_active_interfaces() to use RTNL lock, > and provides the non-RTNL version under a new name: > ieee80211_iterate_active_interfaces_atomic() > > So far only rt2x00 uses ieee80211_iterate_active_interfaces(), and those > drivers require the RTNL version of ieee80211_iterate_active_interfaces(). > Since they already call that function directly, this patch will automatically > fix the USB rt2x00 drivers. > > v2: Rename ieee80211_iterate_active_interfaces_rtnl > > Signed-off-by: Ivo van Doorn <IvDoorn@xxxxxxxxx> Acked-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx> Thanks for doing this. > John, this is still 2.6.26 material. ;) > > diff --git a/include/net/mac80211.h b/include/net/mac80211.h > index 7e75516..7d6de23 100644 > --- a/include/net/mac80211.h > +++ b/include/net/mac80211.h > @@ -1586,13 +1586,16 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw); > void ieee80211_scan_completed(struct ieee80211_hw *hw); > > /** > - * ieee80211_iterate_active_interfaces - iterate active interfaces > + * ieee80211_iterate_active_interfaces- 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 function allows the iterator function to sleep, when the iterator > + * function is atomic @ieee80211_iterate_active_interfaces_atomic can > + * be used. > * > * @hw: the hardware struct of which the interfaces should be iterated over > - * @iterator: the iterator function to call, cannot sleep > + * @iterator: the iterator function to call > * @data: first argument of the iterator function > */ > void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, > @@ -1601,6 +1604,24 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, > void *data); > > /** > + * ieee80211_iterate_active_interfaces_atomic - 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 function requires the iterator callback function to be atomic, > + * if that is not desired, use @ieee80211_iterate_active_interfaces instead. > + * > + * @hw: the hardware struct of which the interfaces should be iterated over > + * @iterator: the iterator function to call, cannot sleep > + * @data: first argument of the iterator function > + */ > +void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, > + void (*iterator)(void *data, > + u8 *mac, > + struct ieee80211_vif *vif), > + void *data); > + > +/** > * ieee80211_start_tx_ba_session - Start a tx Block Ack session. > * @hw: pointer as obtained from ieee80211_alloc_hw(). > * @ra: receiver address of the BA session recipient > diff --git a/net/mac80211/util.c b/net/mac80211/util.c > index 74c48ef..2a8c0c5 100644 > --- a/net/mac80211/util.c > +++ b/net/mac80211/util.c > @@ -401,6 +401,41 @@ void ieee80211_iterate_active_interfaces( > struct ieee80211_local *local = hw_to_local(hw); > struct ieee80211_sub_if_data *sdata; > > + rtnl_lock(); > + > + list_for_each_entry(sdata, &local->interfaces, list) { > + switch (sdata->vif.type) { > + case IEEE80211_IF_TYPE_INVALID: > + case IEEE80211_IF_TYPE_MNTR: > + case IEEE80211_IF_TYPE_VLAN: > + continue; > + case IEEE80211_IF_TYPE_AP: > + case IEEE80211_IF_TYPE_STA: > + case IEEE80211_IF_TYPE_IBSS: > + case IEEE80211_IF_TYPE_WDS: > + case IEEE80211_IF_TYPE_MESH_POINT: > + break; > + } > + if (sdata->dev == local->mdev) > + continue; > + if (netif_running(sdata->dev)) > + iterator(data, sdata->dev->dev_addr, > + &sdata->vif); > + } > + > + rtnl_unlock(); > +} > +EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); > + > +void ieee80211_iterate_active_interfaces_atomic( > + struct ieee80211_hw *hw, > + void (*iterator)(void *data, u8 *mac, > + struct ieee80211_vif *vif), > + void *data) > +{ > + struct ieee80211_local *local = hw_to_local(hw); > + struct ieee80211_sub_if_data *sdata; > + > rcu_read_lock(); > > list_for_each_entry_rcu(sdata, &local->interfaces, list) { > @@ -425,4 +460,4 @@ void ieee80211_iterate_active_interfaces( > > rcu_read_unlock(); > } > -EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); > +EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); >
Attachment:
signature.asc
Description: This is a digitally signed message part