On Mon, 25 Oct 2004, David Brownell wrote:

> Sure -- all SCSI commands go through usb-storage, in task context,
> so it could just usb_resume_device() before submitting any URBs.
> 
> Though this does raise the issue that it probably makes sense to
> have the "hardware" layer suspended while the upper layers'
> "virtual devices" don't know about it.  That's not the assumption
> I think we've been using so far...

No, and I won't be surprised if it comes back later to bite us!


> > My trial (more accurately, mental!) implementation is running into a
> > problem with autoresume.  The race between autoresume and disconnect is
> > very difficult to handle.  If the disconnect arrives first, then the
> > autoresume process will block waiting to acquire the device lock.  But the
> > disconnect routine can't finish until the autoresume process has exited;
> > otherwise an oops might ensue as the driver module is unloaded.
> 
> I don't follow this at all.  First, why a separate autoresume task?

It's not a separate task; it's the usb-storage control thread.

> And second, as soon as the devices are marked NOTATTACHED,
> any resume should fail-fast.   (Unless your locking updates changed
> that behavior...)

You're correct that resume will fail-fast.  But down(&udev->serialize)  
won't!  That's where the blockage is: inside locktree -- the task is
waiting to lock the device.  Once the device has been locked and the 
resume code gets a chance to execute it will indeed fail quickly.

Diagrammatically:

        usb-storage control thread      khubd
        --------------------------      -----
        dequeue next SCSI command
        start to perform the command,
          but the device has been
          suspended
                                        lock the parent hub
                                        get port connect change event
                                        call usb_disconnect
                                        lock the device
        call usb_resume_device
        call locktree: Blocks trying
          to lock the parent hub
                                        call usb_storage:disconnect()
                                        wait for control thread to exit:
                                          Deadlock!

Testing for udev->state != USB_STATE_NOTATTACHED prior to doing the down()  
will help but won't completely eliminate the window.  I'm beginning to
think that locktree() needs to fail without blocking indefinitely if the
device is marked NOTATTACHED.

The other possibility is for the usb_storage disconnect routine to exit 
_without_ waiting for the control thread to finish.  Until module unload 
support is improved, that will almost certainly lead to oopses.


> > We should give some thought to whether we will ever allow hubs to suspend
> > when they have enabled, non-suspended downstream ports.  Assuming we never
> > do (which is the current pattern) then there needn't be any resume delays.
> 
> Suspending hubs in that state makes no sense to me; but since we don't
> do any hub suspend yet, we can defer such discussions till later.

It makes sense because it automatically suspends all the downstream 
devices, without your having to go to the trouble of explicitly suspending 
each individual port.  But yes, we can defer this discussion.

Alan Stern



-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to