LWN.net Logo

USB and fast booting

By Jake Edge
April 29, 2009

The changes that are being made for a faster-booting Linux have generally been welcomed, but when they lead to an apparent regression, complaints will be heard. That situation arose recently when Jeff Garzik reported a regression that caused one of his systems to no longer boot. Because of some changes made to the way USB initializes, the system no longer recognized his disks in time to mount the root filesystem from them. As it turns out, the problem is not limited to disks, nor is it new; it is a longstanding race condition that previously was being "won" by most hardware, but that same hardware is often losing the race now.

Garzik had bisected the problem to a particular commit made back in September of 2008. Instead of sleeping for 100ms as part of the initialization of each USB root hub, the new code uses the delayed work mechanism to schedule the next initialization step 100ms in the future. For kernels which had the USB code built-in, this would allow the boot thread to do other work, rather than block waiting for these delays. It had a rather positive impact on boot speed, with patch author Alan Stern reporting:

Arjan van de Ven was very pleased to see that this shaved 700 ms off his computer's boot time. Since his total boot time is on the order of two seconds, the improvement is considerable.

From Garzik's perspective, the problem is that this system booted successfully with every kernel version until 2.6.28. The immediate suggestion was to use the rootdelay kernel boot option which will delay the boot process for the given number of seconds before trying to mount the root filesystem. That did not sit very well with Garzik, and he asked: "When did regressions become an acceptable tradeoff for speed?"

As it turns out, Garzik had just been "lucky" before, he could have run into this problem on earlier kernels with different hardware as Greg Kroah-Hartman points out: "What happens when you buy a new box with more USB host controllers and a faster processor? Same problem." The underlying issue is specific to USB, as the old initialization waited 100ms per USB bus (i.e. root hub) synchronously, so a system with five hubs would effectively wait 500ms for the first to initialize and enumerate the devices attached. The new code does those same initializations in parallel.

While it is relatively uncommon to have USB root filesystems, it is far from unheard of. Embedded systems are a fairly likely candidate, due to cost and form factor issues, as Alan Cox explained. Multiple distributions also have support for running completely from a USB device, typically a USB flash drive.

But, as Garzik and others point out, users that upgrade their kernels (or distributions who do so), but don't add in a rootdelay option, risk having systems that cannot boot. USB is fundamentally different than other buses, however, because there is no way to know when the enumeration of devices on a particular hub has been completed. Mark Lord questioned the explanation, noting: "SATA drives also take variable amounts of time to 'show up' at boot." But as Arjan van de Ven explained, there is a significant difference:

the difference is that with sata you know when you are done and have all possible drives. No so much much with USB. So with SATA we can, and do, wait for the scan to complete at the right point in the boot.

It turns out that the same problem in a slightly different guise shows up for embedded devices that use USB consoles. David VomLehn has been working on a patch to wait for USB consoles to become available. Because embedded devices often have USB consoles, but only for development and debugging, a long delay waiting for a console that is unlikely to show up in the majority of cases is undesirable. But, because it is impossible to know that all USB devices have reported in, some kind of delay is inevitable. VomLehn's mechanism would delay up until a timeout specified in the kernel boot parameters, but, unlike rootdelay, would wake up early as soon as a console device was detected.

As VomLehn notes, the problem goes even further than that, affecting USB network devices needed at boot time as well. Discussion on various versions of his patch also pointed out that similar problems exist for other buses. As boot parallelization gets better—and more pervasive—more of these kinds of problems are going to be discovered. A more general solution for devices required at boot time needs to be found as van de Ven describes:

For other pieces it's hard. Non-enumeratable busses just suck; at some point all you can do is just wait (which we have already available today for anyone to do). I realize people don't want to just wait 4 seconds (the people who first objected to boot time improvements then suddenly care about boot time ;-)...

For root fs there's some options, and I have patches to basically retry on fail. (The patches have a bug and I don't have time to solve it this week, so I'm not submitting them) For other devices it is hard. Realistically we need hotplug to work well enough so that when a device shows up, we can just hook it up when it does.

So far, the problems have just been identified and discussed. Workarounds like rootdelay have been mentioned, but that only "solves" one facet of the problem. Distributions are, or will be, shipping 2.6.29 kernels in their upcoming releases, one hopes they have already dealt with the issue or there may be a number of rather puzzled users with systems that don't boot. It would seem important to address the problems, at least for USB storage, as part of 2.6.31.


(Log in to post comments)

USB and fast booting

