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 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel