Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 29696
b: refs/heads/master
c: 76a8ad2
h: refs/heads/master
v: v3
  • Loading branch information
Michael Ellerman authored and Linus Torvalds committed Jun 25, 2006
1 parent 149aa9b commit e9ff8e6
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8ae6e163c1b637e1cb125613726ffbd31ca44fdf
refs/heads/master: 76a8ad293912cd2f01eca075d80cd0ddec30c627
1 change: 1 addition & 0 deletions trunk/include/linux/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ void give_up_console(const struct consw *sw);
#define CON_CONSDEV (2) /* Last on the command line */
#define CON_ENABLED (4)
#define CON_BOOT (8)
#define CON_ANYTIME (16) /* Safe to call when cpu is offline */

struct console
{
Expand Down
50 changes: 33 additions & 17 deletions trunk/kernel/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,9 @@ static void __call_console_drivers(unsigned long start, unsigned long end)
struct console *con;

for (con = console_drivers; con; con = con->next) {
if ((con->flags & CON_ENABLED) && con->write)
if ((con->flags & CON_ENABLED) && con->write &&
(cpu_online(smp_processor_id()) ||
(con->flags & CON_ANYTIME)))
con->write(con, &LOG_BUF(start), end - start);
}
}
Expand Down Expand Up @@ -453,6 +455,18 @@ __attribute__((weak)) unsigned long long printk_clock(void)
return sched_clock();
}

/* Check if we have any console registered that can be called early in boot. */
static int have_callable_console(void)
{
struct console *con;

for (con = console_drivers; con; con = con->next)
if (con->flags & CON_ANYTIME)
return 1;

return 0;
}

/**
* printk - print a kernel message
* @fmt: format string
Expand Down Expand Up @@ -566,27 +580,29 @@ asmlinkage int vprintk(const char *fmt, va_list args)
log_level_unknown = 1;
}

if (!cpu_online(smp_processor_id())) {
if (!down_trylock(&console_sem)) {
/*
* Some console drivers may assume that per-cpu resources have
* been allocated. So don't allow them to be called by this
* CPU until it is officially up. We shouldn't be calling into
* random console drivers on a CPU which doesn't exist yet..
* We own the drivers. We can drop the spinlock and
* let release_console_sem() print the text, maybe ...
*/
console_locked = 1;
printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
goto out;
}
if (!down_trylock(&console_sem)) {
console_locked = 1;

/*
* We own the drivers. We can drop the spinlock and let
* release_console_sem() print the text
* Console drivers may assume that per-cpu resources have
* been allocated. So unless they're explicitly marked as
* being able to cope (CON_ANYTIME) don't call them until
* this CPU is officially up.
*/
printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
console_may_schedule = 0;
release_console_sem();
if (cpu_online(smp_processor_id()) || have_callable_console()) {
console_may_schedule = 0;
release_console_sem();
} else {
/* Release by hand to avoid flushing the buffer. */
console_locked = 0;
up(&console_sem);
}
} else {
/*
* Someone else owns the drivers. We drop the spinlock, which
Expand All @@ -596,7 +612,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
}
out:

preempt_enable();
return printed_len;
}
Expand Down

0 comments on commit e9ff8e6

Please sign in to comment.