Re: Query on usb/core/devio.c

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

 



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.

> > 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