Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e95ea49 authored by Johannes Berg's avatar Johannes Berg
Browse files

cfg80211: fix locking and lockdep complaints



To call cfg80211_get_chan_state() we need to lock
the wdev, so we need to lock the wdev_iter mutex
in cfg80211_can_use_iftype_chan(). This needs to
use nested locking for lockdep.

Also, cfg80211_get_chan_state() doesn't actually
use the rdev, so remove that completely including
the lock assertion that isn't needed.

Reported-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 2a9e6c58
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -103,15 +103,13 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
}

void
cfg80211_get_chan_state(struct cfg80211_registered_device *rdev,
		        struct wireless_dev *wdev,
cfg80211_get_chan_state(struct wireless_dev *wdev,
		        struct ieee80211_channel **chan,
		        enum cfg80211_chan_mode *chanmode)
{
	*chan = NULL;
	*chanmode = CHAN_MODE_UNDEFINED;

	ASSERT_RDEV_LOCK(rdev);
	ASSERT_WDEV_LOCK(wdev);

	if (!netif_running(wdev->netdev))
+1 −2
Original line number Diff line number Diff line
@@ -463,8 +463,7 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev,
}

void
cfg80211_get_chan_state(struct cfg80211_registered_device *rdev,
		        struct wireless_dev *wdev,
cfg80211_get_chan_state(struct wireless_dev *wdev,
		        struct ieee80211_channel **chan,
		        enum cfg80211_chan_mode *chanmode);

+10 −1
Original line number Diff line number Diff line
@@ -1059,7 +1059,16 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
		if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype))
			continue;

		cfg80211_get_chan_state(rdev, wdev_iter, &ch, &chmode);
		/*
		 * We may be holding the "wdev" mutex, but now need to lock
		 * wdev_iter. This is OK because once we get here wdev_iter
		 * is not wdev (tested above), but we need to use the nested
		 * locking for lockdep.
		 */
		mutex_lock_nested(&wdev_iter->mtx, 1);
		__acquire(wdev_iter->mtx);
		cfg80211_get_chan_state(wdev_iter, &ch, &chmode);
		wdev_unlock(wdev_iter);

		switch (chmode) {
		case CHAN_MODE_UNDEFINED: