Re: [PATCH v7 14/16] usb: resume (wakeup) child device when port is powered on

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

 



On Tue, Apr 29, 2014 at 8:12 AM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> On Mon, 28 Apr 2014, Dan Williams wrote:
>
>> > Can you include a brief description of situations in which this would
>> > be needed, i.e., when something would runtime-resume the port without
>> > also resuming the child device?  Testing, sure, but not much else comes
>> > to mind.
>>
>> I guess it could be considered testing, but changing the poweroff
>> policy of the port is one case where it matters to immediately resume
>> the child.  A user could (even though it is warned against in
>> Documentation/usb/power-management.txt) unplug a device while the port
>> is powered off.  Without the forced resume of the child we won't
>> notice the unplug event until much later.  So, it's a "the world may
>> have changed, revalidate" operation.  I'll include text along these
>> lines in the update.
>
> Another possibility is the user writes "on" to the port's power/control
> file while the port and device are suspended.
>
>> > I think this can be simplified a lot.  At first glance, almost no
>> > changes to hub.c will be necessary if instead you insert:
>> >
>> >                 if (port_dev->did_runtime_put) {
>> >                         port_dev->did_runtime_put = false;
>> >                         pm_runtime_get_noresume(&port_dev->dev);
>> >                         pm_request_resume(&port_dev->child->dev);
>> >                 }
>>
>> Doesn't this subvert usb_auto{resume|suspend} by changing the power
>> state of the device relative to the usage count?
>
> It does change the power state without changing the usage count, but
> this isn't a subversion.  Runtime PM allows a device to be at full
> power with a usage count of 0 or at low power with a usage count > 0.
>
> (It's not hard to think of ways of doing these things.  For example,
> pm_runtime_resume() will power-up a suspended device without increasing
> the usage count, and pm_runtime_get_noresume() will increase the usage
> count without powering-up a suspended device.)
>
> The only promise made by the runtime PM core is that it won't issue a
> pm_suspend callback if the usage count is positive.
>
>> usb_wakeup_notification() also handles putting the device back to
>> sleep if there is nothing to do.
>
> This happens automatically with any kind of runtime resume, because USB
> devices use autosuspend.

True, true, true.  I forgot that this resume was backstopped by the
timer and an implied call to rpm_suspend(RPM_AUTO), so no worries
about staying active indefinitely.  I'll proceed with the cleanup.

>
>> > But this got me thinking...  It looks like the reference to
>> > port_dev->child in usb_port_runtime_resume() already races with the
>> > line
>> >
>> >         *pdev = NULL;
>> >
>> > in usb_disconnect().  We need to make sure that a port runtime-resume
>> > is mutually exclusive with child device removal.  (Consider, for
>> > example, what happens if a thread does a runtime resume on a port and
>> > at the same time, the hub is unplugged.)  Any ideas?
>>
>> Yes, I think we simply need to add
>> pm_runtime_{get|put}(&port_dev->dev) to guarantee that port_dev->child
>> is always safe to de-reference in usb_port_runtime{suspend|resume}.
>
> You mean, add pm_runtime_get_sync(&port_dev->dev) before the
> device_del() call and pm_runtime_put(&port_dev->dev) after the *pdev =
> NULL statement?  That seems reasonable.
>
>> ...and as I go to add this I notice that prior to the "use
>> pm_request_resume" suggestion we don't de-reference port_dev->child in
>> usb_port_runtime_resume().  This realization plus the usage count
>> tracking that usb_remote_wakeup() affords is leaning me towards
>> leaving the "force wakeup" mechanism as is for the upcoming re-post.
>
> The usage count tracking isn't an issue; that's the way autosuspend is
> meant to work.  Also, you're abusing usb_wakeup_notification() by
> calling it for something that wasn't triggered by a remote wakeup
> request from the device.
>
> However, either way we still have bad interactions between
> hub_{quiesce|activate}() and usb_port_runtime_{suspend|resume}().
> Consider, for example, what happens to the ports' power states when the
> hub is reset.
>

You mean in terms of pm_runtime state getting out of sync with the
hardware state?  We do have (admittedly ugly in my opinion) a check of
the power state in hub_power_on() so if port power was runtime removed
hub_activate() will honor that and not restore power.  And a new
pm_runtime_get_sync in usb_disconnect() will handle the hub_quiesce()
interfaction.  Am I missing something?
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




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

  Powered by Linux