Hi,
We have been seeing frequent deadlocks involving wpa_supplicant on an
ipw2200 card, which rendered the system close to unusable. The scenario
is
- wpa_supplicant requests a network scan
- For some odd reason, the SCAN_COMPLETED notification never
arrives, possibly because the device loses the beacon and
disassociates, or because something is missing a wake_up
call.
- ifconfig etc block in state D
- events/0 blocks
Here's my analysis so far:
wpa_supplicant triggers the scan via an ioctl. This calls dev_ioctl, which
takes the rtnl_lock, then the ipw2200 interface's priv->sem. finds there
is a scan in progress, and goes to sleep until the other scan is complete.
This causes frequent deadlocks: wpa_supplicant triggers the scan, and
blocks. Note that this will first take the rtnl_lock (this is an
ioctl), and then the ipw2200 interface's priv->sem.
The ipw2200 worker thread also tries to do something and blocks on
priv->sem.
events/0 is trying run the linkwatch_queue (net/core/link_watch.c),
and tries to take the rtnl lock but blocks as well. While it does that,
it holds the lock_cpu_hotplug() lock for its CPU, effectively blocking
all sorts of other tasks that try to perform a flush_workqueue on some
work queue.
For sysrq-t ouput and other details, see
https://bugzilla.novell.com/show_bug.cgi?id=133513
What really surprised me was how much of the system a driver can take
down by simply blocking in an ioctl...
And now for a patch - I'm still waiting for feedback on whether this
fixes the problem for good.
-8<- cut here ----------------------------------------------------
Subject: ipw2200 - do not sleep in ipw_request_direct_scan
Drivers should not sleep for very long inside an ioctl -
so return EAGAIN and let wpa_supplicant handle the problem.
Signed-off-by: Olaf Kirch <[EMAIL PROTECTED]>
drivers/net/wireless/ipw2200.c | 14 ++++++--------
1 files changed, 6 insertions(+), 8 deletions(-)
Index: linux-2.6.15/drivers/net/wireless/ipw2200.c
===================================================================
--- linux-2.6.15.orig/drivers/net/wireless/ipw2200.c
+++ linux-2.6.15/drivers/net/wireless/ipw2200.c
@@ -8940,14 +8940,12 @@ static int ipw_request_direct_scan(struc
IPW_DEBUG_HC("starting request direct scan!\n");
if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
- err = wait_event_interruptible(priv->wait_state,
- !(priv->
- status & (STATUS_SCANNING |
-
STATUS_SCAN_ABORTING)));
- if (err) {
- IPW_DEBUG_HC("aborting direct scan");
- goto done;
- }
+ /* We should not sleep here; otherwise we will block most
+ * of the system (for instance, we hold rtnl_lock when we
+ * get here).
+ */
+ err = -EAGAIN;
+ goto done;
}
memset(&scan, 0, sizeof(scan));
-8<- cut here ----------------------------------------------------
--
Olaf Kirch | --- o --- Nous sommes du soleil we love when we play
[EMAIL PROTECTED] | / | \ sol.dhoop.naytheet.ah kin.ir.samse.qurax
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html