aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-21 06:23:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:30 -0400
commitf7969969f416e593bcc7dc24abf3f9fd6c27136d (patch)
tree4f4e2ef49d2afae82442ba273d7490938232f113 /net
parent3d832611d794b3d312d26a4b251ac5285206f90d (diff)
cfg80211: make spurious warnings less likely, configurable
Bob reported that he got warnings in IBSS mode about the ssid_len being zero on a joined event, but only when kmemcheck was enabled. This appears to be due to a race condition between drivers and userspace, when the driver reports joined but the user in the meantime decided to leave the IBSS again, the warning would trigger. This was made more likely by kmemcheck delaying the code that does the check and sends the event. So first, make the warning trigger closer to the driver, which means it's not locked, but since only the warning depends on it that's ok. And secondly, users will not want to have spurious warnings at all, so make those that are known to be racy in such a way configurable. Reported-by: Bob Copeland <me@bobcopeland.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/Kconfig17
-rw-r--r--net/wireless/core.h11
-rw-r--r--net/wireless/ibss.c4
-rw-r--r--net/wireless/sme.c12
4 files changed, 40 insertions, 4 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index c6031d5b135f..aea7e6824af9 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -17,6 +17,23 @@ config NL80211_TESTMODE
17 17
18 Say N. 18 Say N.
19 19
20config CFG80211_DEVELOPER_WARNINGS
21 bool "enable developer warnings"
22 depends on CFG80211
23 default n
24 help
25 This option enables some additional warnings that help
26 cfg80211 developers and driver developers, but that can
27 trigger due to races with userspace.
28
29 For example, when a driver reports that it was disconnected
30 from the AP, but the user disconnects manually at the same
31 time, the warning might trigger spuriously due to races.
32
33 Say Y only if you are developing cfg80211 or a driver based
34 on it (or mac80211).
35
36
20config CFG80211_REG_DEBUG 37config CFG80211_REG_DEBUG
21 bool "cfg80211 regulatory debugging" 38 bool "cfg80211 regulatory debugging"
22 depends on CFG80211 39 depends on CFG80211
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 68eaf340d613..d262d42cbd5e 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -380,4 +380,15 @@ int rdev_set_freq(struct cfg80211_registered_device *rdev,
380 struct wireless_dev *for_wdev, 380 struct wireless_dev *for_wdev,
381 int freq, enum nl80211_channel_type channel_type); 381 int freq, enum nl80211_channel_type channel_type);
382 382
383#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
384#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
385#else
386/*
387 * Trick to enable using it as a condition,
388 * and also not give a warning when it's
389 * not used that way.
390 */
391#define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; })
392#endif
393
383#endif /* __NET_WIRELESS_CORE_H */ 394#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 42840a01be74..c88338911979 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -22,7 +22,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
22 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) 22 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
23 return; 23 return;
24 24
25 if (WARN_ON(!wdev->ssid_len)) 25 if (!wdev->ssid_len)
26 return; 26 return;
27 27
28 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 28 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
@@ -58,6 +58,8 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
58 struct cfg80211_event *ev; 58 struct cfg80211_event *ev;
59 unsigned long flags; 59 unsigned long flags;
60 60
61 CFG80211_DEV_WARN_ON(!wdev->ssid_len);
62
61 ev = kzalloc(sizeof(*ev), gfp); 63 ev = kzalloc(sizeof(*ev), gfp);
62 if (!ev) 64 if (!ev)
63 return; 65 return;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 4a8289f9b4f0..68307883ec87 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -351,7 +351,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
351 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) 351 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
352 return; 352 return;
353 353
354 if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING)) 354 if (wdev->sme_state != CFG80211_SME_CONNECTING)
355 return; 355 return;
356 356
357 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, 357 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
@@ -445,6 +445,8 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
445 struct cfg80211_event *ev; 445 struct cfg80211_event *ev;
446 unsigned long flags; 446 unsigned long flags;
447 447
448 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
449
448 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); 450 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
449 if (!ev) 451 if (!ev)
450 return; 452 return;
@@ -481,7 +483,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
481 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) 483 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
482 return; 484 return;
483 485
484 if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED)) 486 if (wdev->sme_state != CFG80211_SME_CONNECTED)
485 return; 487 return;
486 488
487 /* internal error -- how did we get to CONNECTED w/o BSS? */ 489 /* internal error -- how did we get to CONNECTED w/o BSS? */
@@ -540,6 +542,8 @@ void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
540 struct cfg80211_event *ev; 542 struct cfg80211_event *ev;
541 unsigned long flags; 543 unsigned long flags;
542 544
545 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
546
543 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); 547 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
544 if (!ev) 548 if (!ev)
545 return; 549 return;
@@ -575,7 +579,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
575 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) 579 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
576 return; 580 return;
577 581
578 if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED)) 582 if (wdev->sme_state != CFG80211_SME_CONNECTED)
579 return; 583 return;
580 584
581 if (wdev->current_bss) { 585 if (wdev->current_bss) {
@@ -639,6 +643,8 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
639 struct cfg80211_event *ev; 643 struct cfg80211_event *ev;
640 unsigned long flags; 644 unsigned long flags;
641 645
646 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
647
642 ev = kzalloc(sizeof(*ev) + ie_len, gfp); 648 ev = kzalloc(sizeof(*ev) + ie_len, gfp);
643 if (!ev) 649 if (!ev)
644 return; 650 return;