提交 a160ee69 编写于 作者: J Johannes Berg 提交者: David S. Miller

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: [<c10ceb99>] sysfs_read_file+0x24/0xf4
   #1:  (dev_base_lock){++.?..}, at: [<c12844ee>] wireless_show+0x1a/0x4c
  Pid: 10450, comm: head Not tainted 2.6.32-rc3 #1
  Call Trace:
   [<c102301c>] __might_sleep+0xf0/0xf7
   [<c1324355>] mutex_lock_nested+0x1a/0x33
   [<f8cea53b>] wdev_lock+0xd/0xf [cfg80211]
   [<f8cea58f>] cfg80211_wireless_stats+0x45/0x12d [cfg80211]
   [<c13118d6>] get_wireless_stats+0x16/0x1c
   [<c12844fe>] wireless_show+0x2a/0x4c

Fix this by using the rtnl instead of dev_base_lock.
Reported-by: NMiles Lane <miles.lane@gmail.com>
Signed-off-by: NJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 5c6ae5b8
...@@ -366,13 +366,13 @@ static ssize_t wireless_show(struct device *d, char *buf, ...@@ -366,13 +366,13 @@ static ssize_t wireless_show(struct device *d, char *buf,
const struct iw_statistics *iw; const struct iw_statistics *iw;
ssize_t ret = -EINVAL; ssize_t ret = -EINVAL;
read_lock(&dev_base_lock); rtnl_lock();
if (dev_isalive(dev)) { if (dev_isalive(dev)) {
iw = get_wireless_stats(dev); iw = get_wireless_stats(dev);
if (iw) if (iw)
ret = (*format)(iw, buf); ret = (*format)(iw, buf);
} }
read_unlock(&dev_base_lock); rtnl_unlock();
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册