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

From: David VomLehn
Date: Fri Apr 24 2009 - 19:10:35 EST


On Fri, Apr 24, 2009 at 11:19:51PM +0100, Jamie Lokier wrote:
> David VomLehn wrote:
> > > This looks like a good plan and not hard to implement. It even should
> > > be possible to fit USB disk drives into the scheme.
> >
> > That would definitely rock.
>
> How about this, perhaps in the generic device model:
>
> 1. Whenever a device's existence is detected by its parent bus,
> add the device id to a pool of "potential devices worth waiting for".
>
> 2. Whenever a device is registered, remove that device id from the pool.
>
> 3. Whenever a device is itself a bus, or has subdevices or
> attributes to be discovered, it triggers step 1 for all devices
> found by enumeration (or in the case of USB, whatever you have to
> wait for). Then the bus can declare itself initialised.
>
> 4. The top-level enumeration behaves as though there was a root bus,
> onto which the real buses like PCI etc. are attached as in step 3.
>
> 5. Waiting for console / boot device / userspace waiting for other
> mount points all check this pool for device ids of matching type.
> In this, the pool serves the same role as Alan Stern's global counter,
> the difference being you can wait for particular types of device when
> you need to, and this is more explicit about how a hierarchy is handled.
>
> Device ids in this pool are simply "category" values for what the
> device is relevant to - and a waitqueue. If a PCI device is a serial
> port, then goes into category "serial port", because it's relevant if
> serial console is requested on the boot command line.
>
> When waiting for a newly powered USB bus to settle, you may get
> notification of all devices on it, but you might not know enough about
> each device until the individual drivers start fetching descriptors.
> Then you can either make every device go temporarily into the pool,
> much as if it were a little bus itself, until it has detailed
> information about what type of device it is. Or you can wait until
> all those devices have fetched descriptors before the USB bus declares
> that its enumeration is complete and removes its own id.

I think this is over-engineered. This focused on boot devices, so you really
don't care about things like buses, and I don't perceive a broader use. What
really matters is particular boot device types, wherever they came from.

I'm just about to send out an RFC patch. It may work, but it sure hasn't been
tested (so we can actually be sure it doesn't work) and it is not integrated
with any bus. Following it will be a patch to handle the specific case of a
console, but even this is not intended for use.

I've been thinking about the issue of handling device classes because, as you
clearly understand, distingishing between them can give you finer granularity
during boot initialization. There are really three possible steps:
1. Discover a device exists.
2. Discover the device type
3. Completion of the probe function for the device.

The existing code is great if the interval between 1 and 2, or 2 and 3, is
nearly zero. In the first case, you do nothing at step 1 and at step 2 you
indicate that a boot device of the given type it found. In the second case,
you indicate that you have found a device of unknown type was found (passing
BOOTDEV_ANY_MASK) at step 1, ignore the information at step 2, and report
completion of the probe for a generic device type at step 3 (again passing
BOOTDEV_ANY_MASK).

There is one additional possibility, that there is a significant amount of time
that passes between steps 1, 2, and 3. The existing interfaces already handle
that, but I'm thinking a clearer interface is in order. The key is that, when
you indicate a possible boot device was found, and when you indicate the
completion of probing, you are actually passing a mask of boot device types.

Say that the device is actually a console, my favorite example. In this case,
you'd pass BOOTDEV_ANY_MASK to bootdev_found at step 1, indicating that you
don't really know the device type. This increments the pending count for all
boot device types. At step 2, you find out you have a console, so you pass
BOOTDEV_ANY_MASK & ~BOOTDEV_CONSOLE_MASK to bootdev_probe_done. This decrements
the pending count for all device types except consoles. Then, at step 3, you
call bootdev_probe_done with BOOTDEV_CONSOLE_MASK. Which decrements the pending
count for console devices and wakes up any waiters.

This is useful functionality only if we have cases where the intervals between
each of the three steps is significant. If so, then my approach is to add a
function:
void bootdev_type_found(int old_mask, enum bootdev_type type);
which is passed the mask that was passed to bootdev_found and the type the
device is now known to be. Implementation-wise, all it really does, then, is
to call bootdev_probe_done:
bootdev_probe_done(old_mask & ~(1 << type));
This would be a cleaner interface than calling bootdev_probe_done twice..

The key question is, are there cases where there is enough time between steps
1 and 2, and steps 2 and 3, to add this complexity? If not, let's skip it.

> -- Jamie

David VomLehn
--
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/