All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Nicholas Piggin <npiggin@gmail.com>, linuxppc-dev@lists.ozlabs.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jslaby@suse.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 08/15] powerpc/powernv: implement opal_put_chars_atomic
Date: Tue, 01 May 2018 19:48:58 +1000	[thread overview]
Message-ID: <1525168138.2325.100.camel@kernel.crashing.org> (raw)
In-Reply-To: <20180430145558.4308-9-npiggin@gmail.com>

On Tue, 2018-05-01 at 00:55 +1000, Nicholas Piggin wrote:
> The RAW console does not need writes to be atomic, so relax
> opal_put_chars to be able to do partial writes, and implement an
> _atomic variant which does not take a spinlock. This API is used
> in xmon, so the less locking that is used, the better chance there
> is that a crash can be debugged.

Same comment I already had :-) "atomic" in Linux tends to mean
something else (ie, atomic context), so I'd rather have something
like opal_put_chars_sync() or such...

> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
>  arch/powerpc/include/asm/opal.h       |  1 +
>  arch/powerpc/platforms/powernv/opal.c | 37 +++++++++++++++++++--------
>  drivers/tty/hvc/hvc_opal.c            | 18 +++++++++----
>  3 files changed, 41 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index bbff49fab0e5..5d7072411561 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -303,6 +303,7 @@ extern void opal_configure_cores(void);
>  
>  extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
>  extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
> +extern int opal_put_chars_atomic(uint32_t vtermno, const char *buf, int total_len);
>  extern int opal_flush_console(uint32_t vtermno);
>  
>  extern void hvc_opal_init_early(void);
> diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> index 55d4b1983110..bcdb90ada938 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -344,9 +344,9 @@ int opal_get_chars(uint32_t vtermno, char *buf, int count)
>  	return 0;
>  }
>  
> -int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
> +static int __opal_put_chars(uint32_t vtermno, const char *data, int total_len, bool atomic)
>  {
> -	unsigned long flags;
> +	unsigned long flags = 0 /* shut up gcc */;
>  	int written;
>  	__be64 olen;
>  	s64 rc;
> @@ -354,11 +354,8 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
>  	if (!opal.entry)
>  		return -ENODEV;
>  
> -	/* We want put_chars to be atomic to avoid mangling of hvsi
> -	 * packets. To do that, we first test for room and return
> -	 * -EAGAIN if there isn't enough.
> -	 */
> -	spin_lock_irqsave(&opal_write_lock, flags);
> +	if (atomic)
> +		spin_lock_irqsave(&opal_write_lock, flags);
>  	rc = opal_console_write_buffer_space(vtermno, &olen);
>  	if (rc || be64_to_cpu(olen) < total_len) {
>  		/* Closed -> drop characters */
> @@ -391,14 +388,18 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
>  
>  	written = be64_to_cpu(olen);
>  	if (written < total_len) {
> -		/* Should not happen */
> -		pr_warn("atomic console write returned partial len=%d written=%d\n", total_len, written);
> +		if (atomic) {
> +			/* Should not happen */
> +			pr_warn("atomic console write returned partial "
> +				"len=%d written=%d\n", total_len, written);
> +		}
>  		if (!written)
>  			written = -EAGAIN;
>  	}
>  
>  out:
> -	spin_unlock_irqrestore(&opal_write_lock, flags);
> +	if (atomic)
> +		spin_unlock_irqrestore(&opal_write_lock, flags);
>  
>  	/* In the -EAGAIN case, callers loop, so we have to flush the console
>  	 * here in case they have interrupts off (and we don't want to wait
> @@ -412,6 +413,22 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
>  	return written;
>  }
>  
> +int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
> +{
> +	return __opal_put_chars(vtermno, data, total_len, false);
> +}
> +
> +/*
> + * opal_put_chars_atomic will not perform partial-writes. Data will be
> + * atomically written to the terminal or not at all. This is not strictly
> + * true at the moment because console space can race with OPAL's console
> + * writes.
> + */
> +int opal_put_chars_atomic(uint32_t vtermno, const char *data, int total_len)
> +{
> +	return __opal_put_chars(vtermno, data, total_len, true);
> +}
> +
>  int opal_flush_console(uint32_t vtermno)
>  {
>  	s64 rc;
> diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
> index af122ad7f06d..0a72f98ee082 100644
> --- a/drivers/tty/hvc/hvc_opal.c
> +++ b/drivers/tty/hvc/hvc_opal.c
> @@ -183,9 +183,15 @@ static int hvc_opal_probe(struct platform_device *dev)
>  			return -ENOMEM;
>  		pv->proto = proto;
>  		hvc_opal_privs[termno] = pv;
> -		if (proto == HV_PROTOCOL_HVSI)
> -			hvsilib_init(&pv->hvsi, opal_get_chars, opal_put_chars,
> +		if (proto == HV_PROTOCOL_HVSI) {
> +			/*
> +			 * We want put_chars to be atomic to avoid mangling of
> +			 * hvsi packets.
> +			 */
> +			hvsilib_init(&pv->hvsi,
> +				     opal_get_chars, opal_put_chars_atomic,
>  				     termno, 0);
> +		}
>  
>  		/* Instanciate now to establish a mapping index==vtermno */
>  		hvc_instantiate(termno, termno, ops);
> @@ -376,8 +382,9 @@ void __init hvc_opal_init_early(void)
>  	else if (of_device_is_compatible(stdout_node,"ibm,opal-console-hvsi")) {
>  		hvc_opal_boot_priv.proto = HV_PROTOCOL_HVSI;
>  		ops = &hvc_opal_hvsi_ops;
> -		hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars,
> -			     opal_put_chars, index, 1);
> +		hvsilib_init(&hvc_opal_boot_priv.hvsi,
> +			     opal_get_chars, opal_put_chars_atomic,
> +			     index, 1);
>  		/* HVSI, perform the handshake now */
>  		hvsilib_establish(&hvc_opal_boot_priv.hvsi);
>  		pr_devel("hvc_opal: Found HVSI console\n");
> @@ -409,7 +416,8 @@ void __init udbg_init_debug_opal_hvsi(void)
>  	hvc_opal_privs[index] = &hvc_opal_boot_priv;
>  	hvc_opal_boot_termno = index;
>  	udbg_init_opal_common();
> -	hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, opal_put_chars,
> +	hvsilib_init(&hvc_opal_boot_priv.hvsi,
> +		     opal_get_chars, opal_put_chars_atomic,
>  		     index, 1);
>  	hvsilib_establish(&hvc_opal_boot_priv.hvsi);
>  }

  reply	other threads:[~2018-05-01  9:48 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-30 14:55 [PATCH 00/15] hvc and powerpc opal console latency reduction Nicholas Piggin
2018-04-30 14:55 ` [PATCH 01/15] powerpc/powernv: opal_put_chars partial write fix Nicholas Piggin
2018-07-24 13:59   ` [01/15] " Michael Ellerman
2018-04-30 14:55 ` [PATCH 02/15] powerpc/powernv: Fix OPAL console driver OPAL_BUSY loops Nicholas Piggin
2018-04-30 14:55 ` [PATCH 03/15] powerpc/powernv: opal-kmsg standardise OPAL_BUSY handling Nicholas Piggin
2018-04-30 14:55 ` [PATCH 04/15] powerpc/powernv: opal-kmsg use flush fallback from console code Nicholas Piggin
2018-05-04  5:16   ` Michael Ellerman
2018-05-04  5:37     ` Nicholas Piggin
2018-05-07 10:36       ` Michael Ellerman
2018-05-08  3:40         ` Nicholas Piggin
2018-04-30 14:55 ` [PATCH 05/15] powerpc/powernv: Implement and use opal_flush_console Nicholas Piggin
2018-04-30 14:55 ` [PATCH 06/15] powerpc/powernv: Remove OPALv1 support from opal console driver Nicholas Piggin
2018-04-30 14:55 ` [PATCH 07/15] powerpc/powernv: move opal console flushing to udbg Nicholas Piggin
2018-04-30 14:55 ` [PATCH 08/15] powerpc/powernv: implement opal_put_chars_atomic Nicholas Piggin
2018-05-01  9:48   ` Benjamin Herrenschmidt [this message]
2018-05-01 10:37     ` Nicholas Piggin
2018-05-07 10:35       ` Michael Ellerman
2018-05-08  3:36         ` Nicholas Piggin
2018-04-30 14:55 ` [PATCH 09/15] tty: hvc: remove unexplained "just in case" spin delay Nicholas Piggin
2018-04-30 14:55 ` [PATCH 10/15] tty: hvc: use mutex instead of spinlock for hvc_structs lock Nicholas Piggin
2018-08-13 11:22   ` [10/15] " Michael Ellerman
2018-04-30 14:55 ` [PATCH 11/15] tty: hvc: hvc_poll break hv read loop Nicholas Piggin
2018-08-13 11:23   ` [11/15] " Michael Ellerman
2018-04-30 14:55 ` [PATCH 12/15] tty: hvc: hvc_poll may sleep Nicholas Piggin
2018-08-13 11:23   ` [12/15] " Michael Ellerman
2018-04-30 14:55 ` [PATCH 13/15] tty: hvc: hvc_write " Nicholas Piggin
2018-08-13 11:23   ` [13/15] " Michael Ellerman
2018-04-30 14:55 ` [PATCH 14/15] tty: hvc: introduce the hv_ops.flush operation for hvc drivers Nicholas Piggin
2018-08-13 11:23   ` [14/15] " Michael Ellerman
2018-04-30 14:55 ` [PATCH 15/15] powerpc/powernv: provide a console flush operation for opal hvc driver Nicholas Piggin
2018-08-21 10:35   ` [15/15] " Michael Ellerman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1525168138.2325.100.camel@kernel.crashing.org \
    --to=benh@kernel.crashing.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=npiggin@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.