New console flag: CON_BOOT
CON_BOOT is like early printk in that it allows for output really
early on. It's better than early printk because it unregisters
automatically when a real console is initialised. So if you don't get
consoles registering in console_init, there isn't a huge delay between
the boot console unregistering and the real console starting. This is
the case on PA-RISC where we have serial ports that aren't discovered
until the PCI bus has been walked.
I think all the current early printk users could be converted to this
scheme with a minimal amount of effort.
diff -urpNX dontdiff linus-2.6/include/linux/console.h parisc-2.6/include/linux/console.h
--- linus-2.6/include/linux/console.h 2005-03-02 04:35:07.000000000 -0700
+++ parisc-2.6/include/linux/console.h 2005-03-02 04:25:54.000000000 -0700
@@ -84,6 +84,7 @@ void give_up_console(const struct consw
#define CON_PRINTBUFFER (1)
#define CON_CONSDEV (2) /* Last on the command line */
#define CON_ENABLED (4)
+#define CON_BOOT (8)
struct console
{
diff -urpNX dontdiff linus-2.6/kernel/printk.c parisc-2.6/kernel/printk.c
--- linus-2.6/kernel/printk.c 2005-03-02 04:35:10.000000000 -0700
+++ parisc-2.6/kernel/printk.c 2005-03-15 09:20:32.339891098 -0700
@@ -804,6 +804,11 @@ void register_console(struct console * c
if (!(console->flags & CON_ENABLED))
return;
+ if (console_drivers && (console_drivers->flags & CON_BOOT)) {
+ unregister_console(console_drivers);
+ console->flags &= ~CON_PRINTBUFFER;
+ }
+
/*
* Put this console in the list - keep the
* preferred driver at the head of the list.
--
"Next the statesmen will invent cheap lies, putting the blame upon
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince
himself that the war is just, and will thank God for the better sleep
he enjoys after this process of grotesque self-deception." -- Mark Twain
Matthew Wilcox <[email protected]> wrote:
>
> + if (console_drivers && (console_drivers->flags & CON_BOOT)) {
> + unregister_console(console_drivers);
> + console->flags &= ~CON_PRINTBUFFER;
> + }
> +
Should we support more than a single CON_BOOT-labelled driver?
On Tue, Mar 15, 2005 at 02:37:11PM -0800, Andrew Morton wrote:
> Matthew Wilcox <[email protected]> wrote:
> >
> > + if (console_drivers && (console_drivers->flags & CON_BOOT)) {
> > + unregister_console(console_drivers);
> > + console->flags &= ~CON_PRINTBUFFER;
> > + }
> > +
>
> Should we support more than a single CON_BOOT-labelled driver?
I want to say yes. But there's a can o' worms lurking under the surface.
Our goal is to get output from as early as possible, then have the real
console driver take over from the (boot|early) console in a completely
transparent way.
With just one console, this is straightforward. The BOOT console gets
unregistered, the replacement console gets its PRINTBUFFER flag cleared,
everybody's happy.
With two (or more) consoles, it's a bit more tricky. If there's only one
BOOT console and the corresponding real console gets registered first,
its PRINTBUFFER flag is cleared and it continues, then the second console
kicks in and doesn't get its PRINTBUFFER flag cleared. Everything looks
pretty, we're all happy. If the wrong console gets registered first,
we miss the start of the log on it, and the BOOT console gets the start
of the log printed twice.
If we allow two BOOT consoles, we guarantee that one of the consoles
will get double-printing, but neither will miss the start of the log.
To handle this properly, we'd have to be able to see which BOOT console
corresponds to the real console and deregister it. I think it's doable
if we do something like:
- Add an int (*takeover)(struct console *); to struct console
- Replace the hunk above with:
for (existing = console_drivers; existing; existing = existing->next) {
if (existing->takeover && existing->takeover(console)) {
unregister_console(existing);
console->flags &= ~CON_PRINTBUFFER;
}
}
That puts the onus on the early console to be able to figure out
whether a registering console is its replacement or not; for the x86_64
early_printk, that'd be as simple as comparing the ->name against "ttyS"
or "tty". It'll be a bit more tricky for PA-RISC, but would solve some
messiness that we could potentially have. I think that's doable; want
me to try it?
--
"Next the statesmen will invent cheap lies, putting the blame upon
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince
himself that the war is just, and will thank God for the better sleep
he enjoys after this process of grotesque self-deception." -- Mark Twain
Matthew Wilcox <[email protected]> wrote:
>
> I think it's doable
> if we do something like:
>
> - Add an int (*takeover)(struct console *); to struct console
> - Replace the hunk above with:
>
> for (existing = console_drivers; existing; existing = existing->next) {
> if (existing->takeover && existing->takeover(console)) {
> unregister_console(existing);
> console->flags &= ~CON_PRINTBUFFER;
> }
> }
>
> That puts the onus on the early console to be able to figure out
> whether a registering console is its replacement or not; for the x86_64
> early_printk, that'd be as simple as comparing the ->name against "ttyS"
> or "tty". It'll be a bit more tricky for PA-RISC, but would solve some
> messiness that we could potentially have. I think that's doable; want
> me to try it?
It doesn't sound terribly important - I was just curious, thanks. We can
let this one be demand-driven.
I'm surprised that more systems don't encounter this - there's potentially
quite a gap between console_init() and the bringup of the first real
console driver. What happens if we crash in mem_init()? Am I misreading
the code, or do we just get no info?
On Wed, Mar 16, 2005 at 01:09:48PM -0800, Andrew Morton wrote:
> It doesn't sound terribly important - I was just curious, thanks. We can
> let this one be demand-driven.
OK, thanks ;-)
> I'm surprised that more systems don't encounter this - there's potentially
> quite a gap between console_init() and the bringup of the first real
> console driver. What happens if we crash in mem_init()? Am I misreading
> the code, or do we just get no info?
You're spot on, we get no info. That's why there's a bunch of kludges
around, mostly called early_printk. But most people use x86 and they
get console output sufficiently early anyway because they know their
serial port is at 0x3f8 ...
I just realised that with CON_BOOT, we could actually get rid of the
__con_initcall loop in tty_io.c and let all the horrible early serial
console stuff disappear.
This console stuff really needs a dedicated maintainer ... wonder if
we can find a sucker ...
--
"Next the statesmen will invent cheap lies, putting the blame upon
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince
himself that the war is just, and will thank God for the better sleep
he enjoys after this process of grotesque self-deception." -- Mark Twain
> You're spot on, we get no info. That's why there's a bunch of kludges
> around, mostly called early_printk. But most people use x86 and they
> get console output sufficiently early anyway because they know their
> serial port is at 0x3f8 ...
>
> I just realised that with CON_BOOT, we could actually get rid of the
> __con_initcall loop in tty_io.c and let all the horrible early serial
> console stuff disappear.
>
> This console stuff really needs a dedicated maintainer ... wonder if
> we can find a sucker ...
I like ot tackle those problems. The only thing is I'm busy handling the
fbdev fixes.
Where is this patch? The work looks like the stuff I did a few years ago.
On Wed, 16 Mar 2005, Andrew Morton wrote:
> Matthew Wilcox <[email protected]> wrote:
> >
> > I think it's doable
> > if we do something like:
> >
> > - Add an int (*takeover)(struct console *); to struct console
> > - Replace the hunk above with:
> >
> > for (existing = console_drivers; existing; existing = existing->next) {
> > if (existing->takeover && existing->takeover(console)) {
> > unregister_console(existing);
> > console->flags &= ~CON_PRINTBUFFER;
> > }
> > }
> >
> > That puts the onus on the early console to be able to figure out
> > whether a registering console is its replacement or not; for the x86_64
> > early_printk, that'd be as simple as comparing the ->name against "ttyS"
> > or "tty". It'll be a bit more tricky for PA-RISC, but would solve some
> > messiness that we could potentially have. I think that's doable; want
> > me to try it?
>
> It doesn't sound terribly important - I was just curious, thanks. We can
> let this one be demand-driven.
>
> I'm surprised that more systems don't encounter this - there's potentially
> quite a gap between console_init() and the bringup of the first real
> console driver. What happens if we crash in mem_init()? Am I misreading
> the code, or do we just get no info?
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
James Simmons <[email protected]> wrote:
>
> Where is this patch?
From: Matthew Wilcox <[email protected]>
CON_BOOT is like early printk in that it allows for output really early on.
It's better than early printk because it unregisters automatically when a
real console is initialised. So if you don't get consoles registering in
console_init, there isn't a huge delay between the boot console
unregistering and the real console starting. This is the case on PA-RISC
where we have serial ports that aren't discovered until the PCI bus has
been walked.
I think all the current early printk users could be converted to this
scheme with a minimal amount of effort.
Signed-off-by: Andrew Morton <[email protected]>
---
25-akpm/include/linux/console.h | 1 +
25-akpm/kernel/printk.c | 5 +++++
2 files changed, 6 insertions(+)
diff -puN include/linux/console.h~new-console-flag-con_boot include/linux/console.h
--- 25/include/linux/console.h~new-console-flag-con_boot 2005-03-15 22:47:16.000000000 -0800
+++ 25-akpm/include/linux/console.h 2005-03-15 22:47:16.000000000 -0800
@@ -84,6 +84,7 @@ void give_up_console(const struct consw
#define CON_PRINTBUFFER (1)
#define CON_CONSDEV (2) /* Last on the command line */
#define CON_ENABLED (4)
+#define CON_BOOT (8)
struct console
{
diff -puN kernel/printk.c~new-console-flag-con_boot kernel/printk.c
--- 25/kernel/printk.c~new-console-flag-con_boot 2005-03-15 22:47:16.000000000 -0800
+++ 25-akpm/kernel/printk.c 2005-03-15 22:47:16.000000000 -0800
@@ -861,6 +861,11 @@ void register_console(struct console * c
if (!(console->flags & CON_ENABLED))
return;
+ if (console_drivers && (console_drivers->flags & CON_BOOT)) {
+ unregister_console(console_drivers);
+ console->flags &= ~CON_PRINTBUFFER;
+ }
+
/*
* Put this console in the list - keep the
* preferred driver at the head of the list.
_