[printk,v3,36/40] tty: serial: kgdboc: use console_list_lock for list traversal

Message ID 20221107141638.3790965-37-john.ogness@linutronix.de
State New
Headers
Series reduce console_lock scope |

Commit Message

John Ogness Nov. 7, 2022, 2:16 p.m. UTC
  configure_kgdboc() uses the console_lock for console list iteration. Use
the console_list_lock instead because list synchronization responsibility
will be removed from the console_lock in a later change.

The SRCU iterator could have been used here, but a later change will
relocate the locking of the console_list_lock to also provide
synchronization against register_console().

Note, the console_lock is still needed to serialize the device()
callback with other console operations.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/kgdboc.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
  

Comments

Daniel Thompson Nov. 9, 2022, 9:06 a.m. UTC | #1
On Mon, Nov 07, 2022 at 03:22:34PM +0106, John Ogness wrote:
> configure_kgdboc() uses the console_lock for console list iteration. Use
> the console_list_lock instead because list synchronization responsibility
> will be removed from the console_lock in a later change.
>
> The SRCU iterator could have been used here, but a later change will
> relocate the locking of the console_list_lock to also provide
> synchronization against register_console().
>
> Note, the console_lock is still needed to serialize the device()
> callback with other console operations.
>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/kgdboc.c | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
> index 5be381003e58..82b4b4d67823 100644
> --- a/drivers/tty/serial/kgdboc.c
> +++ b/drivers/tty/serial/kgdboc.c
> @@ -451,6 +463,7 @@ static void kgdboc_earlycon_pre_exp_handler(void)
>  {
>  	struct console *con;
>  	static bool already_warned;
> +	int cookie;
>
>  	if (already_warned)
>  		return;
> @@ -463,9 +476,14 @@ static void kgdboc_earlycon_pre_exp_handler(void)
>  	 * serial drivers might be OK with this, print a warning once per
>  	 * boot if we detect this case.
>  	 */
> -	for_each_console(con)
> +	cookie = console_srcu_read_lock();
> +	for_each_console_srcu(con) {
>  		if (con == kgdboc_earlycon_io_ops.cons)
> -			return;
> +			break;
> +	}
> +	console_srcu_read_unlock(cookie);
> +	if (con)
> +		return;

This change isn't mentioned in the patch description.


Daniel.
  
John Ogness Nov. 9, 2022, 9:44 a.m. UTC | #2
On 2022-11-09, Daniel Thompson <daniel.thompson@linaro.org> wrote:
>> @@ -463,9 +476,14 @@ static void kgdboc_earlycon_pre_exp_handler(void)
>>  	 * serial drivers might be OK with this, print a warning once per
>>  	 * boot if we detect this case.
>>  	 */
>> -	for_each_console(con)
>> +	cookie = console_srcu_read_lock();
>> +	for_each_console_srcu(con) {
>>  		if (con == kgdboc_earlycon_io_ops.cons)
>> -			return;
>> +			break;
>> +	}
>> +	console_srcu_read_unlock(cookie);
>> +	if (con)
>> +		return;
>
> This change isn't mentioned in the patch description.

I will move this change into its own separate patch.

    tty: serial: kgdboc: use srcu console list iterator

    Use srcu console list iteration for safe console list traversal.

Thanks.

John
  
Petr Mladek Nov. 10, 2022, 6 p.m. UTC | #3
On Wed 2022-11-09 10:50:43, John Ogness wrote:
> On 2022-11-09, Daniel Thompson <daniel.thompson@linaro.org> wrote:
> >> @@ -463,9 +476,14 @@ static void kgdboc_earlycon_pre_exp_handler(void)
> >>  	 * serial drivers might be OK with this, print a warning once per
> >>  	 * boot if we detect this case.
> >>  	 */
> >> -	for_each_console(con)
> >> +	cookie = console_srcu_read_lock();
> >> +	for_each_console_srcu(con) {
> >>  		if (con == kgdboc_earlycon_io_ops.cons)
> >> -			return;
> >> +			break;
> >> +	}
> >> +	console_srcu_read_unlock(cookie);
> >> +	if (con)
> >> +		return;
> >
> > This change isn't mentioned in the patch description.
> 
> I will move this change into its own separate patch.
> 
>     tty: serial: kgdboc: use srcu console list iterator
> 
>     Use srcu console list iteration for safe console list traversal.

Yes, split it please :-) Anyway, both changes look good to me.

Best Regards,
Petr
  

Patch

diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index 5be381003e58..82b4b4d67823 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -193,7 +193,16 @@  static int configure_kgdboc(void)
 	if (!p)
 		goto noconfig;
 
+	/* For safe traversal of the console list. */
+	console_list_lock();
+
+	/*
+	 * Take console_lock to serialize device() callback with
+	 * other console operations. For example, fg_console is
+	 * modified under console_lock when switching vt.
+	 */
 	console_lock();
+
 	for_each_console(cons) {
 		int idx;
 		if (cons->device && cons->device(cons, &idx) == p &&
@@ -202,8 +211,11 @@  static int configure_kgdboc(void)
 			break;
 		}
 	}
+
 	console_unlock();
 
+	console_list_unlock();
+
 	kgdb_tty_driver = p;
 	kgdb_tty_line = tty_line;
 
@@ -451,6 +463,7 @@  static void kgdboc_earlycon_pre_exp_handler(void)
 {
 	struct console *con;
 	static bool already_warned;
+	int cookie;
 
 	if (already_warned)
 		return;
@@ -463,9 +476,14 @@  static void kgdboc_earlycon_pre_exp_handler(void)
 	 * serial drivers might be OK with this, print a warning once per
 	 * boot if we detect this case.
 	 */
-	for_each_console(con)
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(con) {
 		if (con == kgdboc_earlycon_io_ops.cons)
-			return;
+			break;
+	}
+	console_srcu_read_unlock(cookie);
+	if (con)
+		return;
 
 	already_warned = true;
 	pr_warn("kgdboc_earlycon is still using bootconsole\n");