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

Reply via email to