On 07/09/21(Tue) 18:03, Stefan Sperling wrote:
> On Tue, Sep 07, 2021 at 05:16:52PM +0200, Martin Pieuchot wrote:
> > On 07/09/21(Tue) 15:48, Stefan Sperling wrote:
> > > This patch makes iwx(4) resume reliably for me.
> > > 
> > > There were missing splnet() calls which leads to an obvious race
> > > between the interrupt handler and the code which triggers firmware
> > > loading and then sleeps to wait for confirmation.
> > > This patch adds the missing splnet().
> > > 
> > > However, even with splnet() protection added I need to add the
> > > following two lines of code to make the patch work reliably:
> > > 
> > >   /* wait for the firmware to load */
> > >   for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++) {
> > >           err = tsleep_nsec(&sc->sc_uc, 0, "iwxuc", MSEC_TO_NSEC(100));
> > > +         /* XXX This should not be needed, should it: */
> > > +         if (err == EWOULDBLOCK && sc->sc_uc.uc_intr)
> > > +                 err = 0;
> > >   }
> > >   if (err || !sc->sc_uc.uc_ok)
> > >           printf("%s: could not load firmware, %d\n", DEVNAME(sc), err);
> > > 
> > > Which seems odd. I would expect tsleep to return EWOULDBLOCK only when
> > > the interrupt handler did not already set uc_intr and call wakeup().
> > 
> > That suggests the timeout fires before the wakeup(9).
> 
> Yes, it does.
> 
> But how could uc_intr already be set to 1 in that case?

Is it set before the timeout fires or before tsleep(9) returns?

Reply via email to