Re: [PATCH] usb: Use a workqueue in usb_add_hcd() to reduce boottime

From: Alan Stern
Date: Mon Jan 23 2012 - 11:15:01 EST


On Fri, 20 Jan 2012, Simon Glass wrote:

> First, backing up a bit, there are at least two ways to solve this.
> One is to have the drivers only call usb_add_hcd() from a work queue
> or similar - i.e. not as part of their initcall execution. The other
> is what I have done here.
>
> Before I go much further I would like to know which is
> best/preferable. Because in answer to your questions I'm not sure
> drivers have a way of dealing with failure of delayed init. It would
> need notification back to the driver at least.

I thought about this a little more. Maybe it's okay not to unbind the
driver when the async initialization fails. After all, it's not like
any other driver is going to want to manage that hardware.

But that still leaves problems. Unregistration should work properly
even when async init fails. The easiest solution seems to be to clear
hcd->self.root_hub whenever async initialization fails, and then in
usb_remove_hcd, return immediately if hcd->self.root_hub isn't set.
Doing things this way, you avoid the need to modify all those
controller drivers.

That's not all. You have a race between unbinding and async
initialization. Probably you will need to make the work routine lock
the hcd->self.controller device, for mutual exclusion with unbinding.
In addition, usb_remove_hcd should try to cancel the work routine, in
case it hasn't run yet. And finally, for the case where both things
end up running concurrently, the work routine should check whether
unbinding has already started and fail immediately if it has.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/