Re: [RFC PATCH 00/15] rework port power control

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

 



On Thu, 24 Oct 2013, Dan Williams wrote:

> >> Details:
> >> 1/ Port power policy needs 'connector' awareness.
> >>
> >>    It is a recipe for unintended device disconnects to turn off a
> >>    port while leaving its peer active.
> >
> > "It is a recipe" -- what is "it"?  Do you mean that under the current
> > implementation, an unintended device disconnect turns off a port while
> > leaving the port's peer turned on?  Or do you mean that this series of
> > patches creates a mechanism for doing this?
> 
> The current implementation is unaware of cases where it is turning off
> a USB3 port that has a related USB2 port.  These patches create
> mechanisms to turn off both ports in concert.

Why is that necessary?

Consider an external hub.  The USB-3 spec says that the hub is allowed 
to remove power from a port only if both the SuperSpeed and USB-2 
port-power features are set to 0.  Assuming xhci-hcd is made to do the 
same for root-hub ports, what's wrong with the kernel treating related 
ports independently?

> > What is a port's "peer"?
> 
> See patch 2 [1].  For example ACPI enumerates when a USB2 port is
> peered (colocated in the same physical plug) with a USB3 for the XHCI
> controller.

Sarah has mentioned that some systems may do weird things like hook the
USB-3 wires in a port directly to a controller while routing the USB-2
wires through an integrated hub (a "tier mismatch").  Can the ACPI data
represent this sort of thing?

Even more relevant: How is the power for such ports controlled?  By the 
controller or by the integrated hub?

> > Note that most USB-3 devices are not allowed to connect to the both
> > USB-3 and USB-2 buses at the same time.  Hubs are exceptions; they are
> > required to do so (and consequently each USB-3 hub appears to the
> > system as two separate and unrelated hubs; one that is USB-3 and one
> > that is USB-2).
> 
> I special case hubs in the code as devices that are allowed to be
> connected to both ports in a connector simultaneously.  There will be
> no peer power management in that case.  Are there other devices that
> are expected to dual connect?

According to the USB-3 spec, it is not allowed.

> >>  A 'connector' is
> >>    distinct from 'companion' ports which share the same data lines
> >>    across multiple hcds.
> >
> > Why treat "companion" ports differently?
> >
> 
> Companion-ports share 1 physical connection among controllers,
> 'connectors' co-locate multiple physical connections in one plug.

Yes, I realize that.  It doesn't answer the question, though.  In both
cases we have two usb_port structures representing a single physical
plug.  This suggests they should be treated the same way.

> >>    The existing implementation makes attempts to mitigate the damage of
> >>    khubd running in the middle of a port power control event, but
> >>    makes no guarantees.
> >
> > Sure it does.  What damage are you talking about?
> 
> Unless I missed it I did not see what prevents the port from being
> powered down mid khubd run?

It looks like hub_port_connect_change() needs to do a 
pm_runtime_get_sync on the port...  That's an easy fix, though.

>  We have the busy_bits check but what does
> that synchronize against?

It prevents khubd from trying to manage a port when another thread is 
doing something to it (a reset, for example).

> We also used to have this usb_port_runtime_resume:
> 
> static int usb_port_runtime_resume(struct device *dev)
> {...
>         usb_autopm_get_interface(intf);
> ...}

What do you mean, "used to"?  That code is there right now!

> Which arranges for hub_activate() to run on a known powered down port.

I'm not sure what you mean by "on a ... port".  hub_activate doesn't 
run on any ports; it affects the entire hub.

>  We would subsequently notice the connection gone and disconnect the
> device.  I could reliably reproduce this after just a few power
> toggles...  fixed now.

Fixed what?  Calling usb_disconnect when the connection is gone is the 
right thing to do.

> Now the policy is explicit that khubd only touches ports that have a
> power policy set to 'on', or are otherwise runtime active.  No more
> pm_suspend_ignore_children() for the hub device.  This makes hub.c a
> bit less complicated and the stats seem to agree:
> 
>  drivers/usb/core/hub.c |  252 +++++++++++++-----------------------------------
>  drivers/usb/core/hub.h |   29 +++---
>  2 files changed, 85 insertions(+), 196 deletions(-)

Okay, so you are changing what it means for a port to be in runtime
suspend.  In the current code, it means the port is powered down.  If I
understand all this, your intention is to leave a port in runtime
suspend essentially whenever the attached device is suspended (or there
is no attached device).  Then you have to decide whether or not to
power-down the port while suspending it.

> >>  We need to support both suspending hubs with
> >>    live ports (to receive wakeup events) and fully powering down the
> >>    port when userspace policy allows.
> >
> > Don't we support this already?
> >
> 
> The code tries to, yes.  The usb_port_runtime_resume() issue above is
> one bug I hit.

What's the bug?

> When patch 6 [2] moved the port into its more natural place in the
> device model hierarchy the code needed to support two 'suspended'
> states for the port.  Suspended with power on (to support remote
> wakeup), and suspended with power off.  Patch 5 [3] gives more detail.

I couldn't understand the tables in the patch 5 description.  There are 
columns labelled "power", "state", and "count", but they don't say 
whether this means power before or after the event in the left column, 
or what is being counted.

> Quick summary is:
> portX/power/pm_qos_no_power_off: regardless of connect_type never power down

Okay.  We do this already.

> portX/connect_type: when 'hotplug', prevent port power off (unless
> peer port is connected to a non-hub device, then power down until the
> peer port disconnects),

All right, this policy explains why you need to keep track of related
ports.  This should have been mentioned at the very start of your 00/15
description -- it appears to be the main reason for doing all this
work.

>  when 'hardwired' honor pm_qos_no_power_off and
> child device runtime state.  Hmm, also should block power-down when
> the child is configured for remote-wakeup, will add.

This is what we do now, right?

> portX/power/pm_qos_no_notify_flags: when set don't try to keep
> connector peer power policies synchronized.  See patch 4 [4]

I didn't understand the description of that patch either, but it seems
to contain some confusion about the power provided to a port and its
peer.  The power is either on to both or off to both, because there is
only one Vbus pin in the physical plug.

> portX/<child-usb-device>/power/control: when set to auto the port
> runtime state is implicitly controlled by the child driver

What does this mean?  Are you saying that if 
portX/<child-usb-device>/power/control is set to "on" then the port's 
runtime state _isn't_ implicitly controlled by the child driver?

Alan Stern

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