cfg80211: fix sysfs registration race

My locking rework/race fixes caused a regression in the
registration, causing uevent notifications for wireless
devices before the device is really fully registered and
available in nl80211.

Fix this by moving the device_add() under rtnl and move
the rfkill to afterwards (it can't be under rtnl.)

Reported-and-tested-by: Maxime Bizon <mbizon@freebox.fr>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2013-09-26 20:03:45 +02:00
parent cc63ec766b
commit aa5f66d5a1

View File

@ -566,18 +566,13 @@ int wiphy_register(struct wiphy *wiphy)
/* check and set up bitrates */ /* check and set up bitrates */
ieee80211_set_bitrate_flags(wiphy); ieee80211_set_bitrate_flags(wiphy);
rtnl_lock();
res = device_add(&rdev->wiphy.dev); res = device_add(&rdev->wiphy.dev);
if (res)
return res;
res = rfkill_register(rdev->rfkill);
if (res) { if (res) {
device_del(&rdev->wiphy.dev); rtnl_unlock();
return res; return res;
} }
rtnl_lock();
/* set up regulatory info */ /* set up regulatory info */
wiphy_regulatory_register(wiphy); wiphy_regulatory_register(wiphy);
@ -606,6 +601,15 @@ int wiphy_register(struct wiphy *wiphy)
rdev->wiphy.registered = true; rdev->wiphy.registered = true;
rtnl_unlock(); rtnl_unlock();
res = rfkill_register(rdev->rfkill);
if (res) {
rfkill_destroy(rdev->rfkill);
rdev->rfkill = NULL;
wiphy_unregister(&rdev->wiphy);
return res;
}
return 0; return 0;
} }
EXPORT_SYMBOL(wiphy_register); EXPORT_SYMBOL(wiphy_register);
@ -640,7 +644,8 @@ void wiphy_unregister(struct wiphy *wiphy)
rtnl_unlock(); rtnl_unlock();
__count == 0; })); __count == 0; }));
rfkill_unregister(rdev->rfkill); if (rdev->rfkill)
rfkill_unregister(rdev->rfkill);
rtnl_lock(); rtnl_lock();
rdev->wiphy.registered = false; rdev->wiphy.registered = false;