Hi Greg,
Sorry, I forgot to mentioned base kernel version. Following patch based on
linux-3.13.y till date.
I don't find a better way to avoid infinite loops. Moreover in worst case I
find that device lock is held forever. Usually usb_open was able to get this
lock in less than 5 seconds but rarely issue reproduces when it never gets lock
for more than 2 minutes.
--- drivers/usb/core/hub.c.orig 2014-01-30 12:49:39.797839231 +0530
+++ drivers/usb/core/hub.c 2014-01-30 12:49:56.189839229 +0530
@@ -4895,6 +4895,9 @@ static void hub_events(void)
usb_unlock_device(hdev);
kref_put(&hub->kref, hub_release);
+ /* preventing tight loop holding hdev lock */
+ msleep(20);
+
} /* end while (1) */
}
-Manoj
-----Original Message-----
From: [email protected] [mailto:[email protected]]
Sent: Tuesday, January 14, 2014 12:21 AM
To: Manoj Chourasia
Cc: [email protected]; [email protected]
Subject: Re: [PATCH] usb: hub: Avoid tight loop holding hdev lock
On Tue, Dec 31, 2013 at 02:26:41PM +0530, Manoj Chourasia wrote:
> Hi All,
>
> I was facing an issue bad usb device which was affecting other system. Kernel
> was trying to enumerate the device but it was failing continuously.
> Unfortunately that device was on mounted onboard in the platform so I cannot
> remove it.
> The continuous re-enumeration of the device causing other application
> malfunctioning which were using libusb. I found that usb_find_devices() call
> was stuck in usb_open for very long time. It was stuck in getting device lock
> which was taken in hub_event thread.
> Solution was to add msleep in the loop to prevent is spinning tightly.
>
> ----------------------------------------------------------------------
> -----
> usb: hub: Avoid tight loop holding hdev lock
>
> Other system call(like usb_open) to root port device
> starved in getting device lock when the while loop
> in hub_event loops tightly because of misbehaving device.
>
> Adding a small msleep provides chance to system calls to
> schedule.
>
> The issue was returning -EPROTO and re-enumerating with
> continuous hub_events. That was makes the while loop in
> hub_event to spin tightly.
>
> usb_find_devices call from libusb tries to open all devices
> including root hub. The call to usb_open stuck for very
> long time(sometimes forever) because the priority of
> kernel thread is higher than that system call in this case.
>
> Signed-off-by: Manoj Chourasia <[email protected]>
Please don't make me hand-edit patches in order to be able to apply them. I
don't scale at all, so if you want this applied, please resend it.
Also, this isn't how you submit patches to the stable kernel tree, please read
Documentation/stable_kernel_rules.txt for how to do that.
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index
> c5c3667..b968fd5 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -4899,6 +4899,9 @@ static void hub_events(void)
> usb_unlock_device(hdev);
> kref_put(&hub->kref, hub_release);
>
> + /* preventing tight loop holding hdev lock */
> + msleep(20);
This feels like a horrible hack for some seriously broken hardware. Now I know
we work around broken hardware all the time, is this really the only way the
system can recover?
thanks,
greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/