On Fri, 9 Jul 2004, Andrew Morton wrote: > Alan Stern <[EMAIL PROTECTED]> wrote: > > > > Okay, in a separate thread on LKML Andrew Morton has said he doesn't > > really like my approach either. Then what should it be? > > > > Clumsily use different routines for locking the first vs. the > > others in a nested set? (Or clumsily force drivers that want > > to lock more than one device to explicitly acquire and release > > the readlock?) > > > > Or only allow one thread to lock a USB device at any time? > > (That is, don't lock individual devices but only lock the > > entire set of USB devices.) > > I'm at a bit of a disadvantage here because I don't know the frequency at > which this lock will be taken, nor the expected hold times.
The lock will be taken whenever: a USB device driver is registered or unregistered; the hub driver detects that a new USB device has been plugged in; the hub driver detects that a USB device has been unplugged; a USB device is suspended, resumed, or reset; someone reads /proc/bus/usb/devices; someone changes a USB device's configuration through sysfs or usbfs; someone does I/O using the usbfs filesystem (exactly which operations take the lock hasn't quite been settled yet but probably most of them will). I may have missed a few instances but that's most of them. In each case the hold time is expected to be not much more than a second (often quite a lot less). Drivers might stretch that out quite a bit if, for example, their probe() routine is slow. usb-storage can be that way, since it scans for logical units during probe() and buggy devices often require time-consuming error recovery during the scanning process. (Matt Dharm has mentioned the possibility of deferring the scanning to a separate thread, to prevent such delays.) > If it is acceptable to use a non-rw semaphore then you could perhaps do: > > > take_the_lock() > { > if (sem_holder == current) { > sem_depth++; > } else { > down(&sem); > sem_holder = current; > } > } > > drop_the_lock() > { > if (--sem_depth == 0) { > sem_holder = NULL; > up(&sem); > } > } > > or something like that. > But note that it would be preferable to deisgn the code in such > a manner that the above trick is not needed - apart from lock_kernel() > we've never had a need for such a thing anywhere else in the kernel. I don't think anything like this will help. Using a non-rw semaphore implies complete mutual exclusion -- only one thread can hold the lock at a time. Once you've accepted that, there's no need for nested locking. A driver simply acquires the single semaphore when it begins and releases it when it ends. Alan Stern ------------------------------------------------------- This SF.Net email sponsored by Black Hat Briefings & Training. Attend Black Hat Briefings & Training, Las Vegas July 24-29 - digital self defense, top technical experts, no vendor pitches, unmatched networking opportunities. Visit www.blackhat.com _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel