aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-05-10 06:32:47 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-05-24 18:02:16 -0400
commit8d61ffa5e01c5f676431d12caba17db164a48a86 (patch)
treec3df0dc13fdc8d2327712db10c1c654f428f11a3 /net/mac80211/mesh.c
parent5fe231e873729fa2f57cdc417d5c1f80871e2d7d (diff)
cfg80211/mac80211: use cfg80211 wdev mutex in mac80211
Using separate locks in cfg80211 and mac80211 has always caused issues, for example having to unlock in places in mac80211 to call cfg80211, which even needed a framework to make cfg80211 calls after some functions returned etc. Additionally, I suspect some issues people have reported with the cfg80211 state getting confused could be due to such issues, when cfg80211 is asking mac80211 to change state but mac80211 is in the process of telling cfg80211 that the state changed (in another way.) Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r--net/mac80211/mesh.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c14bb816c6a3..b3d1fdd46368 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -161,8 +161,11 @@ void mesh_sta_cleanup(struct sta_info *sta)
161 del_timer_sync(&sta->plink_timer); 161 del_timer_sync(&sta->plink_timer);
162 } 162 }
163 163
164 if (changed) 164 if (changed) {
165 sdata_lock(sdata);
165 ieee80211_mbss_info_change_notify(sdata, changed); 166 ieee80211_mbss_info_change_notify(sdata, changed);
167 sdata_unlock(sdata);
168 }
166} 169}
167 170
168int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 171int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -577,7 +580,9 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
577 mesh_path_expire(sdata); 580 mesh_path_expire(sdata);
578 581
579 changed = mesh_accept_plinks_update(sdata); 582 changed = mesh_accept_plinks_update(sdata);
583 sdata_lock(sdata);
580 ieee80211_mbss_info_change_notify(sdata, changed); 584 ieee80211_mbss_info_change_notify(sdata, changed);
585 sdata_unlock(sdata);
581 586
582 mod_timer(&ifmsh->housekeeping_timer, 587 mod_timer(&ifmsh->housekeeping_timer,
583 round_jiffies(jiffies + 588 round_jiffies(jiffies +
@@ -697,25 +702,21 @@ out_free:
697} 702}
698 703
699static int 704static int
700ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) 705ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata)
701{ 706{
702 struct beacon_data *old_bcn; 707 struct beacon_data *old_bcn;
703 int ret; 708 int ret;
704 709
705 mutex_lock(&ifmsh->mtx); 710 old_bcn = rcu_dereference_protected(sdata->u.mesh.beacon,
706 711 lockdep_is_held(&sdata->wdev.mtx));
707 old_bcn = rcu_dereference_protected(ifmsh->beacon, 712 ret = ieee80211_mesh_build_beacon(&sdata->u.mesh);
708 lockdep_is_held(&ifmsh->mtx));
709 ret = ieee80211_mesh_build_beacon(ifmsh);
710 if (ret) 713 if (ret)
711 /* just reuse old beacon */ 714 /* just reuse old beacon */
712 goto out; 715 return ret;
713 716
714 if (old_bcn) 717 if (old_bcn)
715 kfree_rcu(old_bcn, rcu_head); 718 kfree_rcu(old_bcn, rcu_head);
716out: 719 return 0;
717 mutex_unlock(&ifmsh->mtx);
718 return ret;
719} 720}
720 721
721void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, 722void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
@@ -726,7 +727,7 @@ void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
726 BSS_CHANGED_HT | 727 BSS_CHANGED_HT |
727 BSS_CHANGED_BASIC_RATES | 728 BSS_CHANGED_BASIC_RATES |
728 BSS_CHANGED_BEACON_INT))) 729 BSS_CHANGED_BEACON_INT)))
729 if (ieee80211_mesh_rebuild_beacon(&sdata->u.mesh)) 730 if (ieee80211_mesh_rebuild_beacon(sdata))
730 return; 731 return;
731 ieee80211_bss_info_change_notify(sdata, changed); 732 ieee80211_bss_info_change_notify(sdata, changed);
732} 733}
@@ -788,12 +789,12 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
788 sdata->vif.bss_conf.enable_beacon = false; 789 sdata->vif.bss_conf.enable_beacon = false;
789 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 790 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
790 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 791 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
791 mutex_lock(&ifmsh->mtx); 792 sdata_lock(sdata);
792 bcn = rcu_dereference_protected(ifmsh->beacon, 793 bcn = rcu_dereference_protected(ifmsh->beacon,
793 lockdep_is_held(&ifmsh->mtx)); 794 lockdep_is_held(&sdata->wdev.mtx));
794 rcu_assign_pointer(ifmsh->beacon, NULL); 795 rcu_assign_pointer(ifmsh->beacon, NULL);
795 kfree_rcu(bcn, rcu_head); 796 kfree_rcu(bcn, rcu_head);
796 mutex_unlock(&ifmsh->mtx); 797 sdata_unlock(sdata);
797 798
798 /* flush STAs and mpaths on this iface */ 799 /* flush STAs and mpaths on this iface */
799 sta_info_flush(sdata); 800 sta_info_flush(sdata);
@@ -1041,7 +1042,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
1041 spin_lock_init(&ifmsh->mesh_preq_queue_lock); 1042 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
1042 spin_lock_init(&ifmsh->sync_offset_lock); 1043 spin_lock_init(&ifmsh->sync_offset_lock);
1043 RCU_INIT_POINTER(ifmsh->beacon, NULL); 1044 RCU_INIT_POINTER(ifmsh->beacon, NULL);
1044 mutex_init(&ifmsh->mtx);
1045 1045
1046 sdata->vif.bss_conf.bssid = zero_addr; 1046 sdata->vif.bss_conf.bssid = zero_addr;
1047} 1047}