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