Commit a160ee69c6a4622ed30c377a978554015e9931cb

Authored by Johannes Berg
Committed by David S. Miller
1 parent 5c6ae5b880

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: Miles Lane <miles.lane@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 2 additions and 2 deletions Side-by-side Diff

net/core/net-sysfs.c
... ... @@ -366,13 +366,13 @@
366 366 const struct iw_statistics *iw;
367 367 ssize_t ret = -EINVAL;
368 368  
369   - read_lock(&dev_base_lock);
  369 + rtnl_lock();
370 370 if (dev_isalive(dev)) {
371 371 iw = get_wireless_stats(dev);
372 372 if (iw)
373 373 ret = (*format)(iw, buf);
374 374 }
375   - read_unlock(&dev_base_lock);
  375 + rtnl_unlock();
376 376  
377 377 return ret;
378 378 }