Am Freitag, 30. März 2007 11:03 schrieb Greg KH: > On Fri, Mar 30, 2007 at 10:45:26AM +0200, Oliver Neukum wrote: > > Am Freitag, 30. M?rz 2007 10:39 schrieb Greg KH: > > > > 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 > > > > > > > Oops. You are right. That would work. > > If you think that's simpler, yes it can be done. > > Yes, I think that would be both easier to understand, and easier to > prove correct :)
However it would not always work out so nicely. Have a look at this code from usblp: timeout = USBLP_WRITE_TIMEOUT; rv = wait_event_interruptible_timeout(usblp->wait, usblp->wcomplete || !usblp->present , timeout); if (rv < 0) return writecount ? writecount : -EINTR; and static void usblp_bulk_write(struct urb *urb) { struct usblp *usblp = urb->context; if (unlikely(!usblp || !usblp->dev || !usblp->used)) return; if (unlikely(!usblp->present)) goto unplug; if (unlikely(urb->status)) warn("usblp%d: nonzero read/write bulk status received: %d", usblp->minor, urb->status); usblp->wcomplete = 1; unplug: wake_up_interruptible(&usblp->wait); } It has the same issue. The correct code is: if (unlikely(urb->status)) warn("usblp%d: nonzero read/write bulk status received: %d", usblp->minor, urb->status); smp_mb(); usblp->wcomplete = 1; unplug: wake_up_interruptible(&usblp->wait); This can'be solved with a simple spinlock, as wait_event() can sleep. Neither is simply returning 0 an option. It would mean EOF. Really somebody went to some effort to find a lockless solution and did well, he just didn't figure out of order execution units. You'd destroy that. Regards Oliver ------------------------------------------------------------------------- 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