On Fri, Mar 30, 2007 at 10:28:48AM +0200, Oliver Neukum wrote:
> Am Freitag, 30. M?rz 2007 09:48 schrieb Greg KH:
> > > As an added complication, the resubmission would happen on another cpu.
> > > Therefore the order on the bus must be correct, hence the "smp_mb()".
> >
> > This part I still don't understand.
> >
> > What are we doing a memory barier for after the completion handler is
> > finished here? ?If we set the write_urb_busy flag to 0 after we check
> > the status, we should be safe, as that urb will not be able to be
> > resubmitted until that point in time. ?Or should we be grabbing the lock
> > for the port when we change the status instead? ?That would make more
> > sense I think.
>
> CPU A (handler) CPU B (write path)
> a = urb->status if (!write_busy)
> write_busy = 0
> usb_submit_urb(urb)
>
> On the bus CPU A's memory references can be reordered into:
>
> CPU A
>
> write_busy = 0
> a = urb->status
>
> The urb may be resubmitted on _another_ CPU which is executing the
> write code path. It may resubmit as soon as it sees the flag as zero on
> the bus. We must not assume that CPUs do on the bus as they do in the
> code. Without explicit instructions a CPU is free to postpone a read after
> a write. Therefore the correct sequence is:
>
> CPU A
>
> a = urb->status
> smp_mb()
> write_busy = 0
>
> To solve this with locking would require both CPU A and CPU B to take
> the lock, which means that the urb would have to be submitted with
> GFP_ATOMIC.
Can't this all be solved with a simple:
get port spinlock
a = urb->status
write_busy = 0
unlock spinlock
In the callback, and in the write path:
get port spinlock
if write_busy
unlock
exit
write_busy = 1
unlock port spinlock
submit_urb
thanks,
greg k-h
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel