提交 034260d6 编写于 作者: K Kevin Cernekee 提交者: Ralf Baechle

printk: fix delayed messages from CPU hotplug events

When a secondary CPU is being brought up, it is not uncommon for
printk() to be invoked when cpu_online(smp_processor_id()) == 0.  The
case that I witnessed personally was on MIPS:

http://lkml.org/lkml/2010/5/30/4

If (can_use_console() == 0), printk() will spool its output to log_buf
and it will be visible in "dmesg", but that output will NOT be echoed to
the console until somebody calls release_console_sem() from a CPU that
is online.  Therefore, the boot time messages from the new CPU can get
stuck in "limbo" for a long time, and might suddenly appear on the
screen when a completely unrelated event (e.g. "eth0: link is down")
occurs.

This patch modifies the console code so that any pending messages are
automatically flushed out to the console whenever a CPU hotplug
operation completes successfully or aborts.

The issue was seen on 2.6.34.

Original patch by Kevin Cernekee with cleanups by akpm and additional fixes
by Santosh Shilimkar.  This patch superseeds
https://patchwork.linux-mips.org/patch/1357/.
Signed-off-by: NKevin Cernekee <cernekee@gmail.com>
To: <mingo@elte.hu>
To: <akpm@linux-foundation.org>
To: <simon.kagstrom@netinsight.net>
To: <David.Woodhouse@intel.com>
To: <lethal@linux-sh.org>
Cc: <linux-kernel@vger.kernel.org>
Cc: <linux-mips@linux-mips.org>
Reviewed-by: NPaul Mundt <lethal@linux-sh.org>
Signed-off-by: NKevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/1534/
LKML-Reference: <ede63b5a20af951c755736f035d1e787772d7c28@localhost>
LKML-Reference: <EAF47CD23C76F840A9E7FCE10091EFAB02C5DB6D1F@dbde02.ent.ti.com>
Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 d745866e
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <linux/kmsg_dump.h> #include <linux/kmsg_dump.h>
#include <linux/syslog.h> #include <linux/syslog.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -984,6 +986,32 @@ void resume_console(void) ...@@ -984,6 +986,32 @@ void resume_console(void)
release_console_sem(); release_console_sem();
} }
/**
* console_cpu_notify - print deferred console messages after CPU hotplug
* @self: notifier struct
* @action: CPU hotplug event
* @hcpu: unused
*
* If printk() is called from a CPU that is not online yet, the messages
* will be spooled but will not show up on the console. This function is
* called when a new CPU comes online (or fails to come up), and ensures
* that any such output gets printed.
*/
static int __cpuinit console_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
switch (action) {
case CPU_ONLINE:
case CPU_DEAD:
case CPU_DYING:
case CPU_DOWN_FAILED:
case CPU_UP_CANCELED:
acquire_console_sem();
release_console_sem();
}
return NOTIFY_OK;
}
/** /**
* acquire_console_sem - lock the console system for exclusive use. * acquire_console_sem - lock the console system for exclusive use.
* *
...@@ -1371,7 +1399,7 @@ int unregister_console(struct console *console) ...@@ -1371,7 +1399,7 @@ int unregister_console(struct console *console)
} }
EXPORT_SYMBOL(unregister_console); EXPORT_SYMBOL(unregister_console);
static int __init disable_boot_consoles(void) static int __init printk_late_init(void)
{ {
struct console *con; struct console *con;
...@@ -1382,9 +1410,10 @@ static int __init disable_boot_consoles(void) ...@@ -1382,9 +1410,10 @@ static int __init disable_boot_consoles(void)
unregister_console(con); unregister_console(con);
} }
} }
hotcpu_notifier(console_cpu_notify, 0);
return 0; return 0;
} }
late_initcall(disable_boot_consoles); late_initcall(printk_late_init);
#if defined CONFIG_PRINTK #if defined CONFIG_PRINTK
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册