summaryrefslogtreecommitdiff
path: root/net/wireless/core.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-04 11:28:18 (GMT)
committerJohannes Berg <johannes.berg@intel.com>2012-07-04 11:30:23 (GMT)
commitc5a7e582490c423f0685e42ee5cfb7c6de81adb0 (patch)
tree6eda6d23264d9f434e6e92445168e55c16ea3300 /net/wireless/core.c
parenta1845fc7c552977e23fe552ad3f5c6c279e3d550 (diff)
downloadlinux-fsl-qoriq-c5a7e582490c423f0685e42ee5cfb7c6de81adb0.tar.xz
cfg80211: fix locking regression in monitor channel tracking
Michal's monitor channel tracking introduce a locking problem as it locked the rdev lock inside the netdev notifier which isn't allowed as we might already hold it if we get there by removing an interface that is up. Fix this by relying only on the RTNL to protect the interface counters, the RTNL is always held in these code paths anyway. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r--net/wireless/core.c8
1 files changed, 2 insertions, 6 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index e13365f..eb60410 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -766,7 +766,7 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
bool has_monitors_only_old = cfg80211_has_monitors_only(rdev);
bool has_monitors_only_new;
- ASSERT_RDEV_LOCK(rdev);
+ ASSERT_RTNL();
rdev->num_running_ifaces += num;
if (iftype == NL80211_IFTYPE_MONITOR)
@@ -888,10 +888,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
wdev->beacon_interval = 0;
break;
case NETDEV_DOWN:
- dev_hold(dev);
- cfg80211_lock_rdev(rdev);
cfg80211_update_iface_num(rdev, wdev->iftype, -1);
- cfg80211_unlock_rdev(rdev);
+ dev_hold(dev);
queue_work(cfg80211_wq, &wdev->cleanup_work);
break;
case NETDEV_UP:
@@ -1001,9 +999,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
mutex_unlock(&rdev->devlist_mtx);
if (ret)
return notifier_from_errno(ret);
- cfg80211_lock_rdev(rdev);
cfg80211_update_iface_num(rdev, wdev->iftype, 1);
- cfg80211_unlock_rdev(rdev);
break;
}