Re: Query on usb/core/devio.c

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

 



On Fri, 16 Nov 2018, Mayuresh Kulkarni wrote:

> Thanks for the comments. Based on the info so far, attempting to summarize the
> probable solution, to ensure that I understand it clearly -
> 
> Facts -
> 1. USBFS driver grabs a PM ref-count in .open and drops it in .close which means
> USB device cannot suspend untill user-space closes it (even if all interface
> drivers report "idle" to usb-core).
> 2. Since the .ioctl "knows" that .open has ensured to keep device active, it
> does not call PM runtime APIs.
> 
> Proposal -
> 1. Add new ioctl: suspend & wait-for-resume
> 2. suspend ioctl: decrements PM ref count and return
> 3. wait-for-resume ioctl: wait for resume or timeout or signal

Do you really want to have a timeout for this ioctl?  Maybe it isn't 
important -- I don't know.

> 4. Modify .ioctl implementation to do PM runtime calls except for above "new"
> ioctl calls (so pm_runtime_get_sync -> ioctl -> response ->
> pm_runtime_put_sync). This also means, pm runtime get/put will be in both
> .open/.close.

That's not exactly what I had in mind.  Open will do:

	ps->runtime_active = true;

The new suspend ioctl will do this:

	if (ps->runtime_active) {
		usb_autosuspend_device(ps->dev);
		ps->runtime_active = false;
	}

and the old ioctls (and close) will do this at the start:

	if (!ps->runtime_active) {
		if (usb_autoresume_device(ps->dev))
			return -EIO;	/* Could not resume */
		ps->runtime_active = true;
	}		

This means that after any interaction with the device, you will have to 
call the suspend ioctl again if you want the device to go back to 
sleep.

> Use-case analysis -
> 1. Remote-wake: Due to device's remote wake, wait-for-resume will return
> successfully. The user space caller then need to queue a request to "know" the
> reason of remote-wake.
> 2. Host-wake: The user-space caller issues any ioctl supported by .ioctl method.
> Due to (4) above, the device will be resumed and the ioctl will be performed.

Correct.

> For (2) in use-case analysis, the user-space caller's wait-for-resume will also
> return, but since it knows that it has initiated the ioctl, it may or may not
> decide to queue a request. Instead, when ioctl returns it can call wait-for-
> resume again.

Yes.  Of course, your app will have some way to check for user
interaction with the device.  Doing these checks while the device is
suspended would be counter-productive, since the check itself would
wake up the device.  So you will probably want to do a check as soon as
you know the device has woken up, regardless of the cause.  If you 
don't, you run the risk of not noticing a user interaction.

> Am I getting in sync with your comments?
> 
> What issue(s) you anticipate in above proposal due to inherent race condition
> between host and remote-wake?

Only what I mentioned above, that your program should check for user 
interaction whenever it knows the device has woken up.

> Based on my meagre understanding of usb-core, it feels
> like usb_lock_device/usb_unlock_device calls around remote-wake and usbfs ioctl
> should help with race condition, right?

No, they will not help.  This is not a race between two different parts
of the kernel both trying to communicate with the device; it is a race
between the kernel and the user.  usb_lock_device doesn't prevent the 
user from interacting with the device.  :-)

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