Posted Apr 30, 2009 1:57 UTC (Thu) by alankila (subscriber, #47141) [Link]

Suffering from this problem, I have had to pull the USB stick out after loading kernel from it and then reinsert it when initramfs is waiting for root device to appear. This mysteriously allowed the boot to continue.

Since this worked around the problem well enough, I didn't seek for any long-term fix. I'm happy that my laziness paid off.

USB and fast booting

Posted Apr 30, 2009 5:08 UTC (Thu) by pabs (subscriber, #43278) [Link]

Shouldn't the initrd wait for your desired rootfs to become available and shouldn't the rootfs be specified by UUID rather than /dev/sdXY?

Feature availability-based boot

Posted Apr 30, 2009 7:07 UTC (Thu) by rvfh (subscriber, #31018) [Link]

Same for any feature required at boot-up, like network: it could be the initramfs' job to wait until the feature is available...

Maybe event-based init might help here?

Not an issue for distros.. due to initrd

Posted Apr 30, 2009 16:36 UTC (Thu) by arjan (subscriber, #36785) [Link]

This is only a problem for those that don't use an initrd (well the console is different).....
because the initrd is supposed to wait for the rootfs anyway

Not an issue for distros.. due to initrd

Posted May 1, 2009 2:28 UTC (Fri) by adric (subscriber, #7180) [Link]

Unfortunately, this doesn't just affect the root filesystem. For example, I recently installed Ubuntu Netbook Remix 9.04 on an Eeepc 901, with /home residing on a 16 GB SD card... rootfs is on internal storage. I soon discovered that when running on battery power, however, the SD card usually isn't available when the filesystems get mounted.

My current workaround is to check if /home is present in /etc/rc.local, and re-attempt the mount if necessary. I'm definitely on the lookout for a better fix, but at the time needed to get it working rather quickly.

USB and fast booting

Posted Apr 30, 2009 18:59 UTC (Thu) by ABCD (subscriber, #53650) [Link]

Personally, instead of "rootdelay=...", I use "rootwait", which waits until the root filesystem becomes available, and then immediately proceeds with the boot process. I've needed this since at least c. 2006 (IIRC), so this isn't news to me.

USB and fast booting

Posted May 2, 2009 11:14 UTC (Sat) by dagb (subscriber, #30984) [Link]

Hey1 That's cool. I didn't know about rootwait. Why not make rootwait time out after 31secs and make that the default?

USB and fast booting

Posted May 1, 2009 1:40 UTC (Fri) by spitzak (guest, #4593) [Link]

I know absolutely nothing about this so feel free to correct me if I am completely wrong.

But it seems that whatever step is trying to mount the USB device has to wait until initialization of the USB driver for that device is done. Therefore it seems that the driver should not say it is done until the timeout has passed. So the example machine will wait for the timeout. It may do other things first so it will still be faster.

USB and fast booting

Posted May 3, 2009 2:28 UTC (Sun) by giraffedata (subscriber, #1954) [Link]

it seems that whatever step is trying to mount the USB device has to wait until initialization of the USB driver for that device is done.

It doesn't know it's trying to mount a USB device. All it knows is block devices, and the one it was told to mount doesn't exist.

While it's undesirable to have the USB driver hold up the boot, because the boot may not depend upon any device on a given hub, it might make sense to have a driver delay an open until the full initialization has taken place, to see if the device shows up.

USB and fast booting

Posted May 3, 2009 6:13 UTC (Sun) by dlang (✭ supporter ✭, #313) [Link]

also, waiting for the USB driver to initialize isn't enough. you need to wait an unknown amount of time after the driver is initialized for all the devices to announce themselves.

the problem is that you have _no_ way of knowing if you have waited long enough. all you can do is to pick a number and guess.

it may be that the USB device was powered on at the same time as the computer, and until it finishes booting itself (and unknown time period), it can't announce it's existence.

USB and fast booting

Posted May 3, 2009 16:36 UTC (Sun) by giraffedata (subscriber, #1954) [Link]

also, waiting for the USB driver to initialize isn't enough. you need to wait an unknown amount of time after the driver is initialized for all the devices to announce themselves.

The suggestion was that the driver not consider itself initialized until it had waited a prescribed amount of time for devices to announce themselves.

the problem is that you have _no_ way of knowing if you have waited long enough. all you can do is to pick a number and guess.

That's a problem, and a big one, but it's not the immediate one. The immediate problem is that Linux already picked a number (100 ms) and it works for many people, but the new decoupling of USB driver initialization from mounting the root filesystem makes even that strategy fail. Hence the suggestion that the wait somehow be made part of mounting the USB root filesystem.

I think even if you could know when every device had reported in, it wouldn't solve the problem. Who says the root device has to be plugged in before the kernel begins running? The reason USB doesn't provide for definitive enumeration of devices is that it is designed for a fluid network, so maybe mount needs to wait for the operator to get around to plugging in the device as well.

USB and fast booting

Posted May 3, 2009 16:44 UTC (Sun) by dlang (✭ supporter ✭, #313) [Link]

if you are waiting for the operator to plug something in I think it's very reasonable to have that operator take an action after doing to to start the system.

other buses that can tell that everything that exist has reported in do not have the same problem, even in the async mode they can work because they can delay long enough for everything to report, without having to wait any longer than that.

it's the need to wait unproductivly that is the problem here

USB and fast booting

Posted May 7, 2009 9:42 UTC (Thu) by endecotp (guest, #36428) [Link]

I have had to work around this issue a few times. In the case of a root filesystem it's not difficult as the kernel can be made to wait until the device is available before continuing. For other filesystems it's more difficult. I generally mount them by label or by UUID in /etc/fstab. What I would really like is to be able to specify, e.g. in fstab, what the system should do if the device is not (yet) available i.e. wait, skip the mount, or background it. In comparison, NFS mounts can be backgrounded if the server is not immediately available. An alternative is to automount the device when it's first used, and wait at that point if it's not available. See my bug report at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=482273

Heuristics upon boot wait time?

Posted May 11, 2009 13:10 UTC (Mon) by gadnio (guest, #30187) [Link]

I still think if this cannot be done in an easy way and one just NEEDS to wait an unspecified amount of time, to just try with some heuristic (record wait times on different boots, interpolate and get the new wait amount). After a couple of boots one would know approximately how much to wait until all the (needed) devices are brought up. All that is needed is a way to store and pass on subsequent boots the needed information (previous wait time for example) so one can make a better guess.

Copyright © 2009, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds