Re: Query on usb/core/devio.c

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

 



On Mon, 15 Oct 2018 09:50:46 -0400
Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:

> On Mon, 15 Oct 2018, Oliver Neukum wrote:
> 
> > On Do, 2018-10-11 at 14:29 -0400, Alan Stern wrote:
> > > On Thu, 11 Oct 2018, Mayuresh Kulkarni wrote:
> > [..]
> > > > We are looking into closing the device instance during normal operation i.e.: only open/close device when needed.
> > > > 
> > > > However, we still have one particular use-case where our USB device sends async notification to USB-host via the above interface. For that, as of now, we queue a URB from user-space. But because, the link never enters suspend (L2), we receive this async notification.
> > > > 
> > > > I am not sure, how this use-case will work, if we open-close device only when needed.
> > > > 
> > > > Assuming we have PM calls moved from open/close to ioctl or some other appropriate method, is the following sequence possible -
> > > > * Queue an URB -> suspend (L2)
> > > > * Device does remote wake & sends async notification
> > > > * URB above returns with that notification
> > > 
> > > It won't work like that.  When a device goes into suspend there can't
> > > be any outstanding URBs.
> > 
> > Exactly. Yet in case the device is active the URB must be kept running.
> > 
> > > How about instead having a mechanism whereby your usrspace driver can 
> > > tell when the device does a remote wakeup?  At that point it could
> > 
> > select() and trigger a wake up from resume()?
> 
> Something like that, although usbfs already has a usbdev_poll() routine 
> with fixed semantics.  I'm not sure we can change it.
> 
> Another difficulty is that select() applies to open files, and usbfs
> currently doesn't allow the device to suspend while the device file is
> open.
> 
> It seems that a better approach would be to have an ioctl which would:
> 
> 	fail if there are any active user URBs;
> 
> 	drop the usbfs PM reference so the device can suspend;
> 
> 	block interruptibly until the device resumes;
> 
> 	reacquire the PM reference (forcing the device to resume)
> 	if the ioctl call is interrupted.
> 

Please correct me if wrong, but as I understand, with this new ioctl proposal, below should be possible -
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.
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.
3. Compatibility is maintained with current user-space implementation as only "newer" user-space will call this new ioctl.

The USB device can suspend between (1) and (2).

If this is correct interpretation, what will happen when USB device sends remote-wake to host, but the reason is not async notification but something other than that (e.g.: something standard UAC or HID)? Here, the URB will be queued forcing the link to be active (and we probably land into same issue).
In such a case, is it expected from user-space to dequeue the URB after a while and follow (1) and (2) above?

Apologies if this is implied but I am just trying to get my head around with the proposal, hence being verbose.

> > > submit an URB via usbfs and receive the async notification.
> > 
> > I am afraid that design includes an inevitable race condition.
> > It works fine for resume(). It fails for suspend(). If you
> > require user space to cancel periodic transfers before the device
> > can suspend, you will introduce a window of at least two seconds
> > between the cancellation and the eventual suspend() during which
> > the device will not work. In fact events may be outright lost.
> 
> That "two seconds" value can be changed by the user, all the way down 
> to 0 if necessary.  However, we cannot prevent other processes from 
> keeping the device out of suspend or waking it up.
> 
> > If you want to suspend with user space drivers active, the kernel will
> > have to kill all active URBs originating from user space drivers.
> 
> What difference does it make if the URBs are killed by the user instead 
> of the kernel?
> 
> > And notify user space when the device is resumed. IMHO select()
> > is the syscall designed for that.
> 
> Apart from the difficulties mentioned above.
> 
> 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