From a160ee69c6a4622ed30c377a978554015e9931cb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Oct 2009 02:22:23 -0700 Subject: [PATCH] wext: let get_wireless_stats() sleep A number of drivers (recently including cfg80211-based ones) assume that all wireless handlers, including statistics, can sleep and they often also implicitly assume that the rtnl is held around their invocation. This is almost always true now except when reading from sysfs: BUG: sleeping function called from invalid context at kernel/mutex.c:280 in_atomic(): 1, irqs_disabled(): 0, pid: 10450, name: head 2 locks held by head/10450: #0: (&buffer->mutex){+.+.+.}, at: [] sysfs_read_file+0x24/0xf4 #1: (dev_base_lock){++.?..}, at: [] wireless_show+0x1a/0x4c Pid: 10450, comm: head Not tainted 2.6.32-rc3 #1 Call Trace: [] __might_sleep+0xf0/0xf7 [] mutex_lock_nested+0x1a/0x33 [] wdev_lock+0xd/0xf [cfg80211] [] cfg80211_wireless_stats+0x45/0x12d [cfg80211] [] get_wireless_stats+0x16/0x1c [] wireless_show+0x2a/0x4c Fix this by using the rtnl instead of dev_base_lock. Reported-by: Miles Lane Signed-off-by: Johannes Berg Signed-off-by: David S. Miller --- net/core/net-sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 821d309..427ded8 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -366,13 +366,13 @@ static ssize_t wireless_show(struct device *d, char *buf, const struct iw_statistics *iw; ssize_t ret = -EINVAL; - read_lock(&dev_base_lock); + rtnl_lock(); if (dev_isalive(dev)) { iw = get_wireless_stats(dev); if (iw) ret = (*format)(iw, buf); } - read_unlock(&dev_base_lock); + rtnl_unlock(); return ret; } -- 1.8.2.3