summaryrefslogtreecommitdiff
path: root/include/net/cfg80211.h
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2020-06-04 13:04:20 +0300
committerJohannes Berg <johannes.berg@intel.com>2020-06-05 10:22:00 +0300
commit79ea1e12c0b8540100e89b32afb9f0e6503fad35 (patch)
treea5ce18c194bb617ec5337fedfe2395ba02ca5a9b /include/net/cfg80211.h
parent98749b7188affbf2900c2aab704a8853901d1139 (diff)
downloadlinux-79ea1e12c0b8540100e89b32afb9f0e6503fad35.tar.xz
cfg80211: fix management registrations deadlock
Lockdep reports that we may deadlock because we take the RTNL on the work struct, but flush it under RTNL. Clearly, it's correct. In practice, this can happen when doing rfkill on an active device. Fix this by moving the work struct to the wiphy (registered dev) layer, and iterate over all the wdevs inside there. This then means we need to track which one of them has work to do, so we don't update to the driver for all wdevs all the time. Also fix a locking bug I noticed while working on this - the registrations list is iterated as if it was an RCU list, but it isn't handle that way - and we need to lock now for the update flag anyway, so remove the RCU. Fixes: 6cd536fe62ef ("cfg80211: change internal management frame registration API") Reported-by: Markus Theil <markus.theil@tu-ilmenau.de> Reported-and-tested-by: Kenneth R. Crudup <kenny@panix.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Link: https://lore.kernel.org/r/20200604120420.b1dc540a7e26.I55dcca56bb5bdc5d7ad66a36a0b42afd7034d8be@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'include/net/cfg80211.h')
-rw-r--r--include/net/cfg80211.h5
1 files changed, 3 insertions, 2 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b58ad1a3f695..fc7e8807838d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5075,7 +5075,8 @@ struct cfg80211_cqm_config;
* by cfg80211 on change_interface
* @mgmt_registrations: list of registrations for management frames
* @mgmt_registrations_lock: lock for the list
- * @mgmt_registrations_update_wk: update work to defer from atomic context
+ * @mgmt_registrations_need_update: mgmt registrations were updated,
+ * need to propagate the update to the driver
* @mtx: mutex used to lock data in this struct, may be used by drivers
* and some API functions require it held
* @beacon_interval: beacon interval used on this device for transmitting
@@ -5121,7 +5122,7 @@ struct wireless_dev {
struct list_head mgmt_registrations;
spinlock_t mgmt_registrations_lock;
- struct work_struct mgmt_registrations_update_wk;
+ u8 mgmt_registrations_need_update:1;
struct mutex mtx;