Using ‘delay_use’ to speed up USB Enumeration

Table of content

Whilst investigating ways to improve the cold boot time of embedded Linux I came across a little-known control parameter of the USB stack known as ‘delay_use‘. It’s a parameter that describes the amount of time given to Mass Storage Devices to allow them to ‘settle down’ before being used. This article examines ‘delay_use’ and identifies how it may be used to reduce boot time and improve responsiveness.

320px-USB-Connector-Standard

320px-USB-Connector-Standard

The sole reason for the existence of ‘delay_use’ is that some USB Mass Storage Devices are unable to correctly respond to the kernel immediately after being powered up (e.g. here, here and here). I’m not sure the reasons why but would suspect it’s either because they internally need to load firmware which takes time, or require access to slow hardware (spinning disks) before getting the information they need to respond. In any case, if these devices are not given enough time then they don’t respond correctly and the kernel is unable to detect and use them.

Therefore if the kernel wishes to support a broad range of devices with every chance of success then the kernel should set this settling period high. However this delay affects all mass storage devices and the kernel will wait for the whole settle period regardless to when the device becomes ready – this means that if this value is set high then upon inserting a mass storage device the kernel will take a long time before making it available for us – thus giving the appearance of an unresponsive system. Furthermore, if the mass storage device is a boot device or used during boot then a large settle period may affect boot time.

We can see the effect of the settling period by changing it on a running system. The following command will change the settle period to 0 seconds.

Upon inserting my USB Mass Storage Device (my phone) I see the following output:

If you look at the printk times you will see that the /dev/sdc device is available within 47 ms of the insert being detected. Now let’s try increasing the settle period:

This time it took 30.125 seconds!

This give the kernel a dilemma – a large settle period results in slow initial enumeration which can impact on boot time and perceived responsiveness, but a short settle period may result in more devices failing to be detected. What should the kernel use for its default value?

There isn’t a correct value and over the course of the kernel’s development the default value has changed – when ‘delay_use’ was introduced in the 2.6.10 kernel it was set to 5 seconds, but this was later reduced by Linus to 1 second for the 2.6.34 kernel (thought not without side effects).

For embedded devices/products, where the complete range of USB devices to be supported is known or where the USB devices are hard wired then it is possible, through testing/trial-and-error to determine an optimal delay_use value – this may very well end up being 0.

In order to specify a settling period to be used during boot the following kernel argument can be used:

Additional documentation can be found in Documentation/kernel-parameters.txt

In addition to tweaking the settling period, additional boot time optimisations in this area may include starting USB enumeration as early as possible during boot and starting it in it’s own thread and if some devices do require a high value for delay_use then attempting to apply the delay to only those devices.

Related articles

Cyber-Resilience-Act-CRA-fines
Top 5 CRA Takeaways for Engineers and Device Makers
07/30/2024
Witekio-Long-Term-Software-Maintenance
Long-Term Maintenance Guide for i.MX Family Devices
06/13/2024
SOUP-Software-medical-devices
Understanding SOUP Software in Medical Device Development
05/31/2024

Newsletters
Signup