Message ID | 20221107141638.3790965-41-john.ogness@linutronix.de |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2079594wru; Mon, 7 Nov 2022 06:22:37 -0800 (PST) X-Google-Smtp-Source: AMsMyM67rVT+bLEA1Pac2t3941Qb/Pi/txhIPfABbSMpAxvlfowu6BAEzcMzjWs/LzWYcW2+5GJo X-Received: by 2002:a17:90a:6f83:b0:213:9e97:d5e1 with SMTP id e3-20020a17090a6f8300b002139e97d5e1mr53202476pjk.149.1667830956823; Mon, 07 Nov 2022 06:22:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1667830956; cv=none; d=google.com; s=arc-20160816; b=rYsThg7JIhVa+Fkvq5cZM/r18TgvYYdVx/Z3CdDzSIfBiCzZl49739Ttnf936FW1q4 DGOIht4QvBA4XKlrp3JJZV+DXwbxUqamaw5czpNmoyb3b3L57aoe50Ro5abVbbirFSgn /nCozQCa8E4H/clmkUpchtdVZk8hANqfFK10UCCsqYR01YjRJ3q6LPV3YUkJd3YKuFrO biqXqVuXslx1cSRilG5OvhuYFKsJerzNFS2WK5fk1vC9sgu9OLxo7xAIALCyV89Qb17S jHcOQHxQFco/IFkdJBmSjqH3FBUcGjeMyldOIEjk7TxmDbMG05NpZLq395o+ZKtrgzt1 drJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:dkim-signature :dkim-signature:from; bh=wOWHeHInm2fmU2wKM0mWh276PVpVVzC8ULssrB/joiM=; b=bcMDtYUPenZYWWIStUv/0NQzkx7xNSkxMrb8+7+lJ2osql3wsKldc+T3pdObEH3vTV CkI+zg10CMhtAEyJ2iJ+4jChvsm54o6YY0IDb+buPdBxev14thLYTyibBbWYcTtGJo5M jLtxLmerS4lNL/8ZUMBk4A39wVcGTKd8PlTFdEuuDAi2ucGxqwoLVF22AmCF4rziAL9Q greXWKcmgKS/rGP73nkc3NITlUCz6jLVwyCJ/frAVYwGAi7yWtYZ91KVp3SiV4Fx9wJC dWj84NCu/Su2W7YXmNv/0eRIj4B9EpN4ngRAmAeEOqnmoXZ9mHD1MKy8Zp58aLWpxN3K s5bA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="swwcC/ey"; dkim=neutral (no key) header.i=@linutronix.de header.b=XMu8M3iT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e6-20020a17090301c600b0018699a9ea71si11270111plh.18.2022.11.07.06.22.23; Mon, 07 Nov 2022 06:22:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="swwcC/ey"; dkim=neutral (no key) header.i=@linutronix.de header.b=XMu8M3iT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232469AbiKGOTg (ORCPT <rfc822;hjfbswb@gmail.com> + 99 others); Mon, 7 Nov 2022 09:19:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232313AbiKGOSB (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 7 Nov 2022 09:18:01 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10CD41D33D; Mon, 7 Nov 2022 06:17:00 -0800 (PST) From: John Ogness <john.ogness@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1667830618; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wOWHeHInm2fmU2wKM0mWh276PVpVVzC8ULssrB/joiM=; b=swwcC/eytgcMbEKzOsEncCun4WY7vCLbcSffYIRaqcjIVCgoqyAiB72Hq237ceNlyL5/yg IaBRPSjRNC+INjKqpcmmT7hw6GRutYGeymQnr6Ol54Fij7be5Jfsm1DMqRlgS5UuQl9Rvq kdDA0dnHuT7VyfDq9u5tURAAc7KWeGndsalFDzyw85DF2YnZXb09JJH4a9xoJEpkWVwyS8 9jeLeuqUOLHzlmT4uTJIGlq4oWnVJQX+g1TczTiRuFCoB5GfciO6IKmx3iBPLaJbghiv/i PLkKtR22cC0RUj+pZZuRVN6VNvOn/czOzbB7QmzT3PZHj15nJHjX9f2zg0usMA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1667830618; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wOWHeHInm2fmU2wKM0mWh276PVpVVzC8ULssrB/joiM=; b=XMu8M3iTA3yEquZZqVsUkXpN+6MK0GssBgVj2Cl5IKI6K2iL8N2eyBMcwztJY/whxe4NYQ BGYy6M/luah7T/Cg== To: Petr Mladek <pmladek@suse.com> Cc: Sergey Senozhatsky <senozhatsky@chromium.org>, Steven Rostedt <rostedt@goodmis.org>, Thomas Gleixner <tglx@linutronix.de>, linux-kernel@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jiri Slaby <jirislaby@kernel.org>, linux-serial@vger.kernel.org Subject: [PATCH printk v3 40/40] tty: serial: sh-sci: use setup() callback for early console Date: Mon, 7 Nov 2022 15:22:38 +0106 Message-Id: <20221107141638.3790965-41-john.ogness@linutronix.de> In-Reply-To: <20221107141638.3790965-1-john.ogness@linutronix.de> References: <20221107141638.3790965-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,INVALID_DATE_TZ_ABSURD, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748847513435395923?= X-GMAIL-MSGID: =?utf-8?q?1748847513435395923?= |
Series |
reduce console_lock scope
|
|
Commit Message
John Ogness
Nov. 7, 2022, 2:16 p.m. UTC
When setting up the early console, the setup() callback of the
regular console is used. It is called manually before registering
the early console instead of providing a setup() callback for the
early console. This is probably because the early setup needs a
different @options during the early stage.
The issue here is that the setup() callback is called without the
console_list_lock held and functions such as uart_set_options()
expect that.
Rather than manually calling the setup() function before registering,
provide an early console setup() callback that will use the different
early options. This ensures that the error checking, ordering, and
locking context when setting up the early console are correct.
Note that technically the current implementation works because it is
only used in early boot. And since the early console setup is
performed before registering, it cannot race with anything and thus
does not need any locking. However, longterm maintenance is easier
when drivers rely on the subsystem API rather than manually
implementing steps that could cause breakage in the future.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
drivers/tty/serial/sh-sci.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
Comments
Hi John, CC linux-sh (SH-specific code) CC linux-renesas-soc (JFYI) On Mon, Nov 7, 2022 at 3:20 PM John Ogness <john.ogness@linutronix.de> wrote: > When setting up the early console, the setup() callback of the > regular console is used. It is called manually before registering > the early console instead of providing a setup() callback for the > early console. This is probably because the early setup needs a > different @options during the early stage. > > The issue here is that the setup() callback is called without the > console_list_lock held and functions such as uart_set_options() > expect that. > > Rather than manually calling the setup() function before registering, > provide an early console setup() callback that will use the different > early options. This ensures that the error checking, ordering, and > locking context when setting up the early console are correct. > > Note that technically the current implementation works because it is > only used in early boot. And since the early console setup is > performed before registering, it cannot race with anything and thus > does not need any locking. However, longterm maintenance is easier > when drivers rely on the subsystem API rather than manually > implementing steps that could cause breakage in the future. > > Signed-off-by: John Ogness <john.ogness@linutronix.de> Thanks for your patch! > --- a/drivers/tty/serial/sh-sci.c > +++ b/drivers/tty/serial/sh-sci.c > @@ -3054,15 +3054,26 @@ static struct console serial_console = { > }; > > #ifdef CONFIG_SUPERH > +static char early_serial_buf[32]; > + > +static int early_serial_console_setup(struct console *co, char *options) > +{ > + WARN_ON(options); > + /* > + * Use @early_serial_buf because @options will always be > + * NULL at this early stage. > + */ > + return serial_console_setup(co, early_serial_buf); > +} > + > static struct console early_serial_console = { > .name = "early_ttySC", > .write = serial_console_write, > + .setup = early_serial_console_setup, > .flags = CON_PRINTBUFFER, > .index = -1, > }; > > -static char early_serial_buf[32]; > - > static int sci_probe_earlyprintk(struct platform_device *pdev) > { > const struct plat_sci_port *cfg = dev_get_platdata(&pdev->dev); > @@ -3074,8 +3085,6 @@ static int sci_probe_earlyprintk(struct platform_device *pdev) > > sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true); > > - serial_console_setup(&early_serial_console, early_serial_buf); > - > if (!strstr(early_serial_buf, "keep")) > early_serial_console.flags |= CON_BOOT; > > -- > 2.30.2 LGTM, so Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Ccing Bartosz who should be familiar with the early platform code. On Mon 2022-11-07 15:22:38, John Ogness wrote: > When setting up the early console, the setup() callback of the > regular console is used. It is called manually before registering > the early console instead of providing a setup() callback for the > early console. This is probably because the early setup needs a > different @options during the early stage. This last sentece makes a bit nervous ;-) I think that I understood it in the end, see below. > The issue here is that the setup() callback is called without the > console_list_lock held and functions such as uart_set_options() > expect that. > > Rather than manually calling the setup() function before registering, > provide an early console setup() callback that will use the different > early options. This ensures that the error checking, ordering, and > locking context when setting up the early console are correct. > > Note that technically the current implementation works because it is > only used in early boot. And since the early console setup is > performed before registering, it cannot race with anything and thus > does not need any locking. However, longterm maintenance is easier > when drivers rely on the subsystem API rather than manually > implementing steps that could cause breakage in the future. > > Signed-off-by: John Ogness <john.ogness@linutronix.de> > --- > drivers/tty/serial/sh-sci.c | 17 +++++++++++++---- > 1 file changed, 13 insertions(+), 4 deletions(-) > > diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c > index 62f773286d44..f3a1cfec757a 100644 > --- a/drivers/tty/serial/sh-sci.c > +++ b/drivers/tty/serial/sh-sci.c > @@ -3054,15 +3054,26 @@ static struct console serial_console = { > }; > > #ifdef CONFIG_SUPERH > +static char early_serial_buf[32]; > + > +static int early_serial_console_setup(struct console *co, char *options) > +{ > + WARN_ON(options); > + /* > + * Use @early_serial_buf because @options will always be > + * NULL at this early stage. > + */ The commit message says that we use @early_serial_buf because the early console probably needs another parameters. It suggests that @options might be for the later stage and we need to replace them there. Are we sure that this will always be NULL? Background: The console->setup() is called in two situations: 1. when the console is registered as the default console, see try_enable_default_console(). In this case, @options is really NULL. 2. when the console is preferred either via the commnadline, or device tree, or SPCR, see try_enable_preferred_console(). In this case, some real @options would be passed. From the code POV, the preferred consoles are added by calling add_preferred_console(). Now, it means that the WARN_ON() is correct only when this console is always registered before the preferred consoles are defined. I think that this is really the case. This console is actually registered via the "earlyprintk" parameter that is proceed by the arch-specific code before the preferred consoles are added the standard way via the kernel commandline. Note that "earlyprintk" and "earlycon" are two different parameters. "earlyprintk" normally initializes "early_console" that is called directly by early_printk(). It is used for super early debugging. These messages even do not end in the ring buffer. "earlycon" defines a "normal" console that is used by the standard printk(). They are later replaced by properly initialized console drivers that are in sysfs, ... Note that "earlycon" calls add_preferred_console() so that the @options are stored and passed from try_enable_preferred_console(). But "earlyprintk" does not call add_preferred_console() so we need this hack to store and pass the console options another way. > + return serial_console_setup(co, early_serial_buf); > +} > + So I would do something like: static int early_serial_console_setup(struct console *co, char *options) { /* * This early console is registered using earlyprintk= parameter * that does not call add_preferred_console(). The @options * are passed using a custom buffer. */ WARN_ON(options); return serial_console_setup(co, early_serial_buf); } Also we should explain this in the commit message. Best Regards, Petr
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 62f773286d44..f3a1cfec757a 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -3054,15 +3054,26 @@ static struct console serial_console = { }; #ifdef CONFIG_SUPERH +static char early_serial_buf[32]; + +static int early_serial_console_setup(struct console *co, char *options) +{ + WARN_ON(options); + /* + * Use @early_serial_buf because @options will always be + * NULL at this early stage. + */ + return serial_console_setup(co, early_serial_buf); +} + static struct console early_serial_console = { .name = "early_ttySC", .write = serial_console_write, + .setup = early_serial_console_setup, .flags = CON_PRINTBUFFER, .index = -1, }; -static char early_serial_buf[32]; - static int sci_probe_earlyprintk(struct platform_device *pdev) { const struct plat_sci_port *cfg = dev_get_platdata(&pdev->dev); @@ -3074,8 +3085,6 @@ static int sci_probe_earlyprintk(struct platform_device *pdev) sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true); - serial_console_setup(&early_serial_console, early_serial_buf); - if (!strstr(early_serial_buf, "keep")) early_serial_console.flags |= CON_BOOT;