On Wed, 7 Jul 2004, Jesse Stockall wrote:

> On Wed, 2004-07-07 at 14:10, Alan Stern wrote:
> > 
> > This shows that some thread has locked the usb_all_devices_rwsem but 
> > didn't unlock it.  Kind of hard to tell where that occurred, though.  Did 
> > you apply that short patch I sent out yesterday?  It's included in the 
> > patch below.
> > 
> 
> Yes, I had already applied the 1 liner you sent yesterday.
> 
> > This patch will print a lot of extra information related to that rwsem in
> > the system log.  Probably everything we need will be in the part of the
> > log corresponding to when the usbhid module is loaded.
> > 
> 
> Here is the relevant log output:

Arrgh!  You know, this was a possibility that occurred to me while writing
this code, but then I forgot and never checked up on it.

The problem is that rw-semaphores don't have the semantics I need.  I need 
something where, if the semaphore is locked for reading and a writer is 
waiting for the lock, another reader will be granted a readlock 
immediately.  But that's not how it works; another reader will be forced 
to wait until the writer is done.

Okay, guess I'll have to do a little roll-your-own.  Try out this patch.  
It assumes you have already applied that 1-liner.

Alan Stern



===== drivers/usb/core/usb.c 1.281 vs edited =====
--- 1.281/drivers/usb/core/usb.c        Wed Jun 30 09:44:26 2004
+++ edited/drivers/usb/core/usb.c       Wed Jul  7 15:47:23 2004
@@ -64,6 +64,7 @@
                        /* Not honored on modular build */
 
 static DECLARE_RWSEM(usb_all_devices_rwsem);
+static DECLARE_WAIT_QUEUE_HEAD(usb_all_devices_wqh);
 
 
 static int generic_probe (struct device *dev)
@@ -933,6 +934,7 @@
 {
        up(&udev->serialize);
        up_read(&usb_all_devices_rwsem);
+       wake_up(&usb_all_devices_wqh);
 }
 
 /**
@@ -940,10 +942,15 @@
  *
  * This is necessary when registering a new driver or probing a bus,
  * since the driver-model core may try to use any usb_device.
+ *
+ * Unfortunately we have to use a separate wait queue, because we need
+ * to make sure that a thread waiting for a writelock won't block other
+ * threads from acquiring a readlock.
  */
 void usb_lock_all_devices(void)
 {
-       down_write(&usb_all_devices_rwsem);
+       wait_event(usb_all_devices_wqh,
+                       down_write_trylock(&usb_all_devices_rwsem));
 }
 
 /**
@@ -952,6 +959,7 @@
 void usb_unlock_all_devices(void)
 {
        up_write(&usb_all_devices_rwsem);
+       wake_up(&usb_all_devices_wqh);
 }
 
 



-------------------------------------------------------
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