On Mon, 30 Apr 2001, Sancho Dauskardt wrote:

> changed
>          while( urb->status == -EINPROGRESS )
                /* WINDOW */
>                  schedule();
> 
> to
>          while( !wakeupdata->urb_complete )
                /* WINDOW */
>                  schedule();
> 
> with wakeupdata->urb_complete being set in the urb's completion handler.

Still racy: if the HC-interrupt happens in /* WINDOW */ you simply loose
the wake_up() because you are going to sleep for an interrupt which
already happened!

> Why doesn't the former work ? The code i'm using is exactly the same as the 
> api-wrapper stuff in usb.c (except that there's two urb's on the line).

Do you have the same waitqueue/current_state handling like there?
Probably some additional mb() are needed - I think it's better to
add_wait_queue() first and use set_current_state() afterwards to get the
memory access serialized - might be important for SMP.

> If my task is seeing false wakeup's, that would mean, the status has 
> changed from EINPROGRESS to something else, before the completions handler 
> was called, right ?
> But nearly everybody is relying on this behaviour ??

Sadly to say: yes!
grep'ing drivers/usb reveals 35 times using sleep_on() family!

Apparently most of the usb-drivers have this
missing-wakeup-in-conditional-schedule race! audio.c, storage/* and
probably one or two others seem to be the exceptions!

> (Note: same thing for UP and SMP !)

So far we've just dealt with user-/interrupt-context races which are there
for UP too. There are probably some more for SMP only.

Martin


_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
http://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to