diff mbox

Add OPAL_CONSOLE_FLUSH to the OPAL API

Message ID 1448258444-7362-1-git-send-email-ruscur@russell.cc
State Superseded
Headers show

Commit Message

Russell Currey Nov. 23, 2015, 6 a.m. UTC
uart consoles only flush output when polled.  The Linux kernel calls these
pollers frequently, except when in a panic state.  As such, panic messages
are not fully printed unless the system is configured to reboot after panic.

This patch adds a new call to the OPAL API to completely flush the buffer.
If the system has a uart console (i.e. BMC machines), it will fully flush
the buffer.  If not, this function will have no effect.  This will allow
the Linux kernel to ensure the panic message has been fully printed out.

Signed-off-by: Russell Currey <ruscur@russell.cc>
---
A patch to the Linux kernel to call this function while panicking will be
sent upstream shortly.  If this function is not defined (i.e. an older
Skiboot version), it will just call opal_poll_events a bunch of times.
---
 core/console.c                               |  1 +
 doc/opal-api/opal-console-read-write-1-2.txt | 16 +++++++++++++++-
 include/opal-api.h                           |  3 ++-
 3 files changed, 18 insertions(+), 2 deletions(-)

Comments

Stewart Smith Nov. 27, 2015, 7:16 a.m. UTC | #1
Russell Currey <ruscur@russell.cc> writes:
> uart consoles only flush output when polled.  The Linux kernel calls these
> pollers frequently, except when in a panic state.  As such, panic messages
> are not fully printed unless the system is configured to reboot after panic.
>
> This patch adds a new call to the OPAL API to completely flush the buffer.
> If the system has a uart console (i.e. BMC machines), it will fully flush
> the buffer.  If not, this function will have no effect.  This will allow
> the Linux kernel to ensure the panic message has been fully printed out.
>
> Signed-off-by: Russell Currey <ruscur@russell.cc>
> ---
> A patch to the Linux kernel to call this function while panicking will be
> sent upstream shortly.  If this function is not defined (i.e. an older
> Skiboot version), it will just call opal_poll_events a bunch of times.
> ---
>  core/console.c                               |  1 +
>  doc/opal-api/opal-console-read-write-1-2.txt | 16 +++++++++++++++-
>  include/opal-api.h                           |  3 ++-
>  3 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/core/console.c b/core/console.c
> index 1cee5da..9295d6c 100644
> --- a/core/console.c
> +++ b/core/console.c
> @@ -295,6 +295,7 @@ void flush_console_driver(void)
>  	if (con_driver && con_driver->flush != NULL)
>  		con_driver->flush();
>  }
> +opal_call(OPAL_CONSOLE_FLUSH, flush_console_driver, 0);

Current semantics of flush_console_driver are to block if needed while
things are flushed out. This is why we have async console flushing, so
that boot with a billion printfs going on doesn't take a huge amount of
time, and instead we only flush when we're about to shutdown or reboot.

Except that OPAL_CONSOLE_WRITE *does* flush the uart out.. so I think
this patch is okay....

Although I think we want to commit to the API being "if OPAL_BUSY is
returned, call again as the whole buffer is *not* yet flushed". As I
think that would leave us open to be being able to hook into the kernel
tty layer flush()ing mechanism in the future?

>  void set_console(struct con_ops *driver)
>  {
> diff --git a/doc/opal-api/opal-console-read-write-1-2.txt b/doc/opal-api/opal-console-read-write-1-2.txt
> index b8fbc12..97d0632 100644
> --- a/doc/opal-api/opal-console-read-write-1-2.txt
> +++ b/doc/opal-api/opal-console-read-write-1-2.txt
> @@ -1,11 +1,12 @@
>  OPAL Console calls
>  ------------------
>  
> -There are three OPAL calls relating to the OPAL console:
> +There are four OPAL calls relating to the OPAL console:
>  
>  #define OPAL_CONSOLE_WRITE			1
>  #define OPAL_CONSOLE_READ			2
>  #define OPAL_CONSOLE_WRITE_BUFFER_SPACE		25
> +#define OPAL_CONSOLE_FLUSH			117
>  
>  The OPAL console calls can support multiple consoles. Each console MUST
>  be represented in the device tree.
> @@ -64,3 +65,16 @@ Returns:
>  	OPAL_CLOSED
>  
>  Use OPAL_POLL_EVENTS for how to determine
> +
> +OPAL_CONSOLE_FLUSH
> +------------------
> +
> +Parameters:
> +	none

Should same paramter as OPAL_CONSOLE_READ/WRITE, which accepts a
term_number parameter. We may want a simple way to say "just the one
that's actually the OPAL console dammit" - maybe ~0 as term_number?

> +
> +Returns:
> +	none

Should return OPAL_SUCCESS and as mentioned above OPAL_BUSY if buffer
not completely flushed (actually... come to think of it, maybe
OPAL_PARTIAL is what we want there).

Even though OPAL_CONSOLE_WRITE is currently synchronous and all that,
let's not limit what we specify the API to be.
Russell Currey Nov. 30, 2015, 2:13 a.m. UTC | #2
On Fri, 2015-11-27 at 18:16 +1100, Stewart Smith wrote:
> Russell Currey <ruscur@russell.cc> writes:
> > uart consoles only flush output when polled.  The Linux kernel calls these
> > pollers frequently, except when in a panic state.  As such, panic messages
> > are not fully printed unless the system is configured to reboot after
> > panic.
> > 
> > This patch adds a new call to the OPAL API to completely flush the buffer.
> > If the system has a uart console (i.e. BMC machines), it will fully flush
> > the buffer.  If not, this function will have no effect.  This will allow
> > the Linux kernel to ensure the panic message has been fully printed out.
> > 
> > Signed-off-by: Russell Currey <ruscur@russell.cc>
> > ---
> > A patch to the Linux kernel to call this function while panicking will be
> > sent upstream shortly.  If this function is not defined (i.e. an older
> > Skiboot version), it will just call opal_poll_events a bunch of times.
> > ---
> >  core/console.c                               |  1 +
> >  doc/opal-api/opal-console-read-write-1-2.txt | 16 +++++++++++++++-
> >  include/opal-api.h                           |  3 ++-
> >  3 files changed, 18 insertions(+), 2 deletions(-)
> > 
> > diff --git a/core/console.c b/core/console.c
> > index 1cee5da..9295d6c 100644
> > --- a/core/console.c
> > +++ b/core/console.c
> > @@ -295,6 +295,7 @@ void flush_console_driver(void)
> >  	if (con_driver && con_driver->flush != NULL)
> >  		con_driver->flush();
> >  }
> > +opal_call(OPAL_CONSOLE_FLUSH, flush_console_driver, 0);
> 
> Current semantics of flush_console_driver are to block if needed while
> things are flushed out. This is why we have async console flushing, so
> that boot with a billion printfs going on doesn't take a huge amount of
> time, and instead we only flush when we're about to shutdown or reboot.
> 
> Except that OPAL_CONSOLE_WRITE *does* flush the uart out.. so I think
> this patch is okay....
> 
> Although I think we want to commit to the API being "if OPAL_BUSY is
> returned, call again as the whole buffer is *not* yet flushed". As I
> think that would leave us open to be being able to hook into the kernel
> tty layer flush()ing mechanism in the future?
> 
Is there a reason why any tty layer flushing mechanism couldn't hook into
opal_poll_events?  I suppose it's not purpose-built for flushing, but I 
don't fully understand how much else the pollers do.

I'll change it to be more asynchronous, anyway.
> >  void set_console(struct con_ops *driver)
> >  {
> > diff --git a/doc/opal-api/opal-console-read-write-1-2.txt b/doc/opal-
> > api/opal-console-read-write-1-2.txt
> > index b8fbc12..97d0632 100644
> > --- a/doc/opal-api/opal-console-read-write-1-2.txt
> > +++ b/doc/opal-api/opal-console-read-write-1-2.txt
> > @@ -1,11 +1,12 @@
> >  OPAL Console calls
> >  ------------------
> >  
> > -There are three OPAL calls relating to the OPAL console:
> > +There are four OPAL calls relating to the OPAL console:
> >  
> >  #define OPAL_CONSOLE_WRITE			1
> >  #define OPAL_CONSOLE_READ			2
> >  #define OPAL_CONSOLE_WRITE_BUFFER_SPACE		25
> > +#define OPAL_CONSOLE_FLUSH			117
> >  
> >  The OPAL console calls can support multiple consoles. Each console MUST
> >  be represented in the device tree.
> > @@ -64,3 +65,16 @@ Returns:
> >  	OPAL_CLOSED
> >  
> >  Use OPAL_POLL_EVENTS for how to determine
> > +
> > +OPAL_CONSOLE_FLUSH
> > +------------------
> > +
> > +Parameters:
> > +	none
> 
> Should same paramter as OPAL_CONSOLE_READ/WRITE, which accepts a
> term_number parameter. We may want a simple way to say "just the one
> that's actually the OPAL console dammit" - maybe ~0 as term_number?
> 
> > +
> > +Returns:
> > +	none
> 
> Should return OPAL_SUCCESS and as mentioned above OPAL_BUSY if buffer
> not completely flushed (actually... come to think of it, maybe
> OPAL_PARTIAL is what we want there).
> 
> Even though OPAL_CONSOLE_WRITE is currently synchronous and all that,
> let's not limit what we specify the API to be.
> 
Okay, so how about:

 - OPAL_PARAMETER if the term_number is invalid
 - OPAL_UNSUPPORTED if the console type doesn't support implement flush()
 - OPAL_BUSY if there's still more to flush
 - OPAL_SUCCESS if the buffer is now fully flushed

Cheers.
Stewart Smith Dec. 7, 2015, 1:07 a.m. UTC | #3
Russell Currey <ruscur@russell.cc> writes:
>> > +OPAL_CONSOLE_FLUSH
>> > +------------------
>> > +
>> > +Parameters:
>> > +	none
>> 
>> Should same paramter as OPAL_CONSOLE_READ/WRITE, which accepts a
>> term_number parameter. We may want a simple way to say "just the one
>> that's actually the OPAL console dammit" - maybe ~0 as term_number?
>> 
>> > +
>> > +Returns:
>> > +	none
>> 
>> Should return OPAL_SUCCESS and as mentioned above OPAL_BUSY if buffer
>> not completely flushed (actually... come to think of it, maybe
>> OPAL_PARTIAL is what we want there).
>> 
>> Even though OPAL_CONSOLE_WRITE is currently synchronous and all that,
>> let's not limit what we specify the API to be.
>> 
> Okay, so how about:
>
>  - OPAL_PARAMETER if the term_number is invalid
>  - OPAL_UNSUPPORTED if the console type doesn't support implement flush()
>  - OPAL_BUSY if there's still more to flush

OPAL_PARTIAL is probably what we want rather than BUSY (although maybe
BUSY if we can't flush anything, then in theory OS could just give up
waiting at some point - especially in the scenario when it does want to
reboot).

So let's have OPAL_BUSY when nothing was flushed, OPAL_PARTIAL when we
at least flushed something and are making forward progress.

>  - OPAL_SUCCESS if the buffer is now fully flushed
diff mbox

Patch

diff --git a/core/console.c b/core/console.c
index 1cee5da..9295d6c 100644
--- a/core/console.c
+++ b/core/console.c
@@ -295,6 +295,7 @@  void flush_console_driver(void)
 	if (con_driver && con_driver->flush != NULL)
 		con_driver->flush();
 }
+opal_call(OPAL_CONSOLE_FLUSH, flush_console_driver, 0);
 
 void set_console(struct con_ops *driver)
 {
diff --git a/doc/opal-api/opal-console-read-write-1-2.txt b/doc/opal-api/opal-console-read-write-1-2.txt
index b8fbc12..97d0632 100644
--- a/doc/opal-api/opal-console-read-write-1-2.txt
+++ b/doc/opal-api/opal-console-read-write-1-2.txt
@@ -1,11 +1,12 @@ 
 OPAL Console calls
 ------------------
 
-There are three OPAL calls relating to the OPAL console:
+There are four OPAL calls relating to the OPAL console:
 
 #define OPAL_CONSOLE_WRITE			1
 #define OPAL_CONSOLE_READ			2
 #define OPAL_CONSOLE_WRITE_BUFFER_SPACE		25
+#define OPAL_CONSOLE_FLUSH			117
 
 The OPAL console calls can support multiple consoles. Each console MUST
 be represented in the device tree.
@@ -64,3 +65,16 @@  Returns:
 	OPAL_CLOSED
 
 Use OPAL_POLL_EVENTS for how to determine
+
+OPAL_CONSOLE_FLUSH
+------------------
+
+Parameters:
+	none
+
+Returns:
+	none
+
+Completely flushes the console's output buffer. Currently only implemented
+for uart consoles that only flush output when polled, so that the kernel
+has a way to flush output when in a panic state.
diff --git a/include/opal-api.h b/include/opal-api.h
index 7a11fe8..369aa93 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -162,7 +162,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 */