On Mon, Apr 04, 2016 at 01:52:06PM +0200, Jan Kara wrote: > Sounds like a good idea to me. I've also consulted this with Petr Mladek > (added to CC) who is using printk_func per-cpu variable in his > printk-from-NMI patches and he also doesn't see a problem with this. There's a few printk() variants that do not go through this; which means they're broken for a number of cases, including the kdb printk redirection, this NMI stuff etc. > I was just wondering about one thing - this way we add more early printks > if I understand your intention right. Are we guaranteed that they happen > only from a single CPU? Because currently there is no locking in > early_printk() and thus we can end up writing to early console several > messages in parallel from different CPUs. Not sure what's going to happen > in that case... You get lovely per char interleaving on you serial line ;-) What I've done in the past was something like the below; that way you only get the normal task->softirq->irq->nmi nesting, which is mostly decipherable. diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index bfbf284e4218..c4c3269ff104 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1907,17 +1907,36 @@ struct console *early_console; asmlinkage __visible void early_printk(const char *fmt, ...) { va_list ap; + static int print_cpu = -1; char buf[512]; - int n; + int n, cpu; if (!early_console) return; + preempt_disable(); + cpu = raw_smp_processor_id(); + for (;;) { + if (READ_ONCE(print_cpu) == cpu) + break; + + if (READ_ONCE(print_cpu) == -1 && + cmpxchg(&print_cpu, -1, cpu) == -1) { + cpu = -1; + break; + } + + cpu_relax(); + } + va_start(ap, fmt); n = vscnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); early_console->write(early_console, buf, n); + + smp_store_release(&print_cpu, cpu); + preempt_enable(); } #endif -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html