mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
wifi: mac80211: always hold sdata lock in chanctx assign/unassign
Due to all the multi-link handling, we now expose the fact that the sdata/vif is locked to drivers, e.g. when the driver uses ieee80211_set_monitor_channel(). This was true when a chanctx is added to or removed from a link, _except_ in monitor mode with the virtual sdata/vif. Change that, so that drivers can make that assumption. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20230619161906.a5cf7534beda.I5b51664231abee27e02f222083df7ccf88722929@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
5c1f97537b
commit
4484de23ba
@ -913,24 +913,30 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
|
||||
if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&local->mtx);
|
||||
if (local->use_chanctx) {
|
||||
sdata = wiphy_dereference(local->hw.wiphy,
|
||||
local->monitor_sdata);
|
||||
if (sdata) {
|
||||
sdata_lock(sdata);
|
||||
mutex_lock(&local->mtx);
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
ret = ieee80211_link_use_channel(&sdata->deflink,
|
||||
chandef,
|
||||
IEEE80211_CHANCTX_EXCLUSIVE);
|
||||
mutex_unlock(&local->mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
} else if (local->open_count == local->monitors) {
|
||||
local->_oper_chandef = *chandef;
|
||||
ieee80211_hw_config(local, 0);
|
||||
} else {
|
||||
mutex_lock(&local->mtx);
|
||||
if (local->open_count == local->monitors) {
|
||||
local->_oper_chandef = *chandef;
|
||||
ieee80211_hw_config(local, 0);
|
||||
}
|
||||
mutex_unlock(&local->mtx);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
local->monitor_chandef = *chandef;
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1133,6 +1133,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
|
||||
snprintf(sdata->name, IFNAMSIZ, "%s-monitor",
|
||||
wiphy_name(local->hw.wiphy));
|
||||
sdata->wdev.iftype = NL80211_IFTYPE_MONITOR;
|
||||
mutex_init(&sdata->wdev.mtx);
|
||||
|
||||
ieee80211_sdata_init(local, sdata);
|
||||
|
||||
@ -1157,16 +1158,19 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
|
||||
rcu_assign_pointer(local->monitor_sdata, sdata);
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
|
||||
sdata_lock(sdata);
|
||||
mutex_lock(&local->mtx);
|
||||
ret = ieee80211_link_use_channel(&sdata->deflink, &local->monitor_chandef,
|
||||
IEEE80211_CHANCTX_EXCLUSIVE);
|
||||
mutex_unlock(&local->mtx);
|
||||
sdata_unlock(sdata);
|
||||
if (ret) {
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
RCU_INIT_POINTER(local->monitor_sdata, NULL);
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
synchronize_net();
|
||||
drv_remove_interface(local, sdata);
|
||||
mutex_destroy(&sdata->wdev.mtx);
|
||||
kfree(sdata);
|
||||
return ret;
|
||||
}
|
||||
@ -1202,12 +1206,15 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
|
||||
|
||||
synchronize_net();
|
||||
|
||||
sdata_lock(sdata);
|
||||
mutex_lock(&local->mtx);
|
||||
ieee80211_link_release_channel(&sdata->deflink);
|
||||
mutex_unlock(&local->mtx);
|
||||
sdata_unlock(sdata);
|
||||
|
||||
drv_remove_interface(local, sdata);
|
||||
|
||||
mutex_destroy(&sdata->wdev.mtx);
|
||||
kfree(sdata);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user