Re: [PATCH 3/3] early_printk: Add simple serialization to early_vprintk()

From: Peter Zijlstra
Date: Tue Oct 18 2016 - 13:31:04 EST


On Tue, Oct 18, 2016 at 01:19:51PM -0400, Steven Rostedt wrote:
>
> hehe, I have the exact same patch for my -rt work.

> > +static int early_printk_cpu = -1;
> > +
> > static int early_vprintk(const char *fmt, va_list args)
> > {
> > + int n, cpu, old;
> > char buf[512];
> > +
> > + cpu = get_cpu();
> > + for (;;) {
> > + old = cmpxchg(&early_printk_cpu, -1, cpu);
> > + if (old == -1 || old == cpu)
> > + break;

Looking at this again, we really should not spin using cmpxchg(), that
thrashes the cacheline.

The below is slightly better spinning... then again, this isn't
performance code.

--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -376,10 +376,16 @@ static int early_vprintk(const char *fmt

cpu = get_cpu();
for (;;) {
- old = cmpxchg(&early_printk_cpu, -1, cpu);
- if (old == -1 || old == cpu)
+ old = READ_ONCE(early_printk_cpu);
+ if (old == cpu)
break;

+ if (old == -1) {
+ old = cmpxchg(&early_printk_cpu, -1, cpu);
+ if (old == -1 || old == cpu)
+ break;
+ }
+
cpu_relax();
}