Re: Query on usb/core/devio.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 17 Oct 2018 10:32:14 -0400
Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:

> On Wed, 17 Oct 2018, Oliver Neukum wrote:
> 
> > On Di, 2018-10-16 at 10:46 -0400, Alan Stern wrote:
> > > On Tue, 16 Oct 2018, Mayuresh Kulkarni wrote:
> > > 
> > > > 1. User space decides when it is time to suspend the device and calls
> > > > this ioctl. The implmentation takes care to ensure, no URB is in
> > > > flight from this caller to this device. Then proceed with suspend.
> > > 
> > > Well, I did not imagine the ioctl would try to ensure that no URBs are 
> > > in flight.  The user would be responsible for that.
> > 
> > Well, we have to check for URBs in flight. In fact we would have to
> > "plug" the device against new URBs. Now, we could use a new counter.
> > But if we check asynclist, we may just as well walk it and kill the
> > URBs. It just seems a bit silly not to do that.
> 
> In fact, the USB core already flushes outstanding URBs when a device
> gets suspended.
> 
> I don't know that "plugging" is needed.  We could simply let new URBs
> fail (the core prevents URBs from being sent to a suspended device).
> 
> > > Also, proceeding with the suspend is difficult, as Oliver has pointed 
> > > out.  There is no guarantee that the device will go into suspend, 
> > > merely because the userspace driver isn't accessing it.  (In fact, 
> > > there's no guarantee that the device will _ever_ go into suspend.)  The 
> > > ioctl would probably have to include some sort of timeout; it would 
> > > return early if the timeout expired before the device was suspended.
> > 
> > Exactly. The alternative is to have an ioctl() to just allow or block
> > suspend, more or less just exporting autopm_get/put(). The disadvantage
> > is that
> > 
> > 1. The kernel has to cancel URBs in flight
> > 2. There needs to be a mechanism to notify user space about events
> > 
> > > > 2. In an another thread, the user-space calls poll(USB-device-fd).
> > > > When poll() returns, that means the device is active now. User space
> > > > can then request an URB to read out the async notification, if any.
> > > 
> > > No; no other thread or polling is needed.  The ioctl call returns when
> > > the device resumes.  At that point the user program can check whether
> > > there is an async notification pending.
> > 
> > This is problematic. For example, what do we do if a signal needs
> > to be delivered? The obvious solution of just repeating the call will
> > not work. It races with wakeup. You'd need to restart IO to query
> > the device. But the device may be suspended. Or do you want a signal
> > to up the PM counter again?
> 
> The only way to make the ioctl work properly is to have it do a 
> runtime-PM put at the start and then a runtime-PM get before it 
> returns.  This is true regardless of the reason for returning: normal 
> termination, timeout, signal, whatever.  Nothing else would be safe.
> 

Will below steps work safely (sometimes pseudo-code/snippets help to align)? -

"new" ioctl -

timeout is parameter to ioctl.

/* attempt suspend of device */
usb_autosuspend_device(dev);

usb_unlock_device(dev);
r = wait_event_interruptible_timeout(ps->resume_wait,
    (ps->resume_done == true), timeout * HZ);
usb_lock_device(dev);

/*
 * There are 3 possibilities here:
 * 1. Device did suspend and resume (success)
 * 2. Signal was received (failed suspend)
 * 3. Time-out happened (failed suspend)
 * In any of above cases, we need to resume device.
 */
usb_autoresume_device(dev);

ps->resume_done = false;

"ps->resume_done = true;" will be done by the runtime resume call-back.

> > Making Ctrl-C wake up an unrelated device?
> 
> I don't follow.
> 
> > What do we do in case of a failed suspend or resume?
> 
> The ioctl returns when the usbfs runtime-resume callback is invoked.  
> This may or may not happen after a failed suspend.  But if the device 
> doesn't go into suspend within the ioctl's timeout period, the ioctl 
> will return in any case.
> 
> In case of a failed resume, what _can_ we do?
> 
> > How about reset_resume?
> 
> Indeed, what happens if a device in use by usbfs gets reset even while
> it isn't suspended?  We should do the same thing as much as possible, 
> regardless of the device's state when the reset occurred.
> 
> Alan Stern



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux