[PATCH] powerpc/powernv: Add a kmsg_dumper that flushes console output on panic
Denis Kirjanov
kda at linux-powerpc.org
Wed Nov 25 05:19:50 AEDT 2015
On 11/24/15, Russell Currey <ruscur at russell.cc> wrote:
> On BMC machines, console output is controlled by the OPAL firmware and is
> only flushed when its pollers are called. When the kernel is in a panic
> state, it no longer calls these pollers and thus console output does not
> completely flush, causing some output from the panic to be lost.
>
> This patch adds a new kmsg_dumper which gets called at panic time to ensure
> panic output is not lost. It accomplishes this by calling
> OPAL_CONSOLE_FLUSH
> in the OPAL API, and if that is not available, the pollers are called enough
> times to (hopefully) completely flush the buffer.
>
> Signed-off-by: Russell Currey <ruscur at russell.cc>
Some minor nits below.
> ---
> A patch to add the preferred OPAL call for flushing the console buffer,
> OPAL_CONSOLE_FLUSH, was recently sent upstream to Skiboot. You can track
> its progress here: https://patchwork.ozlabs.org/patch/547379/
> ---
> arch/powerpc/include/asm/opal-api.h | 3 +-
> arch/powerpc/include/asm/opal.h | 3 ++
> arch/powerpc/platforms/powernv/Makefile | 1 +
> arch/powerpc/platforms/powernv/opal-kmsg.c | 70
> ++++++++++++++++++++++++++
> arch/powerpc/platforms/powernv/opal-wrappers.S | 1 +
> arch/powerpc/platforms/powernv/opal.c | 3 ++
> 6 files changed, 80 insertions(+), 1 deletion(-)
> create mode 100644 arch/powerpc/platforms/powernv/opal-kmsg.c
>
> diff --git a/arch/powerpc/include/asm/opal-api.h
> b/arch/powerpc/include/asm/opal-api.h
> index 8374afe..f8faaae 100644
> --- a/arch/powerpc/include/asm/opal-api.h
> +++ b/arch/powerpc/include/asm/opal-api.h
> @@ -157,7 +157,8 @@
> #define OPAL_LEDS_GET_INDICATOR 114
> #define OPAL_LEDS_SET_INDICATOR 115
> #define OPAL_CEC_REBOOT2 116
> -#define OPAL_LAST 116
> +#define OPAL_CONSOLE_FLUSH 117
> +#define OPAL_LAST 117
>
> /* Device tree flags */
>
> diff --git a/arch/powerpc/include/asm/opal.h
> b/arch/powerpc/include/asm/opal.h
> index 8001159..a5fd407 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -35,6 +35,7 @@ int64_t opal_console_read(int64_t term_number, __be64
> *length,
> uint8_t *buffer);
> int64_t opal_console_write_buffer_space(int64_t term_number,
> __be64 *length);
> +void opal_console_flush(void);
> int64_t opal_rtc_read(__be32 *year_month_day,
> __be64 *hour_minute_second_millisecond);
> int64_t opal_rtc_write(uint32_t year_month_day,
> @@ -262,6 +263,8 @@ extern int opal_resync_timebase(void);
>
> extern void opal_lpc_init(void);
>
> +extern void opal_kmsg_init(void);
> +
> extern int opal_event_request(unsigned int opal_event_nr);
>
> struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
> diff --git a/arch/powerpc/platforms/powernv/Makefile
> b/arch/powerpc/platforms/powernv/Makefile
> index 1c8cdb6..b9de7ef 100644
> --- a/arch/powerpc/platforms/powernv/Makefile
> +++ b/arch/powerpc/platforms/powernv/Makefile
> @@ -2,6 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o
> idle.o
> obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
> obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
> obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
> +obj-y += opal-kmsg.o
>
> obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o
> obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o
> diff --git a/arch/powerpc/platforms/powernv/opal-kmsg.c
> b/arch/powerpc/platforms/powernv/opal-kmsg.c
> new file mode 100644
> index 0000000..904f123
> --- /dev/null
> +++ b/arch/powerpc/platforms/powernv/opal-kmsg.c
> @@ -0,0 +1,70 @@
> +/*
> + * kmsg dumper that ensures the OPAL console fully flushes panic messages
> + *
> + * Author: Russell Currey <ruscur at russell.cc>
> + *
> + * Copyright 2015 IBM Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + */
> +
> +#include <linux/kmsg_dump.h>
> +
> +#include <asm/opal.h>
> +#include <asm/opal-api.h>
> +
> +/*
> + * Console output is controlled by OPAL firmware. The kernel regularly
> calls
> + * OPAL_POLL_EVENTS, which flushes some console output. In a panic state,
> + * however, the kernel no longer calls OPAL_POLL_EVENTS and the panic
> message
> + * may not be completely printed. This function does not actually dump the
> + * message, it just ensures that OPAL completely flushes the console
> buffer.
> + */
> +static void force_opal_console_flush(struct kmsg_dumper *dumper,
> + enum kmsg_dump_reason reason)
> +{
> + int i;
> +
> + /*
> + * Outside of a panic context the pollers will continue to run,
> + * so we don't need to do any special flushing.
> + */
> + if (reason != KMSG_DUMP_PANIC) {
> + return;
> + }
We don't need the brackets with one-line block
> +
> + if (opal_check_token(OPAL_CONSOLE_FLUSH)) {
> + opal_console_flush();
> + } else {
> + /*
> + * If OPAL_CONSOLE_FLUSH is not implemented in the firmware,
> + * the console can still be flushed by calling the polling
> + * function enough times to flush the buffer. We don't know
> + * how much output still needs to be flushed, but we can be
> + * generous since the kernel is in panic and doesn't need
> + * to do much else.
> + */
> + printk(KERN_NOTICE "opal: OPAL_CONSOLE_FLUSH missing.\n");
> + for (i = 0; i < 1024; i++) {
> + opal_poll_events(NULL);
> + }
> + }
> +}
> +
> +static struct kmsg_dumper opal_kmsg_dumper = {
> + .dump = force_opal_console_flush
> +};
> +
> +void __init opal_kmsg_init(void)
> +{
> + int rc;
> +
> + /* Add our dumper to the list */
> + rc = kmsg_dump_register(&opal_kmsg_dumper);
> + if (rc != 0) {
> + pr_err("opal: kmsg_dump_register failed; returned %d\n", rc);
> + }
ditto.
> +}
> diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S
> b/arch/powerpc/platforms/powernv/opal-wrappers.S
> index b7a464f..e45b88a 100644
> --- a/arch/powerpc/platforms/powernv/opal-wrappers.S
> +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
> @@ -301,3 +301,4 @@ OPAL_CALL(opal_flash_erase, OPAL_FLASH_ERASE);
> OPAL_CALL(opal_prd_msg, OPAL_PRD_MSG);
> OPAL_CALL(opal_leds_get_ind, OPAL_LEDS_GET_INDICATOR);
> OPAL_CALL(opal_leds_set_ind, OPAL_LEDS_SET_INDICATOR);
> +OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH);
> diff --git a/arch/powerpc/platforms/powernv/opal.c
> b/arch/powerpc/platforms/powernv/opal.c
> index 4296d55..a94a85c 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -758,6 +758,9 @@ static int __init opal_init(void)
> opal_pdev_init(opal_node, "ibm,opal-flash");
> opal_pdev_init(opal_node, "ibm,opal-prd");
>
> + /* Initialise OPAL kmsg dumper for flushing console on panic */
> + opal_kmsg_init();
> +
> return 0;
> }
> machine_subsys_initcall(powernv, opal_init);
> --
> 2.6.2
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
More information about the Linuxppc-dev
mailing list