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

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

 



All right, I'm starting to get the overall picture.

This patch set makes a large number of significant changes to important 
and subtle aspects of the USB stack.  It would be a lot easier to 
discuss in pieces; I can't possibly review the whole series in a 
reasonable time.

And I wish the basic approach had been discussed beforehand...  Some of 
the ideas are quite nice, but there are a lot of details that need 
close attention.

On Fri, 25 Oct 2013, Dan Williams wrote:

> >> > 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.
> 
> ...but at any given point of time a controller has exclusive ownership
> of that port, right?

More to the point, at any given time an individual usb_port has 
exclusive control of the physical power.  Whereas with peered ports, 
the physical power is controlled jointly through both usb_ports.

On the other hand, I suspect that powering down a companion port 
wouldn't work right without help.  Removing bus power would probably 
cause the port switch to think the connection had been dropped, so 
the port would be switched back to the EHCI controller.  In any case, 
it's most likely moot.  I don't know of any EHCI/companion combinations 
that actually can turn off Vbus power.

>  We don't need to send a ClearPortFeature through
> each controller, but I wonder if we would need to undo
> usb_acpi_set_power_state() before handing off the port?  As it stands
> only xhci will turn off ports via the platform hooks.

I don't think we need to worry about ACPI for companion ports.

> >> 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.
> 
> I ended up fixing it the other way round.  Set the port as suspended
> and flush khubd.  Otherwise we're waking up ports unnecessarily right?
>  Now that I think about it we can just pm_runtime_get_noresume() each
> port and then check the state.

It's worth first spending a little time thinking about what could cause
khubd to start doing something to a port while it is powered off (or in
the process of being powered off).  I can't come up with many 
possibilities.

> >>  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).
> 
> ...yes, but I did not see anything that prevented.
> 
> core0                   core1
> test_bit(busy_bit)
>                            set_bit(busy_bit)

There's nothing that directly prevents it, because in practice it
doesn't happen.  For example, suppose core1 is doing a port reset.  
core0 will have no reason to test busy_bit until it gets a
port-status-change message, and the port status doesn't change until
the reset is complete.  (Admittedly, some memory barriers might be
needed in theory -- but a port reset takes long enough that it doesn't
matter.)

I suppose you could imagine a bizarre scenario, like a device getting
unplugged at the same time that it is being reset.  In that case it
doesn't really matter what happens, because in the end the device is
gone.

> >> 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.
> 
> I'm referring to when hub_activate hits this powered down port in its port loop.

I still don't understand this point, but for now let's pass over it.  
(Note, by the way, that hub_activate does _not_ turn on power to a port
if port->power_is_on isn't set.)

> > 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.
> 
> You mean item 1 in my list :-).  Although, it's not clear what a
> 'connector' is until later in the patch series.

You should also explain at the start of the description what you mean 
by related (or peer) ports.  Then the idea of a connector is clear -- 
although I got the impression that the implementation may be a little 
over-engineered.

> >>  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?
> 
> No, I don't think we do in the current (pre-patch) code.  If the child
> device is configured for remote wakeup and goes into suspend I do not
> see anything that stops its port from powering down, outside of the
> pm_qos_no_power_off setting.

Look near the end of usb_port_suspend():

	if (status == 0 && !udev->do_remote_wakeup && udev->persist_enabled) {
		pm_runtime_put_sync(&port_dev->dev);
		port_dev->did_runtime_put = true;
	}

> >> 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.
> 
> Ok, I was not distinguishing logically off vs physically off.  We
> coordinate logical off to prevent unintentionally indicating that a
> downgraded connection is desired.  But if userspace *does* want to
> force a certain connection the thought is that it can set this flag
> and then set pm_qos_no_power_off independently for each port.  But the
> mechanism in patch 4 is admittedly quite ugly and I'm open to
> suggestions.

Is this intended to be a way for the user to force a USB-3 device to 
connect at high speed rather than SuperSpeed?  If it is, it seems like 
a rather roundabout way of doing so.

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