After suspend/resume I've found an iwm task sleeping forever. ps showed:

0  7029     0   0 -22   0     0     0 iwmau2  DK    ??    0:00.00 (iwmns)

In this state, the driver awaits a notification from the firmware
which it won't ever get after the system has resumed from sleep.
The task running the state change to 'auth' state should abort itself.

The diff below should fix this particular (hard to reproduce) problem.
I don't particularly enjoy adding more hacks like this but this is at
least consistent with how this driver currently operates.

Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.45
diff -u -p -r1.45 if_iwm.c
--- if_iwm.c    15 Jun 2015 08:06:11 -0000      1.45
+++ if_iwm.c    15 Jun 2015 11:59:54 -0000
@@ -4984,7 +4984,7 @@ iwm_auth(struct iwm_softc *sc)
        struct iwm_node *in = (void *)ic->ic_bss;
        uint32_t duration;
        uint32_t min_duration;
-       int error;
+       int error, generation;
 
        in->in_assoc = 0;
 
@@ -5025,6 +5025,7 @@ iwm_auth(struct iwm_softc *sc)
            100 + in->in_ni.ni_intval);
        iwm_mvm_protect_session(sc, in, duration, min_duration, 500);
 
+       generation = sc->sc_generation;
        while (sc->sc_auth_prot != 2) {
                /*
                 * well, meh, but if the kernel is sleeping for half a
@@ -5038,7 +5039,9 @@ iwm_auth(struct iwm_softc *sc)
                        sc->sc_auth_prot = 0;
                        return EAUTH;
                }
-               tsleep(&sc->sc_auth_prot, 0, "iwmau2", 0);
+               tsleep(&sc->sc_auth_prot, 0, "iwmau2", hz);
+               if (generation != sc->sc_generation)
+                       return (ENXIO);
        }
 
        return 0;

Reply via email to