On Sat, 1 May 2004, David Brownell wrote:

> Alan Stern wrote:
> 
> > I like the way this idea is leading.  We can have a global topology
> > semaphore protect all the children[] arrays and also the driver-model
> > lists, since the two data structure views should always be consistent.  
> > Then the ->serialize locks won't be needed for tree traversal.
> 
> Which "topology" do you mean though ... the physical (hubs, devices)
> or the logical (interfaces in current configurations)?  Or were you
> thinking of combining those?  (In which case the bus rwsem would
> seem to partly address the problem.)

Physical.  This would be only for struct usb_device, not for struct 
usb_interface, because only usb_device has a children[] array.

It might not be necessary to do this if we used the driver model links 
exclusively and did away with ->children[], but since it's there it needs 
to be protected.  And it's becoming clear that ->serialize is the wrong 
way to do so.

> > Instead they can be used by the hub driver to ensure that only one thing 
> > happens on a hub at any time.  When suspending or resetting a port, the 
> > rule should be to acquire the serialize lock on the child first, then on 
> > its parent hub.  That matches the requirements of usb_reset_device(), and 
> > the new suspend code can easily be changed to comply.
> 
> That's what the current suspend code does ... the notion of
> acquiring locks going _up_ the physical tree bothers me, but
> so far it's sufficient.

I beg to differ...  In your most recently posted patch,
usb_suspend_device() acquires hubdev->serialize _before_
hub_port_suspend() acquires dev->serialize, not _after_.

The business of going up the tree is a little odd, yes, but it's limited 
to a couple of cases where we go from a device only to its parent hub.  We 
never go all the way up to the root (unless of course the parent happens 
to be the root hub).


> > Whenever a thread executing in the hub driver acquires a hub's serialize 
> > lock, it should check that the hub device is still in 
> > USB_STATE_CONFIGURED.  That will prevent problems with trying to 
> > manipulate suspended or disconnected hubs.
> 
> Or config 0 hubs.

Right.

> > The only loose end is usb_disconnect().  It can be made to work as 
> > follows: When disconnecting a hub first make sure the state is set to 
> > USB_STATE_DISCONNECTED, then acquire and release the serialize lock to 
> > synchronize with any other threads executing in the hub driver.  Once 
> > that's done no more children can be added to that hub, so we can safely 
> > disconnect all the existing children, then acquire serialize again and 
> > unregister the hub itself.
> 
> I keep wanting a "mark this whole tree disconnected" stage in that
> process ...

I left it out because it wasn't relevant to my point.  But yes, the _very_
first step of disconnecting a hub should be to change its state and the 
state of all its children recursively to USB_STATE_DISCONNECTED.  This 
should be done without waiting to acquire any ->serialize locks (which 
means that usbdev->state will need to be protected by a global spinlock).  
Then everything else I described can take place.

Alan Stern



-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. 
Take an Oracle 10g class now, and we'll give you the exam FREE. 
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to