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