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

Reply via email to