Re: Wait for console to become available, v3.2

From: David VomLehn
Date: Thu Apr 23 2009 - 20:36:25 EST


On Wed, Apr 22, 2009 at 05:24:18PM -0400, Alan Stern wrote:
> On Wed, 22 Apr 2009, Alan Cox wrote:
>
> > > 2. All devices have been probed
> > > If we exit for reason 2, it means that no such device is present,
> > > and we go on to the do the appropriate thing for that device class.
> >
> > USB has no notion of #2 really
>
> That's true, it doesn't. But it _does_ rather have a notion of "all
> devices that were present at boot time have been probed". That should
> be good enough.
>
> Alan Stern

Okay, I've been slugging away at this and have a proposed interface. The
interface is at the level of devices of particular types because that would
maximize the opportunities for concurrency, but I don't know if interesting
buses actually provide that level of detail early enough for this to be
useful. If not, the fallback is just to do things on a bus granularity.

If bus granularity is the best that can be done, it is still interesting
to distingish between boot device types. If a boot device type is not
upported by a particular bus, we don't have to wait for probing to complete
on that bus.

I'm still scratching my head, trying to figure out where I can tap into the
'USB notion of "all devices that were present at boot time have been probed"'
that Alan mentions above, so I don't have a specific implementation yet. I'm
open to any tips in this area.

Below is a write-up of the interface that looks like it should be added to
Documentation/driver-model/bus.txt. Comments are much appreciated.

----------------------------- CUT HERE -------------------------------------
Synchronization with hot pluggable boot devices
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Earlier versions of the Linux kernel used a single-threaded approach to
boot initialization. This took a number of seconds, which mean that
hotpluggable devices used or configured during boot were generally available
before they were used. Modern kernels use a multithreaded approach, which
requires synchronization between code that wants to act upon boot devices
and the probing and initialization of those devices. Support of fine-grained
boot concurrency requires distinguishing between types of boot devices, so
that devices can be used as soon as they are initialized.

There currently two types supported:
- consoles
- network devices

There is a distinction between the hardware type and the boot device type.
>From the hardware view, most any serial device can be used as a console,
but console support is generally be configured separately. For example,
consider USB serial devices. These should be considered a console only if
the software is configured to support this usage, which is done by enabling
the CONFIG_USB_SERIAL_CONSOLE option. If this option is disabled, the USB bus
driver should not report that it has found any console devices.

Two functions are available for use by the per-bus support code:

bus_bootdev_found(int bootdev_mask)
This function must be called each time a boot device device is found.
It is passed a bit mask created by ORing any of the following flags
that apply to the device found:
BOOTDEV_CONSOLE_MASK
BOOTDEV_NETDEV_MASK
There is no need to call this function for a given device if it is
known that it cannot be used as a boot device. If it is not
possible to determine whether a device is usable as a boot device,
or what the specific type of boot device it may be, the argument
BOOTDEV_ANY_MASK can be passed. This should be used only when
necessary as it reduces the level of concurrency that can be
achieved from boot time initialization.

bus_bootdev_initialized(int bootdev_mask)
This function must be called by the bus support code after it calls the
initialiation function for a boot device. Every call to
bus_bootdev_found must be matched by a call to
bus_bootdev_initialized with the same bootdev_mask.

Device initialization functions must have called the appropriate
registration function for that device before bus_bootdev_initialized
is called. So, for console devices, register_console must be called
before bus_bootdev_initialized, and for network devices,
register_netdevice must be called first.

It is possible for bus code to avoid the need to call bus_bootdev_found
for each device if it calls it once at the beginning of device discovery and
once at the end with a mask for all of the possible types of boot devices
that could be on that bus. This approach should be avoid if at all possible
because it reduces the available boot-time concurency, which can lead
to increased boot times.

When it is time to use a given boot device type, the following function
should be used:

bus_wait_for_bootdev(enum bootdev_type type, bool (*done)(void))
The type is one of:
BOOTDEV_CONSOLE
BOOTDEV_NETDEV
The done function checks to see whether all of the boot devices
required have been registered. If it determines that this is the
case, it can return true. This will cause the wait to be terminated
even though some boot devices of the given type have not yet been
initialized, which can decrease the time to boot. If this is not
possible, it can return false. In that case, bus_wait_for_bootdev
won't return until all devices of the given type on all buses have
been initialized. Not surprisingly, this limit the opportunities to
reduce boot time.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/