On Wed, Jun 10, 2015 at 09:23:04PM +0200, Peter Zijlstra wrote:
> +static int vprintk_nmi(const char *fmt, va_list args)
> +{
> +     struct nmi_seq_buf *s = this_cpu_ptr(&nmi_print_seq);
> +     int add = -1, len;
> +
> +     irq_work_queue(&s->work);
> +
> +     /*
> +      * head > tail; indicates someone is writing.
> +      * avoids the buffer being truncated.
> +      *
> +      * we rely on the memory barrier to ensure the increment
> +      * is visible before we start writing to the buffer.
> +      */
> +     len = atomic_inc_return(&s->head);

That wants to be:

        len = atomic_inc_return(&s->head) - 1;

we need the value before the increment, not after it.

> +
> +     if (len < sizeof(s->buffer)) {
> +             add = vsnprintf(s->buffer + len, sizeof(s->buffer) - len, fmt, 
> args);
> +             /*
> +              * Fwd head to the right location; NMIs do not nest, therefore
> +              * we can use regular stores.
> +              */
> +             atomic_set(&s->head, len + add);
> +             /*
> +              * Once the data is written and head is correct, update tail to
> +              * match; indicating we're complete.
> +              */
> +             smp_wmb();
> +             atomic_set(&s->tail, len + add);
> +     }
> +
> +     return add;
> +}
--
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/

Reply via email to