Re: USB3 link PM policy design

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

 



On Tue, Feb 21, 2012 at 02:55:56PM -0500, Alan Stern wrote:
> On Tue, 21 Feb 2012, Sarah Sharp wrote:
> 
> > Hi Alan,
> > 
> > I'm working on some patches to add USB 3.0 link power management to the
> > USB core and xHCI.  I think you already know that U1 and U2 are new link
> > power states for USB 3.0 (although USB 2.1 has U1, sort of, with the L1
> > state).
> > 
> > There are two ways to get into U1 or U2.  The device can initiate the
> > link state change, or the hub/roothub can initiate a link state change
> > after an idle timeout.  Either link partner can reject the request to go
> > to a lower power state.  A USB 3.0 modem might, for example, want to
> > reject a request to go into U2 because it's in the middle of receiving a
> > text message.
> > 
> > For those classes of devices that can send data to the host through an
> > interrupt endpoint, like modems or bluetooth, I think it makes sense to
> > only allow device-initiated link state changes.  The idea is the device
> > knows when it needs to transmit data to the host, and it can quickly
> > transition to a lower power link state after it's done sending data.
> 
> Would this apply to all classes with interrupt endpoints, or would it 
> be more specific?

I think it's more specific to communication class devices.  Maybe it
could be generalized to any interrupt IN endpoint, but that's not what
the Intel Windows folks are doing.  For non-communication classes,
they're just making sure that devices with interrupt or isochronous
endpoints don't have the U1/U2 timeout set too short such that we enter
a lower power state between service intervals for the endpoint.

> > If the host needs to send data through the device, the links will
> > automatically get put into U0 by the hubs in the path to the device, and
> > the hubs will force the links to stay in U0 until the packet is
> > received.  Then after the device gets the data, and transmits it through
> > the radio, the device can quickly put the link back down into U2.
> > 
> > If we have hub-initiated link state changes in this model, I think we
> > will have a lot of churn for the device rejecting link power state
> > transition requests, and I'm not sure if that will actually save power.
> > I'm also concerned about "dumb" modems that always accept the link state
> > change, and shutdown their radios, even though they are receiving data.
> > 
> > The Intel Windows folks have come up with a list of device classes and
> > what they think the device-initiated vs. hub-initiated link state policy
> > should be.  I'd like to duplicate that in Linux, so that we don't run
> > into "broken" devices that work under the Windows policy but break under
> > Linux.
> > 
> > To that end, I'd like to add a new usb_device_driver field,
> > disable_hub_initiated_lpm.  If any interface driver for a device sets
> > that flag, we won't set the U1/U2 link idle timeout values for its
> > parent hub.  We will allow the device to initiate a link state change,
> > regardless of the flag state (later if we find truly broken devices, we
> > might need a second flag).
> 
> You know, this whole thing has a slightly bizarre air to it.  Yes, the 
> device does have some idea of when it's going to need to send or 
> receive data, so it makes sense to allow the device to initiate a 
> link-state change.  But the hub has no idea at all -- it knows less 
> about what's going on than the host does.  Why should the hub ever 
> initiate anything?

The hub U1/U2 timeouts are useful for devices where the communication is
all host-initiated, like printers or mass storage devices.  Those
devices have no idea when they will need to send or receive data, so
either the host or the parent hub needs to tell them when it's safe to
go into U1 or U2.  It's just more efficient to allow the USB 3.0 hubs to
keep track of the idle timeouts than to have the CPU waking up every
10-100 milliseconds to put a device into a lower power state.

The USB 3.0 hubs themselves never initiate a transition to a lower power
link state on their upstream port unless all of their downstream ports
are in that lower power state.  So hubs are really just for propagating
the highest power link state up.

> Or to put it another way, why aren't the link-change idle timeout 
> values used by the device instead of used by the hub?

I think there actually is some of that going on.  There's this Set
Feature System Exit Latency command that's supposed to let the device
know the maximum exit latency for U1 and U2.  Then the device can look
at that value, and decide whether it makes sense to do a
device-initiated transition to a lower power link state.

> > Does this policy sound reasonable?  If so, I have a couple of questions
> > about driver binding and disabling USB devices that are related.
> 
> What would you set the idle-timeout values to?  Should those numbers be
> stored in the usb_device_driver as well?  In which case, would you need
> an explicit disable_hub_initiated_lpm field?

I'm not sure if drivers will care what the idle timeouts are.  As long
as I keep the timeouts bigger than the periodic endpoint service
interval, link PM should just be transparent for them.  Bulk and control
only devices should have the timeout set high enough not to impact
performance too much, but deciding what that value is will require
tuning.  The strawman from the Windows team was no smaller than 10ms.

The actual timeout values are turning out to be pretty host-specific,
unfortunately.  I have no idea what other host controller manufacturers
are doing, but the LPM timeouts impact the Intel bandwidth calculations
unless they're set above that 10ms minimum.  I also can't enable U2 for
devices in the second tier or below.  I have no idea what other hosts
need for LPM timeouts, so I think I might just let those vendors provide
their own algorithms.

I was going to create a new host controller driver function pointer that
could cause the xHCI host to look at the current configuration and alt
settings, and come up with acceptable U1 and U2 timeouts.

Andiry and Felipe, do you have any indication from AMD or Synopsis about
algorithms for their U1/U2 timeouts for their host controller?

> Does this affect scheduling of periodic transfers, or is that all
> handled by the xHCI hardware?

We need to let the host controller know about the increased max exit
latency when we enable U1 or U2.  That effects when it schedules
periodic endpoints.  It needs to schedule interrupt transfers soon
enough in advance so that the path to the device can come into U0 when
the packet was sent.

Isochronous transfers are another thing all together.  The host needs to
ensure that they get delivered without additional latency, so it sends a
"Ping Response" packet some time before the actual transfer.  The
scheduler has to take into account the additional pings it needs to send
in the bandwidth calculation, but again, that's all internal to the host
hardware.

> Yes, overall this seems like a reasonable way to do things, given the 
> framework imposed by the spec.  What are your further questions?

Given that I shouldn't enable the timeouts if a driver sets the
disable_hub_initiated_lpm flag, I need to make sure the timeouts (and
probably device-initiated LPM as well) are disabled before we bind any
new drivers.  The timeouts also need to be evaluated when a driver
unbinds.

It seems like there are several places where I should disable LPM, let
some change occur, and then re-evaluate what the U1/U2 timeouts should
be.  Some of those places I've identified are:
 - usb_disable_device
 - usb_set_interface
 - usb_set_configuration
 - usb_reset_configuration
 - usb_reset_device
 - where ever a new driver is bound

Is there any function I'm missing?  I also don't know exactly where to
handle checking the timeouts when a new driver binds.  There's a note
at the end of usb_set_configuration that adding each device interface
causes the driver to be bound, and I could evaluate the timeouts there,
but I'm not sure where I need to handle drivers that are loaded some
time later after the interface is installed (say through a user running
modprobe for a blacklisted module).

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