All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH printk v2 00/38] reduce console_lock scope
@ 2022-10-19 14:55 ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Paul E. McKenney, Daniel Thompson,
	Douglas Anderson, Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport,
	linux-serial, linux-fsdevel, Miguel Ojeda, Geert Uytterhoeven,
	linux-m68k, Richard Weinberger, Anton Ivanov, Johannes Berg,
	linux-um, Ard Biesheuvel, linux-efi, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Shile Zhang,
	Xianting Tian, linuxppc-dev, Krzysztof Kozlowski, Alim Akhtar,
	linux-arm-kernel, linux-samsung-soc, Michal Simek,
	Peter Zijlstra, Mike Rapoport, Mathias Nyman, Andrew Morton,
	linux-usb, Luis Chamberlain, Aaron Tomlin, Helge Deller,
	Thomas Zimmermann, Javier Martinez Canillas, Boris Ostrovsky,
	Juergen Gross, Tom Rix, linux-fbdev, dri-devel

This is v2 of a series to prepare for threaded/atomic
printing. It is a rework of patches 6-12 of the v1 [0]. From
the v1, patches 1-5 are already mainline and a rework of
patches >12 will be posted in a later series.

This series focuses on reducing the scope of the BKL
console_lock. It achieves this by switching to SRCU and a
dedicated mutex for console list iteration and modification,
respectively. The console_lock will no longer offer this
protection and is completely removed from
(un)register_console() and console_stop/start() code.

All users of the console_lock for list iteration have been
modified. For the call sites where the console_lock is still
needed (because of other reasons), I added comments to explain
exactly why the console_lock was needed.

The base commit for this series is from Paul McKenney's RCU tree
and provides an NMI-safe SRCU implementation [1]. Without the
NMI-safe SRCU implementation, this series is not less safe than
mainline. But we will need the NMI-safe SRCU implementation for
atomic consoles anyway, so we might as well get it in
now. Especially since it _does_ increase the reliability for
mainline in the panic path.

Changes since v2:

general:

- introduce console_is_enabled() to document safe data race on
  console->flags

- switch all "console->flags & CON_ENABLED" code sites to
  console_is_enabled()

- add "for_each_console_srcu" to .clang-format

- cleanup/clarify comments relating to console_lock
  coverage/usage

um:

- kmsg_dumper: use srcu instead of console_lock for list
  iteration

kgdb/kdb:

- configure_kgdboc: keep console_lock for console->device()
  synchronization, use srcu for list iteration

- kgdboc_earlycon_pre_exp_handler: use srcu instead of
  documenting unsafety for list iteration

- kgdboc_earlycon_init: use console_list_lock instead of
  console_lock to lock list

- kdb_msg_write: use srcu instead of documenting unsafety for
  list iteration

tty:

- show_cons_active: keep console_lock for console->device()
  synchronization

fbdev:

- xen-fbfront: xenfb_probe: use srcu instead of console_lock
  for list iteration, introduce console_force_preferred() to
  safely implement hack

proc/consoles:

- show_console_dev: keep console_lock for console->device()
  synchronization

- c_next: use hlist_entry_safe() instead of
  hlist_for_each_entry_continue()

printk:

- remove console_lock from console_stop/start() and
  (un)register_console()

- introduce console_srcu_read_(un)lock() to wrap scru read
  (un)lock

- rename cons_first() macro to console_first()

- for_each_console: add lockdep check instead of introducing
  new for_each_registered_console()

- console_list_lock: add warning if in read-side critical
  section

- release srcu read lock on handover

- console_flush_all: use srcu instead of relying on console
  lock for list iteration

- console_unblank: use srcu instead of relying on console_lock
  for list iteration

- console_flush_on_panic: use srcu for list iteration and
  document console->seq race

- device: keep console_lock for console->device()
  synchronization, usr srcu for list iteration

- register_console: split list adding logic into the 3 distinct
  scenarios

- register_console: set initial sequence number before adding
  to list

- unregister_console: fix ENODEV return value if the console is
  not registered

- console_stop: synchronize srcu

- printk_late_init: use _safe variant of iteration

- __pr_flush: use srcu instead of relying on console_lock for
  list iteration

John Ogness

[0] https://lore.kernel.org/r/20220924000454.3319186-1-john.ogness@linutronix.de
[1] https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/log/?h=srcunmisafe.2022.10.18b

John Ogness (37):
  printk: Convert console_drivers list to hlist
  printk: Prepare for SRCU console list protection
  printk: introduce console_is_enabled() wrapper
  printk: use console_is_enabled()
  tty: nfcon: use console_is_enabled()
  um: kmsg_dump: use console_is_enabled()
  efi: earlycon: use console_is_enabled()
  netconsole: use console_is_enabled()
  tty: hvc: use console_is_enabled()
  tty: serial: earlycon: use console_is_enabled()
  tty: serial: kgdboc: use console_is_enabled()
  tty: serial: pic32_uart: use console_is_enabled()
  tty: serial: samsung_tty: use console_is_enabled()
  tty: serial: serial_core: use console_is_enabled()
  tty: serial: xilinx_uartps: use console_is_enabled()
  tty: tty_io: use console_is_enabled()
  usb: early: xhci-dbc: use console_is_enabled()
  kdb: kdb_io: use console_is_enabled()
  um: kmsg_dumper: use srcu console list iterator
  serial: kgdboc: use srcu console list iterator
  serial: kgdboc: document console_lock usage
  tty: tty_io: document console_lock usage
  xen: fbfront: use srcu console list iterator
  proc: consoles: document console_lock usage
  kdb: use srcu console list iterator
  printk: console_flush_all: use srcu console list iterator
  printk: console_unblank: use srcu console list iterator
  printk: console_flush_on_panic: use srcu console list iterator
  printk: console_device: use srcu console list iterator
  printk: register_console: use srcu console list iterator
  printk: __pr_flush: use srcu console list iterator
  printk: introduce console_list_lock
  serial: kgdboc: use console_list_lock instead of console_lock
  tty: tty_io: use console_list_lock for list synchronization
  proc: consoles: use console_list_lock for list iteration
  printk: relieve console_lock of list synchronization duties
  printk, xen: fbfront: create/use safe function for forcing preferred

Thomas Gleixner (1):
  serial: kgdboc: Lock console list in probe function

 .clang-format                      |   1 +
 arch/m68k/emu/nfcon.c              |   4 +-
 arch/um/kernel/kmsg_dump.c         |  15 +-
 drivers/firmware/efi/earlycon.c    |   4 +-
 drivers/net/netconsole.c           |   4 +-
 drivers/tty/hvc/hvc_console.c      |   2 +-
 drivers/tty/serial/earlycon.c      |   4 +-
 drivers/tty/serial/kgdboc.c        |  37 ++-
 drivers/tty/serial/pic32_uart.c    |   2 +-
 drivers/tty/serial/samsung_tty.c   |   2 +-
 drivers/tty/serial/serial_core.c   |   2 +-
 drivers/tty/serial/xilinx_uartps.c |   2 +-
 drivers/tty/tty_io.c               |  18 +-
 drivers/usb/early/xhci-dbc.c       |   2 +-
 drivers/video/fbdev/xen-fbfront.c  |  16 +-
 fs/proc/consoles.c                 |  20 +-
 include/linux/console.h            |  75 +++++-
 include/linux/serial_core.h        |   2 +-
 kernel/debug/kdb/kdb_io.c          |   7 +-
 kernel/printk/printk.c             | 373 +++++++++++++++++++++--------
 20 files changed, 438 insertions(+), 154 deletions(-)


base-commit: c2d158a284abd63d727dad7402a2eed650dd4233
-- 
2.30.2


^ permalink raw reply	[flat|nested] 151+ messages in thread

* [PATCH printk v2 00/38] reduce console_lock scope
@ 2022-10-19 14:55 ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: linux-fbdev, linux-efi, Peter Zijlstra, kgdb-bugreport,
	dri-devel, Douglas Anderson, Eric Dumazet, netdev,
	Luis Chamberlain, Alim Akhtar, Jiri Slaby, Ard Biesheuvel,
	Anton Ivanov, Daniel Thompson, linux-samsung-soc, Tom Rix,
	Xianting Tian, Richard Weinberger, Helge Deller, Michal Simek,
	Geert Uytterhoeven, linux-serial, Aaron Tomlin, Miguel Ojeda,
	Jakub Kicinski, Paolo Abeni, Juergen Gross, Paul E. McKenney,
	Shile Zhang, linux-um, Steven Rostedt, linux-m68k,
	Thomas Gleixner, Andrew Morton, linux-arm-kernel,
	Boris Ostrovsky, Mathias Nyman, Greg Kroah-Hartman, linux-usb,
	linux-kernel, Sergey Senozhatsky, Krzysztof Kozlowski,
	Thomas Zimmermann, Jason Wessel, linux-fsdevel,
	Javier Martinez Canillas, Johannes Berg, linuxppc-dev,
	David S. Miller, Mike Rapoport

This is v2 of a series to prepare for threaded/atomic
printing. It is a rework of patches 6-12 of the v1 [0]. From
the v1, patches 1-5 are already mainline and a rework of
patches >12 will be posted in a later series.

This series focuses on reducing the scope of the BKL
console_lock. It achieves this by switching to SRCU and a
dedicated mutex for console list iteration and modification,
respectively. The console_lock will no longer offer this
protection and is completely removed from
(un)register_console() and console_stop/start() code.

All users of the console_lock for list iteration have been
modified. For the call sites where the console_lock is still
needed (because of other reasons), I added comments to explain
exactly why the console_lock was needed.

The base commit for this series is from Paul McKenney's RCU tree
and provides an NMI-safe SRCU implementation [1]. Without the
NMI-safe SRCU implementation, this series is not less safe than
mainline. But we will need the NMI-safe SRCU implementation for
atomic consoles anyway, so we might as well get it in
now. Especially since it _does_ increase the reliability for
mainline in the panic path.

Changes since v2:

general:

- introduce console_is_enabled() to document safe data race on
  console->flags

- switch all "console->flags & CON_ENABLED" code sites to
  console_is_enabled()

- add "for_each_console_srcu" to .clang-format

- cleanup/clarify comments relating to console_lock
  coverage/usage

um:

- kmsg_dumper: use srcu instead of console_lock for list
  iteration

kgdb/kdb:

- configure_kgdboc: keep console_lock for console->device()
  synchronization, use srcu for list iteration

- kgdboc_earlycon_pre_exp_handler: use srcu instead of
  documenting unsafety for list iteration

- kgdboc_earlycon_init: use console_list_lock instead of
  console_lock to lock list

- kdb_msg_write: use srcu instead of documenting unsafety for
  list iteration

tty:

- show_cons_active: keep console_lock for console->device()
  synchronization

fbdev:

- xen-fbfront: xenfb_probe: use srcu instead of console_lock
  for list iteration, introduce console_force_preferred() to
  safely implement hack

proc/consoles:

- show_console_dev: keep console_lock for console->device()
  synchronization

- c_next: use hlist_entry_safe() instead of
  hlist_for_each_entry_continue()

printk:

- remove console_lock from console_stop/start() and
  (un)register_console()

- introduce console_srcu_read_(un)lock() to wrap scru read
  (un)lock

- rename cons_first() macro to console_first()

- for_each_console: add lockdep check instead of introducing
  new for_each_registered_console()

- console_list_lock: add warning if in read-side critical
  section

- release srcu read lock on handover

- console_flush_all: use srcu instead of relying on console
  lock for list iteration

- console_unblank: use srcu instead of relying on console_lock
  for list iteration

- console_flush_on_panic: use srcu for list iteration and
  document console->seq race

- device: keep console_lock for console->device()
  synchronization, usr srcu for list iteration

- register_console: split list adding logic into the 3 distinct
  scenarios

- register_console: set initial sequence number before adding
  to list

- unregister_console: fix ENODEV return value if the console is
  not registered

- console_stop: synchronize srcu

- printk_late_init: use _safe variant of iteration

- __pr_flush: use srcu instead of relying on console_lock for
  list iteration

John Ogness

[0] https://lore.kernel.org/r/20220924000454.3319186-1-john.ogness@linutronix.de
[1] https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/log/?h=srcunmisafe.2022.10.18b

John Ogness (37):
  printk: Convert console_drivers list to hlist
  printk: Prepare for SRCU console list protection
  printk: introduce console_is_enabled() wrapper
  printk: use console_is_enabled()
  tty: nfcon: use console_is_enabled()
  um: kmsg_dump: use console_is_enabled()
  efi: earlycon: use console_is_enabled()
  netconsole: use console_is_enabled()
  tty: hvc: use console_is_enabled()
  tty: serial: earlycon: use console_is_enabled()
  tty: serial: kgdboc: use console_is_enabled()
  tty: serial: pic32_uart: use console_is_enabled()
  tty: serial: samsung_tty: use console_is_enabled()
  tty: serial: serial_core: use console_is_enabled()
  tty: serial: xilinx_uartps: use console_is_enabled()
  tty: tty_io: use console_is_enabled()
  usb: early: xhci-dbc: use console_is_enabled()
  kdb: kdb_io: use console_is_enabled()
  um: kmsg_dumper: use srcu console list iterator
  serial: kgdboc: use srcu console list iterator
  serial: kgdboc: document console_lock usage
  tty: tty_io: document console_lock usage
  xen: fbfront: use srcu console list iterator
  proc: consoles: document console_lock usage
  kdb: use srcu console list iterator
  printk: console_flush_all: use srcu console list iterator
  printk: console_unblank: use srcu console list iterator
  printk: console_flush_on_panic: use srcu console list iterator
  printk: console_device: use srcu console list iterator
  printk: register_console: use srcu console list iterator
  printk: __pr_flush: use srcu console list iterator
  printk: introduce console_list_lock
  serial: kgdboc: use console_list_lock instead of console_lock
  tty: tty_io: use console_list_lock for list synchronization
  proc: consoles: use console_list_lock for list iteration
  printk: relieve console_lock of list synchronization duties
  printk, xen: fbfront: create/use safe function for forcing preferred

Thomas Gleixner (1):
  serial: kgdboc: Lock console list in probe function

 .clang-format                      |   1 +
 arch/m68k/emu/nfcon.c              |   4 +-
 arch/um/kernel/kmsg_dump.c         |  15 +-
 drivers/firmware/efi/earlycon.c    |   4 +-
 drivers/net/netconsole.c           |   4 +-
 drivers/tty/hvc/hvc_console.c      |   2 +-
 drivers/tty/serial/earlycon.c      |   4 +-
 drivers/tty/serial/kgdboc.c        |  37 ++-
 drivers/tty/serial/pic32_uart.c    |   2 +-
 drivers/tty/serial/samsung_tty.c   |   2 +-
 drivers/tty/serial/serial_core.c   |   2 +-
 drivers/tty/serial/xilinx_uartps.c |   2 +-
 drivers/tty/tty_io.c               |  18 +-
 drivers/usb/early/xhci-dbc.c       |   2 +-
 drivers/video/fbdev/xen-fbfront.c  |  16 +-
 fs/proc/consoles.c                 |  20 +-
 include/linux/console.h            |  75 +++++-
 include/linux/serial_core.h        |   2 +-
 kernel/debug/kdb/kdb_io.c          |   7 +-
 kernel/printk/printk.c             | 373 +++++++++++++++++++++--------
 20 files changed, 438 insertions(+), 154 deletions(-)


base-commit: c2d158a284abd63d727dad7402a2eed650dd4233
-- 
2.30.2


^ permalink raw reply	[flat|nested] 151+ messages in thread

* [PATCH printk v2 00/38] reduce console_lock scope
@ 2022-10-19 14:55 ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: linux-fbdev, linux-efi, Peter Zijlstra, kgdb-bugreport,
	dri-devel, Douglas Anderson, Eric Dumazet, netdev,
	Luis Chamberlain, Alim Akhtar, Jiri Slaby, Ard Biesheuvel,
	Anton Ivanov, Daniel Thompson, linux-samsung-soc, Tom Rix,
	Xianting Tian, Richard Weinberger, Helge Deller, Michal Simek,
	Geert Uytterhoeven, linux-serial, Aaron Tomlin, Miguel Ojeda,
	Jakub Kicinski, Paolo Abeni, Juergen Gross, Paul E. McKenney,
	Shile Zhang, linux-um, Steven Rostedt, linux-m68k,
	Thomas Gleixner, Andrew Morton, linux-arm-kernel,
	Boris Ostrovsky, Mathias Nyman, Greg Kroah-Hartman, linux-usb,
	linux-kernel, Sergey Senozhatsky, Krzysztof Kozlowski,
	Thomas Zimmermann, Jason Wessel, linux-fsdevel,
	Javier Martinez Canillas, Johannes Berg, linuxppc-dev,
	David S. Miller, Mike Rapoport

This is v2 of a series to prepare for threaded/atomic
printing. It is a rework of patches 6-12 of the v1 [0]. From
the v1, patches 1-5 are already mainline and a rework of
patches >12 will be posted in a later series.

This series focuses on reducing the scope of the BKL
console_lock. It achieves this by switching to SRCU and a
dedicated mutex for console list iteration and modification,
respectively. The console_lock will no longer offer this
protection and is completely removed from
(un)register_console() and console_stop/start() code.

All users of the console_lock for list iteration have been
modified. For the call sites where the console_lock is still
needed (because of other reasons), I added comments to explain
exactly why the console_lock was needed.

The base commit for this series is from Paul McKenney's RCU tree
and provides an NMI-safe SRCU implementation [1]. Without the
NMI-safe SRCU implementation, this series is not less safe than
mainline. But we will need the NMI-safe SRCU implementation for
atomic consoles anyway, so we might as well get it in
now. Especially since it _does_ increase the reliability for
mainline in the panic path.

Changes since v2:

general:

- introduce console_is_enabled() to document safe data race on
  console->flags

- switch all "console->flags & CON_ENABLED" code sites to
  console_is_enabled()

- add "for_each_console_srcu" to .clang-format

- cleanup/clarify comments relating to console_lock
  coverage/usage

um:

- kmsg_dumper: use srcu instead of console_lock for list
  iteration

kgdb/kdb:

- configure_kgdboc: keep console_lock for console->device()
  synchronization, use srcu for list iteration

- kgdboc_earlycon_pre_exp_handler: use srcu instead of
  documenting unsafety for list iteration

- kgdboc_earlycon_init: use console_list_lock instead of
  console_lock to lock list

- kdb_msg_write: use srcu instead of documenting unsafety for
  list iteration

tty:

- show_cons_active: keep console_lock for console->device()
  synchronization

fbdev:

- xen-fbfront: xenfb_probe: use srcu instead of console_lock
  for list iteration, introduce console_force_preferred() to
  safely implement hack

proc/consoles:

- show_console_dev: keep console_lock for console->device()
  synchronization

- c_next: use hlist_entry_safe() instead of
  hlist_for_each_entry_continue()

printk:

- remove console_lock from console_stop/start() and
  (un)register_console()

- introduce console_srcu_read_(un)lock() to wrap scru read
  (un)lock

- rename cons_first() macro to console_first()

- for_each_console: add lockdep check instead of introducing
  new for_each_registered_console()

- console_list_lock: add warning if in read-side critical
  section

- release srcu read lock on handover

- console_flush_all: use srcu instead of relying on console
  lock for list iteration

- console_unblank: use srcu instead of relying on console_lock
  for list iteration

- console_flush_on_panic: use srcu for list iteration and
  document console->seq race

- device: keep console_lock for console->device()
  synchronization, usr srcu for list iteration

- register_console: split list adding logic into the 3 distinct
  scenarios

- register_console: set initial sequence number before adding
  to list

- unregister_console: fix ENODEV return value if the console is
  not registered

- console_stop: synchronize srcu

- printk_late_init: use _safe variant of iteration

- __pr_flush: use srcu instead of relying on console_lock for
  list iteration

John Ogness

[0] https://lore.kernel.org/r/20220924000454.3319186-1-john.ogness@linutronix.de
[1] https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/log/?h=srcunmisafe.2022.10.18b

John Ogness (37):
  printk: Convert console_drivers list to hlist
  printk: Prepare for SRCU console list protection
  printk: introduce console_is_enabled() wrapper
  printk: use console_is_enabled()
  tty: nfcon: use console_is_enabled()
  um: kmsg_dump: use console_is_enabled()
  efi: earlycon: use console_is_enabled()
  netconsole: use console_is_enabled()
  tty: hvc: use console_is_enabled()
  tty: serial: earlycon: use console_is_enabled()
  tty: serial: kgdboc: use console_is_enabled()
  tty: serial: pic32_uart: use console_is_enabled()
  tty: serial: samsung_tty: use console_is_enabled()
  tty: serial: serial_core: use console_is_enabled()
  tty: serial: xilinx_uartps: use console_is_enabled()
  tty: tty_io: use console_is_enabled()
  usb: early: xhci-dbc: use console_is_enabled()
  kdb: kdb_io: use console_is_enabled()
  um: kmsg_dumper: use srcu console list iterator
  serial: kgdboc: use srcu console list iterator
  serial: kgdboc: document console_lock usage
  tty: tty_io: document console_lock usage
  xen: fbfront: use srcu console list iterator
  proc: consoles: document console_lock usage
  kdb: use srcu console list iterator
  printk: console_flush_all: use srcu console list iterator
  printk: console_unblank: use srcu console list iterator
  printk: console_flush_on_panic: use srcu console list iterator
  printk: console_device: use srcu console list iterator
  printk: register_console: use srcu console list iterator
  printk: __pr_flush: use srcu console list iterator
  printk: introduce console_list_lock
  serial: kgdboc: use console_list_lock instead of console_lock
  tty: tty_io: use console_list_lock for list synchronization
  proc: consoles: use console_list_lock for list iteration
  printk: relieve console_lock of list synchronization duties
  printk, xen: fbfront: create/use safe function for forcing preferred

Thomas Gleixner (1):
  serial: kgdboc: Lock console list in probe function

 .clang-format                      |   1 +
 arch/m68k/emu/nfcon.c              |   4 +-
 arch/um/kernel/kmsg_dump.c         |  15 +-
 drivers/firmware/efi/earlycon.c    |   4 +-
 drivers/net/netconsole.c           |   4 +-
 drivers/tty/hvc/hvc_console.c      |   2 +-
 drivers/tty/serial/earlycon.c      |   4 +-
 drivers/tty/serial/kgdboc.c        |  37 ++-
 drivers/tty/serial/pic32_uart.c    |   2 +-
 drivers/tty/serial/samsung_tty.c   |   2 +-
 drivers/tty/serial/serial_core.c   |   2 +-
 drivers/tty/serial/xilinx_uartps.c |   2 +-
 drivers/tty/tty_io.c               |  18 +-
 drivers/usb/early/xhci-dbc.c       |   2 +-
 drivers/video/fbdev/xen-fbfront.c  |  16 +-
 fs/proc/consoles.c                 |  20 +-
 include/linux/console.h            |  75 +++++-
 include/linux/serial_core.h        |   2 +-
 kernel/debug/kdb/kdb_io.c          |   7 +-
 kernel/printk/printk.c             | 373 +++++++++++++++++++++--------
 20 files changed, 438 insertions(+), 154 deletions(-)


base-commit: c2d158a284abd63d727dad7402a2eed650dd4233
-- 
2.30.2


^ permalink raw reply	[flat|nested] 151+ messages in thread

* [PATCH printk v2 00/38] reduce console_lock scope
@ 2022-10-19 14:55 ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Paul E. McKenney, Daniel Thompson,
	Douglas Anderson, Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport,
	linux-serial, linux-fsdevel, Miguel Ojeda, Geert Uytterhoeven,
	linux-m68k, Richard Weinberger, Anton Ivanov, Johannes Berg,
	linux-um, Ard Biesheuvel, linux-efi, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, Shile Zhang,
	Xianting Tian, linuxppc-dev, Krzysztof Kozlowski, Alim Akhtar,
	linux-arm-kernel, linux-samsung-soc, Michal Simek,
	Peter Zijlstra, Mike Rapoport, Mathias Nyman, Andrew Morton,
	linux-usb, Luis Chamberlain, Aaron Tomlin, Helge Deller,
	Thomas Zimmermann, Javier Martinez Canillas, Boris Ostrovsky,
	Juergen Gross, Tom Rix, linux-fbdev, dri-devel

This is v2 of a series to prepare for threaded/atomic
printing. It is a rework of patches 6-12 of the v1 [0]. From
the v1, patches 1-5 are already mainline and a rework of
patches >12 will be posted in a later series.

This series focuses on reducing the scope of the BKL
console_lock. It achieves this by switching to SRCU and a
dedicated mutex for console list iteration and modification,
respectively. The console_lock will no longer offer this
protection and is completely removed from
(un)register_console() and console_stop/start() code.

All users of the console_lock for list iteration have been
modified. For the call sites where the console_lock is still
needed (because of other reasons), I added comments to explain
exactly why the console_lock was needed.

The base commit for this series is from Paul McKenney's RCU tree
and provides an NMI-safe SRCU implementation [1]. Without the
NMI-safe SRCU implementation, this series is not less safe than
mainline. But we will need the NMI-safe SRCU implementation for
atomic consoles anyway, so we might as well get it in
now. Especially since it _does_ increase the reliability for
mainline in the panic path.

Changes since v2:

general:

- introduce console_is_enabled() to document safe data race on
  console->flags

- switch all "console->flags & CON_ENABLED" code sites to
  console_is_enabled()

- add "for_each_console_srcu" to .clang-format

- cleanup/clarify comments relating to console_lock
  coverage/usage

um:

- kmsg_dumper: use srcu instead of console_lock for list
  iteration

kgdb/kdb:

- configure_kgdboc: keep console_lock for console->device()
  synchronization, use srcu for list iteration

- kgdboc_earlycon_pre_exp_handler: use srcu instead of
  documenting unsafety for list iteration

- kgdboc_earlycon_init: use console_list_lock instead of
  console_lock to lock list

- kdb_msg_write: use srcu instead of documenting unsafety for
  list iteration

tty:

- show_cons_active: keep console_lock for console->device()
  synchronization

fbdev:

- xen-fbfront: xenfb_probe: use srcu instead of console_lock
  for list iteration, introduce console_force_preferred() to
  safely implement hack

proc/consoles:

- show_console_dev: keep console_lock for console->device()
  synchronization

- c_next: use hlist_entry_safe() instead of
  hlist_for_each_entry_continue()

printk:

- remove console_lock from console_stop/start() and
  (un)register_console()

- introduce console_srcu_read_(un)lock() to wrap scru read
  (un)lock

- rename cons_first() macro to console_first()

- for_each_console: add lockdep check instead of introducing
  new for_each_registered_console()

- console_list_lock: add warning if in read-side critical
  section

- release srcu read lock on handover

- console_flush_all: use srcu instead of relying on console
  lock for list iteration

- console_unblank: use srcu instead of relying on console_lock
  for list iteration

- console_flush_on_panic: use srcu for list iteration and
  document console->seq race

- device: keep console_lock for console->device()
  synchronization, usr srcu for list iteration

- register_console: split list adding logic into the 3 distinct
  scenarios

- register_console: set initial sequence number before adding
  to list

- unregister_console: fix ENODEV return value if the console is
  not registered

- console_stop: synchronize srcu

- printk_late_init: use _safe variant of iteration

- __pr_flush: use srcu instead of relying on console_lock for
  list iteration

John Ogness

[0] https://lore.kernel.org/r/20220924000454.3319186-1-john.ogness@linutronix.de
[1] https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/log/?h=srcunmisafe.2022.10.18b

John Ogness (37):
  printk: Convert console_drivers list to hlist
  printk: Prepare for SRCU console list protection
  printk: introduce console_is_enabled() wrapper
  printk: use console_is_enabled()
  tty: nfcon: use console_is_enabled()
  um: kmsg_dump: use console_is_enabled()
  efi: earlycon: use console_is_enabled()
  netconsole: use console_is_enabled()
  tty: hvc: use console_is_enabled()
  tty: serial: earlycon: use console_is_enabled()
  tty: serial: kgdboc: use console_is_enabled()
  tty: serial: pic32_uart: use console_is_enabled()
  tty: serial: samsung_tty: use console_is_enabled()
  tty: serial: serial_core: use console_is_enabled()
  tty: serial: xilinx_uartps: use console_is_enabled()
  tty: tty_io: use console_is_enabled()
  usb: early: xhci-dbc: use console_is_enabled()
  kdb: kdb_io: use console_is_enabled()
  um: kmsg_dumper: use srcu console list iterator
  serial: kgdboc: use srcu console list iterator
  serial: kgdboc: document console_lock usage
  tty: tty_io: document console_lock usage
  xen: fbfront: use srcu console list iterator
  proc: consoles: document console_lock usage
  kdb: use srcu console list iterator
  printk: console_flush_all: use srcu console list iterator
  printk: console_unblank: use srcu console list iterator
  printk: console_flush_on_panic: use srcu console list iterator
  printk: console_device: use srcu console list iterator
  printk: register_console: use srcu console list iterator
  printk: __pr_flush: use srcu console list iterator
  printk: introduce console_list_lock
  serial: kgdboc: use console_list_lock instead of console_lock
  tty: tty_io: use console_list_lock for list synchronization
  proc: consoles: use console_list_lock for list iteration
  printk: relieve console_lock of list synchronization duties
  printk, xen: fbfront: create/use safe function for forcing preferred

Thomas Gleixner (1):
  serial: kgdboc: Lock console list in probe function

 .clang-format                      |   1 +
 arch/m68k/emu/nfcon.c              |   4 +-
 arch/um/kernel/kmsg_dump.c         |  15 +-
 drivers/firmware/efi/earlycon.c    |   4 +-
 drivers/net/netconsole.c           |   4 +-
 drivers/tty/hvc/hvc_console.c      |   2 +-
 drivers/tty/serial/earlycon.c      |   4 +-
 drivers/tty/serial/kgdboc.c        |  37 ++-
 drivers/tty/serial/pic32_uart.c    |   2 +-
 drivers/tty/serial/samsung_tty.c   |   2 +-
 drivers/tty/serial/serial_core.c   |   2 +-
 drivers/tty/serial/xilinx_uartps.c |   2 +-
 drivers/tty/tty_io.c               |  18 +-
 drivers/usb/early/xhci-dbc.c       |   2 +-
 drivers/video/fbdev/xen-fbfront.c  |  16 +-
 fs/proc/consoles.c                 |  20 +-
 include/linux/console.h            |  75 +++++-
 include/linux/serial_core.h        |   2 +-
 kernel/debug/kdb/kdb_io.c          |   7 +-
 kernel/printk/printk.c             | 373 +++++++++++++++++++++--------
 20 files changed, 438 insertions(+), 154 deletions(-)


base-commit: c2d158a284abd63d727dad7402a2eed650dd4233
-- 
2.30.2


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um

^ permalink raw reply	[flat|nested] 151+ messages in thread

* [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function
  2022-10-19 14:55 ` John Ogness
                   ` (2 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 15:41   ` Greg Kroah-Hartman
                     ` (2 more replies)
  -1 siblings, 3 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

From: Thomas Gleixner <tglx@linutronix.de>

Unprotected list walks are not necessarily safe.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Reviewed-by: Petr Mladek <pmladek@suse.com>
---
 drivers/tty/serial/kgdboc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index 7aa37be3216a..e76f0186c335 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -193,6 +193,7 @@ static int configure_kgdboc(void)
 	if (!p)
 		goto noconfig;
 
+	console_lock();
 	for_each_console(cons) {
 		int idx;
 		if (cons->device && cons->device(cons, &idx) == p &&
@@ -201,6 +202,7 @@ static int configure_kgdboc(void)
 			break;
 		}
 	}
+	console_unlock();
 
 	kgdb_tty_driver = p;
 	kgdb_tty_line = tty_line;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist
  2022-10-19 14:55 ` John Ogness
                   ` (3 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 15:44   ` Greg Kroah-Hartman
                     ` (2 more replies)
  -1 siblings, 3 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, linux-fsdevel

Replace the open coded single linked list with a hlist so a conversion
to SRCU protected list walks can reuse the existing primitives.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 fs/proc/consoles.c      |  3 +-
 include/linux/console.h |  8 ++--
 kernel/printk/printk.c  | 99 +++++++++++++++++++++++------------------
 3 files changed, 63 insertions(+), 47 deletions(-)

diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index dfe6ce3505ce..cf2e0788f9c7 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -74,8 +74,9 @@ static void *c_start(struct seq_file *m, loff_t *pos)
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
 	struct console *con = v;
+
 	++*pos;
-	return con->next;
+	return hlist_entry_safe(con->node.next, struct console, node);
 }
 
 static void c_stop(struct seq_file *m, void *v)
diff --git a/include/linux/console.h b/include/linux/console.h
index 8c1686e2c233..7b5f21f9e469 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -15,6 +15,7 @@
 #define _LINUX_CONSOLE_H_ 1
 
 #include <linux/atomic.h>
+#include <linux/list.h>
 #include <linux/types.h>
 
 struct vc_data;
@@ -154,14 +155,16 @@ struct console {
 	u64	seq;
 	unsigned long dropped;
 	void	*data;
-	struct	 console *next;
+	struct hlist_node node;
 };
 
+extern struct hlist_head console_list;
+
 /*
  * for_each_console() allows you to iterate on each console
  */
 #define for_each_console(con) \
-	for (con = console_drivers; con != NULL; con = con->next)
+	hlist_for_each_entry(con, &console_list, node)
 
 extern int console_set_on_cmdline;
 extern struct console *early_console;
@@ -174,7 +177,6 @@ enum con_flush_mode {
 extern int add_preferred_console(char *name, int idx, char *options);
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
-extern struct console *console_drivers;
 extern void console_lock(void);
 extern int console_trylock(void);
 extern void console_unlock(void);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index e4f1e7478b52..867becc40021 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -79,13 +79,12 @@ int oops_in_progress;
 EXPORT_SYMBOL(oops_in_progress);
 
 /*
- * console_sem protects the console_drivers list, and also
- * provides serialisation for access to the entire console
- * driver system.
+ * console_sem protects console_list and console->flags updates, and also
+ * provides serialization for access to the entire console driver system.
  */
 static DEFINE_SEMAPHORE(console_sem);
-struct console *console_drivers;
-EXPORT_SYMBOL_GPL(console_drivers);
+HLIST_HEAD(console_list);
+EXPORT_SYMBOL_GPL(console_list);
 
 /*
  * System may need to suppress printk message under certain
@@ -2556,7 +2555,7 @@ static int console_cpu_notify(unsigned int cpu)
  * console_lock - lock the console system for exclusive use.
  *
  * Acquires a lock which guarantees that the caller has
- * exclusive access to the console system and the console_drivers list.
+ * exclusive access to the console system and console_list.
  *
  * Can sleep, returns nothing.
  */
@@ -2576,7 +2575,7 @@ EXPORT_SYMBOL(console_lock);
  * console_trylock - try to lock the console system for exclusive use.
  *
  * Try to acquire a lock which guarantees that the caller has exclusive
- * access to the console system and the console_drivers list.
+ * access to the console system and console_list.
  *
  * returns 1 on success, and 0 on failure to acquire the lock.
  */
@@ -2940,11 +2939,20 @@ void console_flush_on_panic(enum con_flush_mode mode)
 	console_may_schedule = 0;
 
 	if (mode == CONSOLE_REPLAY_ALL) {
+		struct hlist_node *tmp;
 		struct console *c;
 		u64 seq;
 
 		seq = prb_first_valid_seq(prb);
-		for_each_console(c)
+		/*
+		 * This cannot use for_each_console() because it's not established
+		 * that the current context has console locked and neither there is
+		 * a guarantee that there is no concurrency in that case.
+		 *
+		 * Open code it for documentation purposes and pretend that
+		 * it works.
+		 */
+		hlist_for_each_entry_safe(c, tmp, &console_list, node)
 			c->seq = seq;
 	}
 	console_unlock();
@@ -3081,6 +3089,9 @@ static void try_enable_default_console(struct console *newcon)
 	       (con->flags & CON_BOOT) ? "boot" : "",	\
 	       con->name, con->index, ##__VA_ARGS__)
 
+#define console_first()				\
+	hlist_entry(console_list.first, struct console, node)
+
 /*
  * The console driver calls this routine during kernel initialization
  * to register the console printing procedure with printk() and to
@@ -3140,8 +3151,8 @@ void register_console(struct console *newcon)
 	 * flag set and will be first in the list.
 	 */
 	if (preferred_console < 0) {
-		if (!console_drivers || !console_drivers->device ||
-		    console_drivers->flags & CON_BOOT) {
+		if (hlist_empty(&console_list) || !console_first()->device ||
+		    console_first()->flags & CON_BOOT) {
 			try_enable_default_console(newcon);
 		}
 	}
@@ -3169,20 +3180,22 @@ void register_console(struct console *newcon)
 	}
 
 	/*
-	 *	Put this console in the list - keep the
-	 *	preferred driver at the head of the list.
+	 * Put this console in the list - keep the
+	 * preferred driver at the head of the list.
 	 */
 	console_lock();
-	if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) {
-		newcon->next = console_drivers;
-		console_drivers = newcon;
-		if (newcon->next)
-			newcon->next->flags &= ~CON_CONSDEV;
-		/* Ensure this flag is always set for the head of the list */
+	if (hlist_empty(&console_list)) {
+		/* Ensure CON_CONSDEV is always set for the head. */
 		newcon->flags |= CON_CONSDEV;
+		hlist_add_head(&newcon->node, &console_list);
+
+	} else if (newcon->flags & CON_CONSDEV) {
+		/* Only the new head can have CON_CONSDEV set. */
+		console_first()->flags &= ~CON_CONSDEV;
+		hlist_add_head(&newcon->node, &console_list);
+
 	} else {
-		newcon->next = console_drivers->next;
-		console_drivers->next = newcon;
+		hlist_add_behind(&newcon->node, console_list.first);
 	}
 
 	newcon->dropped = 0;
@@ -3209,16 +3222,18 @@ void register_console(struct console *newcon)
 	if (bootcon_enabled &&
 	    ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
 	    !keep_bootcon) {
-		for_each_console(con)
+		struct hlist_node *tmp;
+
+		hlist_for_each_entry_safe(con, tmp, &console_list, node) {
 			if (con->flags & CON_BOOT)
 				unregister_console(con);
+		}
 	}
 }
 EXPORT_SYMBOL(register_console);
 
 int unregister_console(struct console *console)
 {
-	struct console *con;
 	int res;
 
 	con_printk(KERN_INFO, console, "disabled\n");
@@ -3229,32 +3244,30 @@ int unregister_console(struct console *console)
 	if (res > 0)
 		return 0;
 
-	res = -ENODEV;
 	console_lock();
-	if (console_drivers == console) {
-		console_drivers=console->next;
-		res = 0;
-	} else {
-		for_each_console(con) {
-			if (con->next == console) {
-				con->next = console->next;
-				res = 0;
-				break;
-			}
-		}
+
+	/* Disable it unconditionally */
+	console->flags &= ~CON_ENABLED;
+
+	if (hlist_unhashed(&console->node)) {
+		res = -ENODEV;
+		goto out_unlock;
 	}
 
-	if (res)
-		goto out_disable_unlock;
+	hlist_del_init(&console->node);
 
 	/*
+	 * <HISTORICAL>
 	 * If this isn't the last console and it has CON_CONSDEV set, we
 	 * need to set it on the next preferred console.
+	 * </HISTORICAL>
+	 *
+	 * The above makes no sense as there is no guarantee that the next
+	 * console has any device attached. Oh well....
 	 */
-	if (console_drivers != NULL && console->flags & CON_CONSDEV)
-		console_drivers->flags |= CON_CONSDEV;
+	if (!hlist_empty(&console_list) && console->flags & CON_CONSDEV)
+		console_first()->flags |= CON_CONSDEV;
 
-	console->flags &= ~CON_ENABLED;
 	console_unlock();
 	console_sysfs_notify();
 
@@ -3263,10 +3276,8 @@ int unregister_console(struct console *console)
 
 	return res;
 
-out_disable_unlock:
-	console->flags &= ~CON_ENABLED;
+out_unlock:
 	console_unlock();
-
 	return res;
 }
 EXPORT_SYMBOL(unregister_console);
@@ -3317,10 +3328,11 @@ void __init console_init(void)
  */
 static int __init printk_late_init(void)
 {
+	struct hlist_node *tmp;
 	struct console *con;
 	int ret;
 
-	for_each_console(con) {
+	hlist_for_each_entry_safe(con, tmp, &console_list, node) {
 		if (!(con->flags & CON_BOOT))
 			continue;
 
@@ -3340,6 +3352,7 @@ static int __init printk_late_init(void)
 			unregister_console(con);
 		}
 	}
+
 	ret = cpuhp_setup_state_nocalls(CPUHP_PRINTK_DEAD, "printk:dead", NULL,
 					console_cpu_notify);
 	WARN_ON(ret < 0);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection
  2022-10-19 14:55 ` John Ogness
                   ` (4 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 15:16   ` Miguel Ojeda
                     ` (2 more replies)
  -1 siblings, 3 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Miguel Ojeda, Paul E. McKenney, Greg Kroah-Hartman

Provide an NMI-safe SRCU protected variant to walk the console list.

Note that all console fields are now set before adding the console
to the list to avoid the console becoming visible by SCRU readers
before being fully initialized.

This is a preparatory change for a new console infrastructure which
operates independent of the console BKL.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 .clang-format           |  1 +
 include/linux/console.h | 28 +++++++++++++++-
 kernel/printk/printk.c  | 72 ++++++++++++++++++++++++++++++++---------
 3 files changed, 85 insertions(+), 16 deletions(-)

diff --git a/.clang-format b/.clang-format
index 1247d54f9e49..04a675b56b57 100644
--- a/.clang-format
+++ b/.clang-format
@@ -222,6 +222,7 @@ ForEachMacros:
   - 'for_each_component_dais'
   - 'for_each_component_dais_safe'
   - 'for_each_console'
+  - 'for_each_console_srcu'
   - 'for_each_cpu'
   - 'for_each_cpu_and'
   - 'for_each_cpu_not'
diff --git a/include/linux/console.h b/include/linux/console.h
index 7b5f21f9e469..cff86cc615f8 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -15,7 +15,7 @@
 #define _LINUX_CONSOLE_H_ 1
 
 #include <linux/atomic.h>
-#include <linux/list.h>
+#include <linux/rculist.h>
 #include <linux/types.h>
 
 struct vc_data;
@@ -158,8 +158,34 @@ struct console {
 	struct hlist_node node;
 };
 
+#ifdef CONFIG_LOCKDEP
+extern bool console_srcu_read_lock_is_held(void);
+#else
+static inline bool console_srcu_read_lock_is_held(void)
+{
+	return 1;
+}
+#endif
+
+extern int console_srcu_read_lock(void);
+extern void console_srcu_read_unlock(int cookie);
+
 extern struct hlist_head console_list;
 
+/**
+ * for_each_console_srcu() - Iterator over registered consoles
+ * @con:	struct console pointer used as loop cursor
+ *
+ * Although SRCU guarantees the console list will be consistent, the
+ * struct console fields may be updated by other CPUs while iterating.
+ *
+ * Requires console_srcu_read_lock to be held. Can be invoked from
+ * any context.
+ */
+#define for_each_console_srcu(con)					\
+	hlist_for_each_entry_srcu(con, &console_list, node,		\
+				  console_srcu_read_lock_is_held())
+
 /*
  * for_each_console() allows you to iterate on each console
  */
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 867becc40021..e8a56056cd50 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -85,6 +85,7 @@ EXPORT_SYMBOL(oops_in_progress);
 static DEFINE_SEMAPHORE(console_sem);
 HLIST_HEAD(console_list);
 EXPORT_SYMBOL_GPL(console_list);
+DEFINE_STATIC_SRCU(console_srcu);
 
 /*
  * System may need to suppress printk message under certain
@@ -102,6 +103,11 @@ static int __read_mostly suppress_panic_printk;
 static struct lockdep_map console_lock_dep_map = {
 	.name = "console_lock"
 };
+
+bool console_srcu_read_lock_is_held(void)
+{
+	return srcu_read_lock_held(&console_srcu);
+}
 #endif
 
 enum devkmsg_log_bits {
@@ -219,6 +225,32 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
 }
 #endif /* CONFIG_PRINTK && CONFIG_SYSCTL */
 
+/**
+ * console_srcu_read_lock - Register a new reader for the
+ *	SRCU-protected console list
+ *
+ * Use for_each_console_srcu() to iterate the console list
+ *
+ * Context: Any context.
+ */
+int console_srcu_read_lock(void)
+{
+	return srcu_read_lock_nmisafe(&console_srcu);
+}
+EXPORT_SYMBOL(console_srcu_read_lock);
+
+/**
+ * console_srcu_read_unlock - Unregister an old reader from
+ *	the SRCU-protected console list
+ *
+ * Counterpart to console_srcu_read_lock()
+ */
+void console_srcu_read_unlock(int cookie)
+{
+	srcu_read_unlock_nmisafe(&console_srcu, cookie);
+}
+EXPORT_SYMBOL(console_srcu_read_unlock);
+
 /*
  * Helper macros to handle lockdep when locking/unlocking console_sem. We use
  * macros instead of functions so that _RET_IP_ contains useful information.
@@ -2989,6 +3021,9 @@ void console_stop(struct console *console)
 	console_lock();
 	console->flags &= ~CON_ENABLED;
 	console_unlock();
+
+	/* Ensure that all SRCU list walks have completed */
+	synchronize_srcu(&console_srcu);
 }
 EXPORT_SYMBOL(console_stop);
 
@@ -3179,6 +3214,17 @@ void register_console(struct console *newcon)
 		newcon->flags &= ~CON_PRINTBUFFER;
 	}
 
+	newcon->dropped = 0;
+	if (newcon->flags & CON_PRINTBUFFER) {
+		/* Get a consistent copy of @syslog_seq. */
+		mutex_lock(&syslog_lock);
+		newcon->seq = syslog_seq;
+		mutex_unlock(&syslog_lock);
+	} else {
+		/* Begin with next message. */
+		newcon->seq = prb_next_seq(prb);
+	}
+
 	/*
 	 * Put this console in the list - keep the
 	 * preferred driver at the head of the list.
@@ -3187,28 +3233,20 @@ void register_console(struct console *newcon)
 	if (hlist_empty(&console_list)) {
 		/* Ensure CON_CONSDEV is always set for the head. */
 		newcon->flags |= CON_CONSDEV;
-		hlist_add_head(&newcon->node, &console_list);
+		hlist_add_head_rcu(&newcon->node, &console_list);
 
 	} else if (newcon->flags & CON_CONSDEV) {
 		/* Only the new head can have CON_CONSDEV set. */
 		console_first()->flags &= ~CON_CONSDEV;
-		hlist_add_head(&newcon->node, &console_list);
+		hlist_add_head_rcu(&newcon->node, &console_list);
 
 	} else {
-		hlist_add_behind(&newcon->node, console_list.first);
-	}
-
-	newcon->dropped = 0;
-	if (newcon->flags & CON_PRINTBUFFER) {
-		/* Get a consistent copy of @syslog_seq. */
-		mutex_lock(&syslog_lock);
-		newcon->seq = syslog_seq;
-		mutex_unlock(&syslog_lock);
-	} else {
-		/* Begin with next message. */
-		newcon->seq = prb_next_seq(prb);
+		hlist_add_behind_rcu(&newcon->node, console_list.first);
 	}
 	console_unlock();
+
+	/* No need to synchronize SRCU here! */
+
 	console_sysfs_notify();
 
 	/*
@@ -3254,7 +3292,7 @@ int unregister_console(struct console *console)
 		goto out_unlock;
 	}
 
-	hlist_del_init(&console->node);
+	hlist_del_init_rcu(&console->node);
 
 	/*
 	 * <HISTORICAL>
@@ -3269,6 +3307,10 @@ int unregister_console(struct console *console)
 		console_first()->flags |= CON_CONSDEV;
 
 	console_unlock();
+
+	/* Ensure that all SRCU list walks have completed */
+	synchronize_srcu(&console_srcu);
+
 	console_sysfs_notify();
 
 	if (console->exit)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper
  2022-10-19 14:55 ` John Ogness
                   ` (5 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 16:01   ` Greg Kroah-Hartman
  2022-10-21  8:57   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman

After switching to SRCU for console list iteration, some readers
will begin accessing console->flags as a data race. This is safe
because there is at most one CPU modifying console->flags and
using rmw operations.

The primary reason for readers to access console->flags is to
check if the console is enabled. Introduce console_is_enabled()
to mark such access as a data race.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 include/linux/console.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/include/linux/console.h b/include/linux/console.h
index cff86cc615f8..60195cd086dc 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -172,6 +172,26 @@ extern void console_srcu_read_unlock(int cookie);
 
 extern struct hlist_head console_list;
 
+/**
+ * console_is_enabled - Check if the console is enabled
+ * @con:	struct console pointer of console to check
+ *
+ * This should be used instead of manually testing for the CON_ENABLED
+ * bit in the console->flags.
+ *
+ * Context: Any context.
+ */
+static inline bool console_is_enabled(const struct console *con)
+{
+	/*
+	 * If SRCU is used, reading of console->flags can be a data
+	 * race. However, this is safe because there is at most one
+	 * CPU modifying console->flags and it is using only
+	 * read-modify-write operations to do so.
+	 */
+	return (data_race(READ_ONCE(con->flags)) & CON_ENABLED);
+}
+
 /**
  * for_each_console_srcu() - Iterator over registered consoles
  * @con:	struct console pointer used as loop cursor
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 05/38] printk: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (6 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-21  9:25   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index e8a56056cd50..7ff2fc75fc3b 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2658,7 +2658,7 @@ static bool abandon_console_lock_in_panic(void)
  */
 static inline bool console_is_usable(struct console *con)
 {
-	if (!(con->flags & CON_ENABLED))
+	if (!console_is_enabled(con))
 		return false;
 
 	if (!con->write)
@@ -2944,7 +2944,7 @@ void console_unblank(void)
 	console_locked = 1;
 	console_may_schedule = 0;
 	for_each_console(c)
-		if ((c->flags & CON_ENABLED) && c->unblank)
+		if (console_is_enabled(c) && c->unblank)
 			c->unblank();
 	console_unlock();
 
@@ -3098,7 +3098,7 @@ static int try_enable_preferred_console(struct console *newcon,
 	 * without matching. Accept the pre-enabled consoles only when match()
 	 * and setup() had a chance to be called.
 	 */
-	if (newcon->flags & CON_ENABLED && c->user_specified ==	user_specified)
+	if (console_is_enabled(newcon) && (c->user_specified == user_specified))
 		return 0;
 
 	return -ENOENT;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 06/38] tty: nfcon: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (7 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-21  9:55   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Geert Uytterhoeven, linux-m68k

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 arch/m68k/emu/nfcon.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c
index 557d60867f98..c542fc2b121f 100644
--- a/arch/m68k/emu/nfcon.c
+++ b/arch/m68k/emu/nfcon.c
@@ -49,7 +49,7 @@ static void nfcon_write(struct console *con, const char *str,
 static struct tty_driver *nfcon_device(struct console *con, int *index)
 {
 	*index = 0;
-	return (con->flags & CON_ENABLED) ? nfcon_tty_driver : NULL;
+	return console_is_enabled(con) ? nfcon_tty_driver : NULL;
 }
 
 static struct console nf_console = {
@@ -151,7 +151,7 @@ static int __init nfcon_init(void)
 
 	nfcon_tty_driver = driver;
 
-	if (!(nf_console.flags & CON_ENABLED))
+	if (!console_is_enabled(&nf_console))
 		register_console(&nf_console);
 
 	return 0;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 07/38] um: kmsg_dump: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
@ 2022-10-19 14:55   ` John Ogness
  -1 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Richard Weinberger, Anton Ivanov, Johannes Berg,
	linux-um

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 arch/um/kernel/kmsg_dump.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
index 0224fcb36e22..3a3bbbb22090 100644
--- a/arch/um/kernel/kmsg_dump.c
+++ b/arch/um/kernel/kmsg_dump.c
@@ -22,8 +22,8 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
 		return;
 
 	for_each_console(con) {
-		if(strcmp(con->name, "tty") == 0 &&
-		   (con->flags & (CON_ENABLED | CON_CONSDEV)) != 0) {
+		if (strcmp(con->name, "tty") == 0 &&
+		    (console_is_enabled(con) || (con->flags & CON_CONSDEV))) {
 			break;
 		}
 	}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 07/38] um: kmsg_dump: use console_is_enabled()
@ 2022-10-19 14:55   ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Richard Weinberger, Anton Ivanov, Johannes Berg,
	linux-um

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 arch/um/kernel/kmsg_dump.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
index 0224fcb36e22..3a3bbbb22090 100644
--- a/arch/um/kernel/kmsg_dump.c
+++ b/arch/um/kernel/kmsg_dump.c
@@ -22,8 +22,8 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
 		return;
 
 	for_each_console(con) {
-		if(strcmp(con->name, "tty") == 0 &&
-		   (con->flags & (CON_ENABLED | CON_CONSDEV)) != 0) {
+		if (strcmp(con->name, "tty") == 0 &&
+		    (console_is_enabled(con) || (con->flags & CON_CONSDEV))) {
 			break;
 		}
 	}
-- 
2.30.2


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um

^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 08/38] efi: earlycon: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (9 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 15:32   ` Ard Biesheuvel
  2022-10-21 12:53   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Ard Biesheuvel, linux-efi

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/firmware/efi/earlycon.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/efi/earlycon.c b/drivers/firmware/efi/earlycon.c
index a52236e11e5f..8c27eb941d8e 100644
--- a/drivers/firmware/efi/earlycon.c
+++ b/drivers/firmware/efi/earlycon.c
@@ -30,7 +30,7 @@ static void *efi_fb;
 static int __init efi_earlycon_remap_fb(void)
 {
 	/* bail if there is no bootconsole or it has been disabled already */
-	if (!earlycon_console || !(earlycon_console->flags & CON_ENABLED))
+	if (!earlycon_console || !console_is_enabled(earlycon_console))
 		return 0;
 
 	efi_fb = memremap(fb_base, screen_info.lfb_size,
@@ -43,7 +43,7 @@ early_initcall(efi_earlycon_remap_fb);
 static int __init efi_earlycon_unmap_fb(void)
 {
 	/* unmap the bootconsole fb unless keep_bootcon has left it enabled */
-	if (efi_fb && !(earlycon_console->flags & CON_ENABLED))
+	if (efi_fb && !console_is_enabled(earlycon_console))
 		memunmap(efi_fb);
 	return 0;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 09/38] netconsole: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (10 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-21 13:14   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, netdev

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/net/netconsole.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index bdff9ac5056d..073e59a06f21 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -332,7 +332,7 @@ static ssize_t enabled_store(struct config_item *item,
 	}
 
 	if (enabled) {	/* true */
-		if (nt->extended && !(netconsole_ext.flags & CON_ENABLED)) {
+		if (nt->extended && !console_is_enabled(&netconsole_ext)) {
 			netconsole_ext.flags |= CON_ENABLED;
 			register_console(&netconsole_ext);
 		}
@@ -915,7 +915,7 @@ static int __init init_netconsole(void)
 	if (err)
 		goto undonotifier;
 
-	if (netconsole_ext.flags & CON_ENABLED)
+	if (console_is_enabled(&netconsole_ext))
 		register_console(&netconsole_ext);
 	register_console(&netconsole);
 	pr_info("network logging started\n");
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 10/38] tty: hvc: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
@ 2022-10-19 14:55   ` John Ogness
  -1 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, Shile Zhang,
	Xianting Tian, linuxppc-dev

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/hvc/hvc_console.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 4802cfaa107f..6d1d7b72488c 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -265,7 +265,7 @@ static void hvc_port_destruct(struct tty_port *port)
 static void hvc_check_console(int index)
 {
 	/* Already enabled, bail out */
-	if (hvc_console.flags & CON_ENABLED)
+	if (console_is_enabled(&hvc_console))
 		return;
 
  	/* If this index is what the user requested, then register
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 10/38] tty: hvc: use console_is_enabled()
@ 2022-10-19 14:55   ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: linuxppc-dev, Xianting Tian, Greg Kroah-Hartman, Shile Zhang,
	linux-kernel, Steven Rostedt, Sergey Senozhatsky,
	Thomas Gleixner, Jiri Slaby

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/hvc/hvc_console.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 4802cfaa107f..6d1d7b72488c 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -265,7 +265,7 @@ static void hvc_port_destruct(struct tty_port *port)
 static void hvc_check_console(int index)
 {
 	/* Already enabled, bail out */
-	if (hvc_console.flags & CON_ENABLED)
+	if (console_is_enabled(&hvc_console))
 		return;
 
  	/* If this index is what the user requested, then register
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 11/38] tty: serial: earlycon: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (12 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 16:01   ` Greg Kroah-Hartman
  2022-10-21 13:51   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, linux-serial

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

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

diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c
index a5f380584cda..bdfb60da97bd 100644
--- a/drivers/tty/serial/earlycon.c
+++ b/drivers/tty/serial/earlycon.c
@@ -181,7 +181,7 @@ int __init setup_earlycon(char *buf)
 	if (!buf || !buf[0])
 		return -EINVAL;
 
-	if (early_con.flags & CON_ENABLED)
+	if (console_is_enabled(&early_con))
 		return -EALREADY;
 
 again:
@@ -253,7 +253,7 @@ int __init of_setup_earlycon(const struct earlycon_id *match,
 	bool big_endian;
 	u64 addr;
 
-	if (early_con.flags & CON_ENABLED)
+	if (console_is_enabled(&early_con))
 		return -EALREADY;
 
 	spin_lock_init(&port->lock);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (13 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 16:00   ` Greg Kroah-Hartman
                     ` (2 more replies)
  -1 siblings, 3 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

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

diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index e76f0186c335..b17aa7e49894 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -533,7 +533,7 @@ static int __init kgdboc_earlycon_init(char *opt)
 	console_lock();
 	for_each_console(con) {
 		if (con->write && con->read &&
-		    (con->flags & (CON_BOOT | CON_ENABLED)) &&
+		    (console_is_enabled(con) || (con->flags & CON_BOOT)) &&
 		    (!opt || !opt[0] || strcmp(con->name, opt) == 0))
 			break;
 	}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 13/38] tty: serial: pic32_uart: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (14 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 16:01   ` Greg Kroah-Hartman
  2022-10-21 14:11   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, linux-serial

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/pic32_uart.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c
index 2beada66c824..d70344dc6e8a 100644
--- a/drivers/tty/serial/pic32_uart.c
+++ b/drivers/tty/serial/pic32_uart.c
@@ -843,7 +843,7 @@ console_initcall(pic32_console_init);
  */
 static int __init pic32_late_console_init(void)
 {
-	if (!(pic32_console.flags & CON_ENABLED))
+	if (!console_is_enabled(&pic32_console))
 		register_console(&pic32_console);
 
 	return 0;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 14/38] tty: serial: samsung_tty: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
@ 2022-10-19 14:55   ` John Ogness
  -1 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Krzysztof Kozlowski, Alim Akhtar,
	Greg Kroah-Hartman, Jiri Slaby, linux-arm-kernel,
	linux-samsung-soc, linux-serial

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/samsung_tty.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 77d1363029f5..8142a0e53ffa 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -1732,7 +1732,7 @@ static void __init s3c24xx_serial_register_console(void)
 
 static void s3c24xx_serial_unregister_console(void)
 {
-	if (s3c24xx_serial_console.flags & CON_ENABLED)
+	if (console_is_enabled(&s3c24xx_serial_console))
 		unregister_console(&s3c24xx_serial_console);
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 14/38] tty: serial: samsung_tty: use console_is_enabled()
@ 2022-10-19 14:55   ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Krzysztof Kozlowski, Alim Akhtar,
	Greg Kroah-Hartman, Jiri Slaby, linux-arm-kernel,
	linux-samsung-soc, linux-serial

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/samsung_tty.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 77d1363029f5..8142a0e53ffa 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -1732,7 +1732,7 @@ static void __init s3c24xx_serial_register_console(void)
 
 static void s3c24xx_serial_unregister_console(void)
 {
-	if (s3c24xx_serial_console.flags & CON_ENABLED)
+	if (console_is_enabled(&s3c24xx_serial_console))
 		unregister_console(&s3c24xx_serial_console);
 }
 
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 15/38] tty: serial: serial_core: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (16 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 16:00   ` Greg Kroah-Hartman
  2022-10-21 14:14   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, linux-serial

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/serial_core.c | 2 +-
 include/linux/serial_core.h      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 179ee199df34..ebf609e4e179 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -2573,7 +2573,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
 		 * successfully registered yet, try to re-register it.
 		 * It may be that the port was not available.
 		 */
-		if (port->cons && !(port->cons->flags & CON_ENABLED))
+		if (port->cons && !console_is_enabled(port->cons))
 			register_console(port->cons);
 
 		/*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index d657f2a42a7b..ed5d1aeb91e1 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -745,7 +745,7 @@ static inline int setup_earlycon(char *buf) { return 0; }
 
 static inline bool uart_console_enabled(struct uart_port *port)
 {
-	return uart_console(port) && (port->cons->flags & CON_ENABLED);
+	return uart_console(port) && console_is_enabled(port->cons);
 }
 
 struct uart_port *uart_get_console(struct uart_port *ports, int nr,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 16/38] tty: serial: xilinx_uartps: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
@ 2022-10-19 14:55   ` John Ogness
  -1 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, Michal Simek,
	linux-serial, linux-arm-kernel

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 2eff7cff57c4..e1fe95bd55c1 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1631,7 +1631,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
 	/* This is not port which is used for console that's why clean it up */
 	if (console_port == port &&
-	    !(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) {
+	    !console_is_enabled(cdns_uart_uart_driver.cons)) {
 		console_port = NULL;
 		cdns_uart_console.index = -1;
 	}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 16/38] tty: serial: xilinx_uartps: use console_is_enabled()
@ 2022-10-19 14:55   ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, Michal Simek,
	linux-serial, linux-arm-kernel

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 2eff7cff57c4..e1fe95bd55c1 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1631,7 +1631,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
 	/* This is not port which is used for console that's why clean it up */
 	if (console_port == port &&
-	    !(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) {
+	    !console_is_enabled(cdns_uart_uart_driver.cons)) {
 		console_port = NULL;
 		cdns_uart_console.index = -1;
 	}
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 17/38] tty: tty_io: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (18 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 16:00   ` Greg Kroah-Hartman
  2022-10-21 14:24   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/tty_io.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index de06c3c2ff70..2050e63963bb 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3532,7 +3532,7 @@ static ssize_t show_cons_active(struct device *dev,
 			continue;
 		if (!c->write)
 			continue;
-		if ((c->flags & CON_ENABLED) == 0)
+		if (!console_is_enabled(c))
 			continue;
 		cs[i++] = c;
 		if (i >= ARRAY_SIZE(cs))
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 18/38] usb: early: xhci-dbc: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (19 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 16:01   ` Greg Kroah-Hartman
  2022-10-21 14:27   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Peter Zijlstra, Mike Rapoport,
	Mathias Nyman, Andrew Morton, linux-usb

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/usb/early/xhci-dbc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c
index bfb7e2b85299..b1a9c393160b 100644
--- a/drivers/usb/early/xhci-dbc.c
+++ b/drivers/usb/early/xhci-dbc.c
@@ -927,7 +927,7 @@ void __init early_xdbc_register_console(void)
 
 static void xdbc_unregister_console(void)
 {
-	if (early_xdbc_console.flags & CON_ENABLED)
+	if (console_is_enabled(&early_xdbc_console))
 		unregister_console(&early_xdbc_console);
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 19/38] kdb: kdb_io: use console_is_enabled()
  2022-10-19 14:55 ` John Ogness
                   ` (20 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-21 14:28   ` Petr Mladek
  2022-10-25  0:34   ` Doug Anderson
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Luis Chamberlain, Aaron Tomlin, kgdb-bugreport

Replace (console->flags & CON_ENABLED) usage with console_is_enabled().

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/debug/kdb/kdb_io.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
index 67d3c48a1522..550fe8b456ec 100644
--- a/kernel/debug/kdb/kdb_io.c
+++ b/kernel/debug/kdb/kdb_io.c
@@ -559,7 +559,7 @@ static void kdb_msg_write(const char *msg, int msg_len)
 	}
 
 	for_each_console(c) {
-		if (!(c->flags & CON_ENABLED))
+		if (!console_is_enabled(c))
 			continue;
 		if (c == dbg_io_ops->cons)
 			continue;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 20/38] um: kmsg_dumper: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
@ 2022-10-19 14:55   ` John Ogness
  -1 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Richard Weinberger, Anton Ivanov, Johannes Berg,
	linux-um

Rather than using the console_lock to guarantee safe console list
traversal, use srcu console list iteration.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 arch/um/kernel/kmsg_dump.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
index 3a3bbbb22090..44a418dec919 100644
--- a/arch/um/kernel/kmsg_dump.c
+++ b/arch/um/kernel/kmsg_dump.c
@@ -16,20 +16,17 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
 	struct console *con;
 	unsigned long flags;
 	size_t len = 0;
+	int cookie;
 
 	/* only dump kmsg when no console is available */
-	if (!console_trylock())
-		return;
-
-	for_each_console(con) {
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(con) {
 		if (strcmp(con->name, "tty") == 0 &&
 		    (console_is_enabled(con) || (con->flags & CON_CONSDEV))) {
 			break;
 		}
 	}
-
-	console_unlock();
-
+	console_srcu_read_unlock(cookie);
 	if (con)
 		return;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 20/38] um: kmsg_dumper: use srcu console list iterator
@ 2022-10-19 14:55   ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Richard Weinberger, Anton Ivanov, Johannes Berg,
	linux-um

Rather than using the console_lock to guarantee safe console list
traversal, use srcu console list iteration.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 arch/um/kernel/kmsg_dump.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
index 3a3bbbb22090..44a418dec919 100644
--- a/arch/um/kernel/kmsg_dump.c
+++ b/arch/um/kernel/kmsg_dump.c
@@ -16,20 +16,17 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
 	struct console *con;
 	unsigned long flags;
 	size_t len = 0;
+	int cookie;
 
 	/* only dump kmsg when no console is available */
-	if (!console_trylock())
-		return;
-
-	for_each_console(con) {
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(con) {
 		if (strcmp(con->name, "tty") == 0 &&
 		    (console_is_enabled(con) || (con->flags & CON_CONSDEV))) {
 			break;
 		}
 	}
-
-	console_unlock();
-
+	console_srcu_read_unlock(cookie);
 	if (con)
 		return;
 
-- 
2.30.2


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um

^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 21/38] serial: kgdboc: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
                   ` (22 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-19 16:02   ` Greg Kroah-Hartman
  2022-10-21 15:09   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

Use srcu console list iteration for safe console list traversal.

Note that configure_kgdboc() still requires the console_lock in
order to ensure that no console is in its write() callback when
its direct() callback is called. Add comments to clarify this.

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

diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index b17aa7e49894..e9d3f8c6e3dc 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -171,6 +171,7 @@ static int configure_kgdboc(void)
 	int err = -ENODEV;
 	char *cptr = config;
 	struct console *cons;
+	int cookie;
 
 	if (!strlen(config) || isspace(config[0])) {
 		err = 0;
@@ -193,8 +194,14 @@ static int configure_kgdboc(void)
 	if (!p)
 		goto noconfig;
 
+	/*
+	 * Stop console printing because the device() callback may
+	 * assume the console is not within its write() callback.
+	 */
 	console_lock();
-	for_each_console(cons) {
+
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(cons) {
 		int idx;
 		if (cons->device && cons->device(cons, &idx) == p &&
 		    idx == tty_line) {
@@ -202,6 +209,8 @@ static int configure_kgdboc(void)
 			break;
 		}
 	}
+	console_srcu_read_unlock(cookie);
+
 	console_unlock();
 
 	kgdb_tty_driver = p;
@@ -451,6 +460,7 @@ static void kgdboc_earlycon_pre_exp_handler(void)
 {
 	struct console *con;
 	static bool already_warned;
+	int cookie;
 
 	if (already_warned)
 		return;
@@ -463,9 +473,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");
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage
  2022-10-19 14:55 ` John Ogness
                   ` (23 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-20  7:42   ` Greg Kroah-Hartman
                     ` (2 more replies)
  -1 siblings, 3 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
are unregistered until the kgdboc_earlycon is setup. This is necessary
because the trapping of the exit() callback assumes that the exit()
callback is not called before the trap is setup.

Explicitly document this non-typical console_lock usage.

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

diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index e9d3f8c6e3dc..48000666789a 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -545,6 +545,14 @@ static int __init kgdboc_earlycon_init(char *opt)
 	 * Look for a matching console, or if the name was left blank just
 	 * pick the first one we find.
 	 */
+
+	/*
+	 * Hold the console_lock to guarantee that no consoles are
+	 * unregistered until the kgdboc_earlycon setup is complete.
+	 * Trapping the exit() callback relies on exit() not being
+	 * called until the trap is setup. This also allows safe
+	 * traversal of the console list.
+	 */
 	console_lock();
 	for_each_console(con) {
 		if (con->write && con->read &&
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 23/38] tty: tty_io: document console_lock usage
  2022-10-19 14:55 ` John Ogness
                   ` (24 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-20  7:43   ` Greg Kroah-Hartman
  2022-10-25 13:31   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby

show_cons_active() uses the console_lock to gather information
on registered consoles. Since the console_lock is being used for
multiple reasons, explicitly document these reasons. This will
be useful when the console_lock is split into fine-grained
locking.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/tty_io.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 2050e63963bb..333579bfa335 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3526,6 +3526,14 @@ static ssize_t show_cons_active(struct device *dev,
 	struct console *c;
 	ssize_t count = 0;
 
+	/*
+	 * Hold the console_lock to guarantee that no consoles are
+	 * unregistered until all console processing is complete.
+	 * This also allows safe traversal of the console list.
+	 *
+	 * Stop console printing because the device() callback may
+	 * assume the console is not within its write() callback.
+	 */
 	console_lock();
 	for_each_console(c) {
 		if (!c->device)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 24/38] xen: fbfront: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
@ 2022-10-19 14:55   ` John Ogness
  -1 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Helge Deller, Thomas Zimmermann,
	Javier Martinez Canillas, Boris Ostrovsky, Juergen Gross,
	Tom Rix, linux-fbdev, dri-devel

Since the console_lock is not being used for anything other than
safe console list traversal, use srcu console list iteration instead.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/video/fbdev/xen-fbfront.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
index 4d2694d904aa..2552c853c6c2 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -500,16 +500,18 @@ static int xenfb_probe(struct xenbus_device *dev,
 static void xenfb_make_preferred_console(void)
 {
 	struct console *c;
+	int cookie;
 
 	if (console_set_on_cmdline)
 		return;
 
-	console_lock();
-	for_each_console(c) {
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(c) {
 		if (!strcmp(c->name, "tty") && c->index == 0)
 			break;
 	}
-	console_unlock();
+	console_srcu_read_unlock(cookie);
+
 	if (c) {
 		unregister_console(c);
 		c->flags |= CON_CONSDEV;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 24/38] xen: fbfront: use srcu console list iterator
@ 2022-10-19 14:55   ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Juergen Gross, linux-fbdev, Tom Rix, Helge Deller, linux-kernel,
	Steven Rostedt, Javier Martinez Canillas, Sergey Senozhatsky,
	dri-devel, Thomas Zimmermann, Thomas Gleixner, Boris Ostrovsky

Since the console_lock is not being used for anything other than
safe console list traversal, use srcu console list iteration instead.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/video/fbdev/xen-fbfront.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
index 4d2694d904aa..2552c853c6c2 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -500,16 +500,18 @@ static int xenfb_probe(struct xenbus_device *dev,
 static void xenfb_make_preferred_console(void)
 {
 	struct console *c;
+	int cookie;
 
 	if (console_set_on_cmdline)
 		return;
 
-	console_lock();
-	for_each_console(c) {
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(c) {
 		if (!strcmp(c->name, "tty") && c->index == 0)
 			break;
 	}
-	console_unlock();
+	console_srcu_read_unlock(cookie);
+
 	if (c) {
 		unregister_console(c);
 		c->flags |= CON_CONSDEV;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 25/38] proc: consoles: document console_lock usage
  2022-10-19 14:55 ` John Ogness
                   ` (26 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-25 14:40   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel

The console_lock is held throughout the start/show/stop procedure
to print out device/driver information about all registered
consoles. Since the console_lock is being used for multiple reasons,
explicitly document these reasons. This will be useful when the
console_lock is split into fine-grained locking.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 fs/proc/consoles.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index cf2e0788f9c7..32512b477605 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -63,6 +63,14 @@ static void *c_start(struct seq_file *m, loff_t *pos)
 	struct console *con;
 	loff_t off = 0;
 
+	/*
+	 * Stop console printing because the device() callback may
+	 * assume the console is not within its write() callback.
+	 *
+	 * Hold the console_lock to guarantee safe traversal of the
+	 * console list. SRCU cannot be used because there is no
+	 * place to store the SRCU cookie.
+	 */
 	console_lock();
 	for_each_console(con)
 		if (off++ == *pos)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 26/38] kdb: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
                   ` (27 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-25  0:47   ` Doug Anderson
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Luis Chamberlain, Aaron Tomlin, kgdb-bugreport

Guarantee safe iteration of the console list by using SRCU.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/debug/kdb/kdb_io.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
index 550fe8b456ec..5c0bd93c3574 100644
--- a/kernel/debug/kdb/kdb_io.c
+++ b/kernel/debug/kdb/kdb_io.c
@@ -545,6 +545,7 @@ static void kdb_msg_write(const char *msg, int msg_len)
 {
 	struct console *c;
 	const char *cp;
+	int cookie;
 	int len;
 
 	if (msg_len == 0)
@@ -558,7 +559,8 @@ static void kdb_msg_write(const char *msg, int msg_len)
 		cp++;
 	}
 
-	for_each_console(c) {
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(c) {
 		if (!console_is_enabled(c))
 			continue;
 		if (c == dbg_io_ops->cons)
@@ -577,6 +579,7 @@ static void kdb_msg_write(const char *msg, int msg_len)
 		--oops_in_progress;
 		touch_nmi_watchdog();
 	}
+	console_srcu_read_unlock(cookie);
 }
 
 int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 27/38] printk: console_flush_all: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
                   ` (28 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-25 15:17   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

Guarantee safe iteration of the console list by using SRCU.

Note that in the case of a handover, the SRCU read lock is also
released. This is documented in the function description and as
comments in the code. It is a bit tricky, but this preserves the
lockdep lock ordering for the context handing over the
console_lock:

  console_lock()
  | mutex_acquire(&console_lock_dep_map)       <-- console lock
  |
  console_unlock()
  | console_flush_all()
  | | srcu_read_lock(&console_srcu)            <-- srcu lock
  | | console_emit_next_record()
  | | | console_lock_spinning_disable_and_check()
  | | | | srcu_read_unlock(&console_srcu)      <-- srcu unlock
  | | | | mutex_release(&console_lock_dep_map) <-- console unlock

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 7ff2fc75fc3b..c4d5d58b5977 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1851,7 +1851,7 @@ static void console_lock_spinning_enable(void)
  *
  * Return: 1 if the lock rights were passed, 0 otherwise.
  */
-static int console_lock_spinning_disable_and_check(void)
+static int console_lock_spinning_disable_and_check(int cookie)
 {
 	int waiter;
 
@@ -1870,6 +1870,12 @@ static int console_lock_spinning_disable_and_check(void)
 
 	spin_release(&console_owner_dep_map, _THIS_IP_);
 
+	/*
+	 * Preserve lockdep lock ordering. Release the SRCU read lock before
+	 * releasing the console_lock.
+	 */
+	console_srcu_read_unlock(cookie);
+
 	/*
 	 * Hand off console_lock to waiter. The waiter will perform
 	 * the up(). After this, the waiter is the console_lock owner.
@@ -2353,7 +2359,7 @@ static ssize_t msg_print_ext_body(char *buf, size_t size,
 				  char *text, size_t text_len,
 				  struct dev_printk_info *dev_info) { return 0; }
 static void console_lock_spinning_enable(void) { }
-static int console_lock_spinning_disable_and_check(void) { return 0; }
+static int console_lock_spinning_disable_and_check(int cookie) { return 0; }
 static void call_console_driver(struct console *con, const char *text, size_t len,
 				char *dropped_text)
 {
@@ -2695,8 +2701,8 @@ static void __console_unlock(void)
  * DROPPED_TEXT_MAX. Otherwise @dropped_text must be NULL.
  *
  * @handover will be set to true if a printk waiter has taken over the
- * console_lock, in which case the caller is no longer holding the
- * console_lock. Otherwise it is set to false.
+ * console_lock, in which case the caller is no longer holding both the
+ * console_lock and the SRCU read lock. Otherwise it is set to false.
  *
  * Returns false if the given console has no next record to print, otherwise
  * true.
@@ -2704,7 +2710,7 @@ static void __console_unlock(void)
  * Requires the console_lock.
  */
 static bool console_emit_next_record(struct console *con, char *text, char *ext_text,
-				     char *dropped_text, bool *handover)
+				     char *dropped_text, bool *handover, int cookie)
 {
 	static int panic_console_dropped;
 	struct printk_info info;
@@ -2764,7 +2770,7 @@ static bool console_emit_next_record(struct console *con, char *text, char *ext_
 
 	con->seq++;
 
-	*handover = console_lock_spinning_disable_and_check();
+	*handover = console_lock_spinning_disable_and_check(cookie);
 	printk_safe_exit_irqrestore(flags);
 skip:
 	return true;
@@ -2801,6 +2807,7 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
 	bool any_usable = false;
 	struct console *con;
 	bool any_progress;
+	int cookie;
 
 	*next_seq = 0;
 	*handover = false;
@@ -2808,7 +2815,8 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
 	do {
 		any_progress = false;
 
-		for_each_console(con) {
+		cookie = console_srcu_read_lock();
+		for_each_console_srcu(con) {
 			bool progress;
 
 			if (!console_is_usable(con))
@@ -2819,12 +2827,17 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
 				/* Extended consoles do not print "dropped messages". */
 				progress = console_emit_next_record(con, &text[0],
 								    &ext_text[0], NULL,
-								    handover);
+								    handover, cookie);
 			} else {
 				progress = console_emit_next_record(con, &text[0],
 								    NULL, &dropped_text[0],
-								    handover);
+								    handover, cookie);
 			}
+
+			/*
+			 * If a handover has occurred, the SRCU read lock
+			 * is already released.
+			 */
 			if (*handover)
 				return false;
 
@@ -2838,14 +2851,19 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
 
 			/* Allow panic_cpu to take over the consoles safely. */
 			if (abandon_console_lock_in_panic())
-				return false;
+				goto abandon;
 
 			if (do_cond_resched)
 				cond_resched();
 		}
+		console_srcu_read_unlock(cookie);
 	} while (any_progress);
 
 	return any_usable;
+
+abandon:
+	console_srcu_read_unlock(cookie);
+	return false;
 }
 
 /**
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 28/38] printk: console_unblank: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
                   ` (29 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-25 15:28   ` Petr Mladek
  2022-10-25 15:31   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

Use srcu console list iteration for console list traversal.

Document why the console_lock is still necessary.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index c4d5d58b5977..0c37ab208395 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2948,10 +2948,14 @@ EXPORT_SYMBOL(console_conditional_schedule);
 void console_unblank(void)
 {
 	struct console *c;
+	int cookie;
 
 	/*
-	 * console_unblank can no longer be called in interrupt context unless
-	 * oops_in_progress is set to 1..
+	 * Stop console printing because the unblank() callback may
+	 * assume the console is not within its write() callback.
+	 *
+	 * If @oops_in_progress is set, this may be an atomic context.
+	 * In that case, attempt a trylock as best-effort.
 	 */
 	if (oops_in_progress) {
 		if (down_trylock_console_sem() != 0)
@@ -2961,9 +2965,14 @@ void console_unblank(void)
 
 	console_locked = 1;
 	console_may_schedule = 0;
-	for_each_console(c)
+
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(c) {
 		if (console_is_enabled(c) && c->unblank)
 			c->unblank();
+	}
+	console_srcu_read_unlock(cookie);
+
 	console_unlock();
 
 	if (!oops_in_progress)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 29/38] printk: console_flush_on_panic: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
                   ` (30 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-25 15:32   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

With SRCU it is now safe to traverse the console list, even if
the console_trylock() failed. However, overwriting console->seq
when console_trylock() failed is still an issue.

Switch to SRCU iteration and document remaining issue with
console->seq.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 0c37ab208395..e478cb92e7ba 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2998,21 +2998,22 @@ void console_flush_on_panic(enum con_flush_mode mode)
 	console_may_schedule = 0;
 
 	if (mode == CONSOLE_REPLAY_ALL) {
-		struct hlist_node *tmp;
 		struct console *c;
+		int cookie;
 		u64 seq;
 
 		seq = prb_first_valid_seq(prb);
-		/*
-		 * This cannot use for_each_console() because it's not established
-		 * that the current context has console locked and neither there is
-		 * a guarantee that there is no concurrency in that case.
-		 *
-		 * Open code it for documentation purposes and pretend that
-		 * it works.
-		 */
-		hlist_for_each_entry_safe(c, tmp, &console_list, node)
+
+		cookie = console_srcu_read_lock();
+		for_each_console_srcu(c) {
+			/*
+			 * If the above console_trylock() failed, this is an
+			 * unsynchronized assignment. But in that case, the
+			 * kernel is in "hope and pray" mode anyway.
+			 */
 			c->seq = seq;
+		}
+		console_srcu_read_unlock(cookie);
 	}
 	console_unlock();
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 30/38] printk: console_device: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
                   ` (31 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-25 15:35   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

Use srcu console list iteration for console list traversal.

Document why the console_lock is still necessary.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index e478cb92e7ba..410ad9d5649c 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3025,15 +3025,24 @@ struct tty_driver *console_device(int *index)
 {
 	struct console *c;
 	struct tty_driver *driver = NULL;
+	int cookie;
 
+	/*
+	 * Stop console printing because the device() callback may
+	 * assume the console is not within its write() callback.
+	 */
 	console_lock();
-	for_each_console(c) {
+
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(c) {
 		if (!c->device)
 			continue;
 		driver = c->device(c, index);
 		if (driver)
 			break;
 	}
+	console_srcu_read_unlock(cookie);
+
 	console_unlock();
 	return driver;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 31/38] printk: register_console: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
                   ` (32 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-26  8:20   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

Use srcu console list iteration for console list traversal. Now
the traversal at the beginning of register_console() is safe.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 410ad9d5649c..809c43e596d8 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3188,20 +3188,23 @@ void register_console(struct console *newcon)
 	struct console *con;
 	bool bootcon_enabled = false;
 	bool realcon_enabled = false;
+	int cookie;
 	int err;
 
-	for_each_console(con) {
+	cookie = console_srcu_read_lock();
+	for_each_console_srcu(con) {
 		if (WARN(con == newcon, "console '%s%d' already registered\n",
-					 con->name, con->index))
+					 con->name, con->index)) {
+			console_srcu_read_unlock(cookie);
 			return;
-	}
+		}
 
-	for_each_console(con) {
 		if (con->flags & CON_BOOT)
 			bootcon_enabled = true;
 		else
 			realcon_enabled = true;
 	}
+	console_srcu_read_unlock(cookie);
 
 	/* Do not register boot consoles when there already is a real one. */
 	if (newcon->flags & CON_BOOT && realcon_enabled) {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 32/38] printk: __pr_flush: use srcu console list iterator
  2022-10-19 14:55 ` John Ogness
                   ` (33 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-26  8:33   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

Use srcu console list iteration for console list traversal.

Document why the console_lock is still necessary.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 809c43e596d8..2faa6e3e2fb8 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3454,6 +3454,7 @@ static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre
 	struct console *c;
 	u64 last_diff = 0;
 	u64 printk_seq;
+	int cookie;
 	u64 diff;
 	u64 seq;
 
@@ -3464,9 +3465,15 @@ static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre
 	for (;;) {
 		diff = 0;
 
+		/*
+		 * Hold the console_lock to guarantee safe access to
+		 * console->seq and to prevent changes to @console_suspended
+		 * until all consoles have been processed.
+		 */
 		console_lock();
 
-		for_each_console(c) {
+		cookie = console_srcu_read_lock();
+		for_each_console_srcu(c) {
 			if (con && con != c)
 				continue;
 			if (!console_is_usable(c))
@@ -3475,6 +3482,7 @@ static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre
 			if (printk_seq < seq)
 				diff += seq - printk_seq;
 		}
+		console_srcu_read_unlock(cookie);
 
 		/*
 		 * If consoles are suspended, it cannot be expected that they
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 33/38] printk: introduce console_list_lock
  2022-10-19 14:55 ` John Ogness
                   ` (34 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-20  7:53   ` Greg Kroah-Hartman
  2022-10-27 10:09   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman

Currently there exist races in console_register(), where the types
of registered consoles are checked (without holding the console_lock)
and then after acquiring the console_lock, it is assumed that the list
has not changed. Also, some code that performs console_unregister()
make similar assumptions.

Introduce a console_list_lock to provide full synchronization for any
console list changes. The console_list_lock also provides
synchronization for updates to console->flags.

Note that one of the various responsibilities of the console_lock is
also intended to provide this synchronization. Later changes will
update call sites relying on the console_lock for this purpose. Once
all call sites have been updated, the console_lock will be relieved
of synchronizing console_list and console->flags updates.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 include/linux/console.h | 20 ++++++++--
 kernel/printk/printk.c  | 82 +++++++++++++++++++++++++++++++++++------
 2 files changed, 88 insertions(+), 14 deletions(-)

diff --git a/include/linux/console.h b/include/linux/console.h
index 60195cd086dc..bf1e8136424a 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -159,8 +159,12 @@ struct console {
 };
 
 #ifdef CONFIG_LOCKDEP
+extern void lockdep_assert_console_list_lock_held(void);
 extern bool console_srcu_read_lock_is_held(void);
 #else
+static inline void lockdep_assert_console_list_lock_held(void)
+{
+}
 static inline bool console_srcu_read_lock_is_held(void)
 {
 	return 1;
@@ -170,6 +174,9 @@ static inline bool console_srcu_read_lock_is_held(void)
 extern int console_srcu_read_lock(void);
 extern void console_srcu_read_unlock(int cookie);
 
+extern void console_list_lock(void) __acquires(console_mutex);
+extern void console_list_unlock(void) __releases(console_mutex);
+
 extern struct hlist_head console_list;
 
 /**
@@ -206,10 +213,17 @@ static inline bool console_is_enabled(const struct console *con)
 	hlist_for_each_entry_srcu(con, &console_list, node,		\
 				  console_srcu_read_lock_is_held())
 
-/*
- * for_each_console() allows you to iterate on each console
+/**
+ * for_each_console() - Iterator over registered consoles
+ * @con:	struct console pointer used as loop cursor
+ *
+ * The console list and all struct console fields are immutable while
+ * iterating.
+ *
+ * Requires console_list_lock to be held.
  */
-#define for_each_console(con) \
+#define for_each_console(con)						\
+	lockdep_assert_console_list_lock_held();			\
 	hlist_for_each_entry(con, &console_list, node)
 
 extern int console_set_on_cmdline;
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 2faa6e3e2fb8..3615ee6d68fd 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -78,6 +78,9 @@ EXPORT_SYMBOL(ignore_console_lock_warning);
 int oops_in_progress;
 EXPORT_SYMBOL(oops_in_progress);
 
+/* console_mutex protects console_list and console->flags updates. */
+static DEFINE_MUTEX(console_mutex);
+
 /*
  * console_sem protects console_list and console->flags updates, and also
  * provides serialization for access to the entire console driver system.
@@ -104,6 +107,11 @@ static struct lockdep_map console_lock_dep_map = {
 	.name = "console_lock"
 };
 
+void lockdep_assert_console_list_lock_held(void)
+{
+	lockdep_assert_held(&console_mutex);
+}
+
 bool console_srcu_read_lock_is_held(void)
 {
 	return srcu_read_lock_held(&console_srcu);
@@ -225,6 +233,40 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
 }
 #endif /* CONFIG_PRINTK && CONFIG_SYSCTL */
 
+/**
+ * console_list_lock - Lock the console list
+ *
+ * For console list or console->flags updates
+ */
+void console_list_lock(void)
+{
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	/*
+	 * In unregister_console(), synchronize_srcu() is called with the
+	 * console_list_lock held. Therefore it is not allowed that the
+	 * console_list_lock is taken with the srcu_lock held.
+	 *
+	 * Whether or not this context is in the read-side critical section
+	 * can only be detected if the appropriate debug options are enabled.
+	 */
+	WARN_ON_ONCE(debug_lockdep_rcu_enabled() &&
+		     srcu_read_lock_held(&console_srcu));
+#endif
+	mutex_lock(&console_mutex);
+}
+EXPORT_SYMBOL(console_list_lock);
+
+/**
+ * console_list_unlock - Unlock the console list
+ *
+ * Counterpart to console_list_lock()
+ */
+void console_list_unlock(void)
+{
+	mutex_unlock(&console_mutex);
+}
+EXPORT_SYMBOL(console_list_unlock);
+
 /**
  * console_srcu_read_lock - Register a new reader for the
  *	SRCU-protected console list
@@ -3055,9 +3097,11 @@ struct tty_driver *console_device(int *index)
 void console_stop(struct console *console)
 {
 	__pr_flush(console, 1000, true);
+	console_list_lock();
 	console_lock();
 	console->flags &= ~CON_ENABLED;
 	console_unlock();
+	console_list_unlock();
 
 	/* Ensure that all SRCU list walks have completed */
 	synchronize_srcu(&console_srcu);
@@ -3066,9 +3110,11 @@ EXPORT_SYMBOL(console_stop);
 
 void console_start(struct console *console)
 {
+	console_list_lock();
 	console_lock();
 	console->flags |= CON_ENABLED;
 	console_unlock();
+	console_list_unlock();
 	__pr_flush(console, 1000, true);
 }
 EXPORT_SYMBOL(console_start);
@@ -3164,6 +3210,8 @@ static void try_enable_default_console(struct console *newcon)
 #define console_first()				\
 	hlist_entry(console_list.first, struct console, node)
 
+static int unregister_console_locked(struct console *console);
+
 /*
  * The console driver calls this routine during kernel initialization
  * to register the console printing procedure with printk() and to
@@ -3188,15 +3236,14 @@ void register_console(struct console *newcon)
 	struct console *con;
 	bool bootcon_enabled = false;
 	bool realcon_enabled = false;
-	int cookie;
 	int err;
 
-	cookie = console_srcu_read_lock();
-	for_each_console_srcu(con) {
+	console_list_lock();
+
+	for_each_console(con) {
 		if (WARN(con == newcon, "console '%s%d' already registered\n",
 					 con->name, con->index)) {
-			console_srcu_read_unlock(cookie);
-			return;
+			goto unlock;
 		}
 
 		if (con->flags & CON_BOOT)
@@ -3204,13 +3251,12 @@ void register_console(struct console *newcon)
 		else
 			realcon_enabled = true;
 	}
-	console_srcu_read_unlock(cookie);
 
 	/* Do not register boot consoles when there already is a real one. */
 	if (newcon->flags & CON_BOOT && realcon_enabled) {
 		pr_info("Too late to register bootconsole %s%d\n",
 			newcon->name, newcon->index);
-		return;
+		goto unlock;
 	}
 
 	/*
@@ -3241,7 +3287,7 @@ void register_console(struct console *newcon)
 
 	/* printk() messages are not printed to the Braille console. */
 	if (err || newcon->flags & CON_BRL)
-		return;
+		goto unlock;
 
 	/*
 	 * If we have a bootconsole, and are switching to a real console,
@@ -3304,13 +3350,15 @@ void register_console(struct console *newcon)
 
 		hlist_for_each_entry_safe(con, tmp, &console_list, node) {
 			if (con->flags & CON_BOOT)
-				unregister_console(con);
+				unregister_console_locked(con);
 		}
 	}
+unlock:
+	console_list_unlock();
 }
 EXPORT_SYMBOL(register_console);
 
-int unregister_console(struct console *console)
+static int unregister_console_locked(struct console *console)
 {
 	int res;
 
@@ -3362,6 +3410,16 @@ int unregister_console(struct console *console)
 	console_unlock();
 	return res;
 }
+
+int unregister_console(struct console *console)
+{
+	int res;
+
+	console_list_lock();
+	res = unregister_console_locked(console);
+	console_list_unlock();
+	return res;
+}
 EXPORT_SYMBOL(unregister_console);
 
 /*
@@ -3414,6 +3472,7 @@ static int __init printk_late_init(void)
 	struct console *con;
 	int ret;
 
+	console_list_lock();
 	hlist_for_each_entry_safe(con, tmp, &console_list, node) {
 		if (!(con->flags & CON_BOOT))
 			continue;
@@ -3431,9 +3490,10 @@ static int __init printk_late_init(void)
 			 */
 			pr_warn("bootconsole [%s%d] uses init memory and must be disabled even before the real one is ready\n",
 				con->name, con->index);
-			unregister_console(con);
+			unregister_console_locked(con);
 		}
 	}
+	console_list_unlock();
 
 	ret = cpuhp_setup_state_nocalls(CPUHP_PRINTK_DEAD, "printk:dead", NULL,
 					console_cpu_notify);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 34/38] serial: kgdboc: use console_list_lock instead of console_lock
  2022-10-19 14:55 ` John Ogness
                   ` (35 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-20  7:52   ` Greg Kroah-Hartman
  2022-10-27 10:13   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
are unregistered until the kgdboc_earlycon is setup. The console_list_lock
should be used instead because list synchronization repsponsibility will
be removed from the console_lock in a later change.

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

diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index 48000666789a..0d85596aebe2 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -547,13 +547,13 @@ static int __init kgdboc_earlycon_init(char *opt)
 	 */
 
 	/*
-	 * Hold the console_lock to guarantee that no consoles are
+	 * Hold the console_list_lock to guarantee that no consoles are
 	 * unregistered until the kgdboc_earlycon setup is complete.
 	 * Trapping the exit() callback relies on exit() not being
 	 * called until the trap is setup. This also allows safe
 	 * traversal of the console list.
 	 */
-	console_lock();
+	console_list_lock();
 	for_each_console(con) {
 		if (con->write && con->read &&
 		    (console_is_enabled(con) || (con->flags & CON_BOOT)) &&
@@ -595,7 +595,7 @@ static int __init kgdboc_earlycon_init(char *opt)
 	}
 
 unlock:
-	console_unlock();
+	console_list_unlock();
 
 	/* Non-zero means malformed option so we always return zero */
 	return 0;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 35/38] tty: tty_io: use console_list_lock for list synchronization
  2022-10-19 14:55 ` John Ogness
                   ` (36 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-20  7:43   ` Greg Kroah-Hartman
  2022-10-27 10:17   ` Petr Mladek
  -1 siblings, 2 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby

show_cons_active() uses the console_lock to gather information
on registered consoles. It requires that no consoles are unregistered
until it is finished. The console_list_lock should be used because
list synchronization repsponsibility will be removed from the
console_lock in a later change.

Note, the console_lock is still needed to stop console printing.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/tty_io.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 333579bfa335..46a0e3c5c3a5 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3527,14 +3527,12 @@ static ssize_t show_cons_active(struct device *dev,
 	ssize_t count = 0;
 
 	/*
-	 * Hold the console_lock to guarantee that no consoles are
+	 * Hold the console_list_lock to guarantee that no consoles are
 	 * unregistered until all console processing is complete.
 	 * This also allows safe traversal of the console list.
-	 *
-	 * Stop console printing because the device() callback may
-	 * assume the console is not within its write() callback.
 	 */
-	console_lock();
+	console_list_lock();
+
 	for_each_console(c) {
 		if (!c->device)
 			continue;
@@ -3546,6 +3544,12 @@ static ssize_t show_cons_active(struct device *dev,
 		if (i >= ARRAY_SIZE(cs))
 			break;
 	}
+
+	/*
+	 * Stop console printing because the device() callback may
+	 * assume the console is not within its write() callback.
+	 */
+	console_lock();
 	while (i--) {
 		int index = cs[i]->index;
 		struct tty_driver *drv = cs[i]->device(cs[i], &index);
@@ -3561,6 +3565,8 @@ static ssize_t show_cons_active(struct device *dev,
 	}
 	console_unlock();
 
+	console_list_unlock();
+
 	return count;
 }
 static DEVICE_ATTR(active, S_IRUGO, show_cons_active, NULL);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 36/38] proc: consoles: use console_list_lock for list iteration
  2022-10-19 14:55 ` John Ogness
                   ` (37 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-27 12:02   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel

The console_lock is used in part to guarantee safe list iteration.
The console_list_lock should be used because list synchronization
repsponsibility will be removed from the console_lock in a later
change.

Note, the console_lock is still needed to stop console printing.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 fs/proc/consoles.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index 32512b477605..77409b176569 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -33,7 +33,15 @@ static int show_console_dev(struct seq_file *m, void *v)
 	if (con->device) {
 		const struct tty_driver *driver;
 		int index;
+
+		/*
+		 * Stop console printing because the device() callback may
+		 * assume the console is not within its write() callback.
+		 */
+		console_lock();
 		driver = con->device(con, &index);
+		console_unlock();
+
 		if (driver) {
 			dev = MKDEV(driver->major, driver->minor_start);
 			dev += index;
@@ -64,14 +72,11 @@ static void *c_start(struct seq_file *m, loff_t *pos)
 	loff_t off = 0;
 
 	/*
-	 * Stop console printing because the device() callback may
-	 * assume the console is not within its write() callback.
-	 *
-	 * Hold the console_lock to guarantee safe traversal of the
+	 * Hold the console_list_lock to guarantee safe traversal of the
 	 * console list. SRCU cannot be used because there is no
 	 * place to store the SRCU cookie.
 	 */
-	console_lock();
+	console_list_lock();
 	for_each_console(con)
 		if (off++ == *pos)
 			break;
@@ -89,7 +94,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 
 static void c_stop(struct seq_file *m, void *v)
 {
-	console_unlock();
+	console_list_unlock();
 }
 
 static const struct seq_operations consoles_op = {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 37/38] printk: relieve console_lock of list synchronization duties
  2022-10-19 14:55 ` John Ogness
                   ` (38 preceding siblings ...)
  (?)
@ 2022-10-19 14:55 ` John Ogness
  2022-10-27 12:40   ` Petr Mladek
  -1 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:55 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

The console_list_lock provides synchronization for console list and
console->flags updates. All call sites that were using the console_lock
for this synchronization have either switched to use the
console_list_lock or the SRCU list iterator.

Remove console_lock usage for console list updates and console->flags
updates.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 kernel/printk/printk.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 3615ee6d68fd..840d581c4b23 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -82,8 +82,8 @@ EXPORT_SYMBOL(oops_in_progress);
 static DEFINE_MUTEX(console_mutex);
 
 /*
- * console_sem protects console_list and console->flags updates, and also
- * provides serialization for access to the entire console driver system.
+ * console_sem protects updates to console->seq and console_suspended,
+ * and also provides serialization for console printing.
  */
 static DEFINE_SEMAPHORE(console_sem);
 HLIST_HEAD(console_list);
@@ -2635,7 +2635,7 @@ static int console_cpu_notify(unsigned int cpu)
  * console_lock - lock the console system for exclusive use.
  *
  * Acquires a lock which guarantees that the caller has
- * exclusive access to the console system and console_list.
+ * exclusive access to the console system.
  *
  * Can sleep, returns nothing.
  */
@@ -2655,7 +2655,7 @@ EXPORT_SYMBOL(console_lock);
  * console_trylock - try to lock the console system for exclusive use.
  *
  * Try to acquire a lock which guarantees that the caller has exclusive
- * access to the console system and console_list.
+ * access to the console system.
  *
  * returns 1 on success, and 0 on failure to acquire the lock.
  */
@@ -2911,8 +2911,7 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
 /**
  * console_unlock - unlock the console system
  *
- * Releases the console_lock which the caller holds on the console system
- * and the console driver list.
+ * Releases the console_lock which the caller holds on the console system.
  *
  * While the console_lock was held, console output may have been buffered
  * by printk().  If this is the case, console_unlock(); emits
@@ -3098,9 +3097,7 @@ void console_stop(struct console *console)
 {
 	__pr_flush(console, 1000, true);
 	console_list_lock();
-	console_lock();
 	console->flags &= ~CON_ENABLED;
-	console_unlock();
 	console_list_unlock();
 
 	/* Ensure that all SRCU list walks have completed */
@@ -3111,9 +3108,7 @@ EXPORT_SYMBOL(console_stop);
 void console_start(struct console *console)
 {
 	console_list_lock();
-	console_lock();
 	console->flags |= CON_ENABLED;
-	console_unlock();
 	console_list_unlock();
 	__pr_flush(console, 1000, true);
 }
@@ -3315,7 +3310,6 @@ void register_console(struct console *newcon)
 	 * Put this console in the list - keep the
 	 * preferred driver at the head of the list.
 	 */
-	console_lock();
 	if (hlist_empty(&console_list)) {
 		/* Ensure CON_CONSDEV is always set for the head. */
 		newcon->flags |= CON_CONSDEV;
@@ -3329,7 +3323,6 @@ void register_console(struct console *newcon)
 	} else {
 		hlist_add_behind_rcu(&newcon->node, console_list.first);
 	}
-	console_unlock();
 
 	/* No need to synchronize SRCU here! */
 
@@ -3370,8 +3363,6 @@ static int unregister_console_locked(struct console *console)
 	if (res > 0)
 		return 0;
 
-	console_lock();
-
 	/* Disable it unconditionally */
 	console->flags &= ~CON_ENABLED;
 
@@ -3394,8 +3385,6 @@ static int unregister_console_locked(struct console *console)
 	if (!hlist_empty(&console_list) && console->flags & CON_CONSDEV)
 		console_first()->flags |= CON_CONSDEV;
 
-	console_unlock();
-
 	/* Ensure that all SRCU list walks have completed */
 	synchronize_srcu(&console_srcu);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred
  2022-10-19 14:55 ` John Ogness
@ 2022-10-19 14:56   ` John Ogness
  -1 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:56 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Helge Deller, Greg Kroah-Hartman,
	Javier Martinez Canillas, Thomas Zimmermann, Juergen Gross,
	Boris Ostrovsky, Tom Rix, linux-fbdev, dri-devel

With commit 9e124fe16ff2("xen: Enable console tty by default in domU
if it's not a dummy") a hack was implemented to make sure that the
tty console remains the console behind the /dev/console device. The
main problem with the hack is that, after getting the console pointer
to the tty console, it is assumed the pointer is still valid after
releasing the console_sem. This assumption is incorrect and unsafe.

Make the hack safe by introducing a new function
console_force_preferred() to perform the full operation under
the console_list_lock.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/video/fbdev/xen-fbfront.c |  8 +---
 include/linux/console.h           |  1 +
 kernel/printk/printk.c            | 69 +++++++++++++++++++------------
 3 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
index 2552c853c6c2..aa362b25a60f 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -512,12 +512,8 @@ static void xenfb_make_preferred_console(void)
 	}
 	console_srcu_read_unlock(cookie);
 
-	if (c) {
-		unregister_console(c);
-		c->flags |= CON_CONSDEV;
-		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
-		register_console(c);
-	}
+	if (c)
+		console_force_preferred(c);
 }
 
 static int xenfb_resume(struct xenbus_device *dev)
diff --git a/include/linux/console.h b/include/linux/console.h
index bf1e8136424a..41378b00bbdd 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -235,6 +235,7 @@ enum con_flush_mode {
 };
 
 extern int add_preferred_console(char *name, int idx, char *options);
+extern void console_force_preferred(struct console *c);
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
 extern void console_lock(void);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 840d581c4b23..9a056a42b8d8 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3207,38 +3207,17 @@ static void try_enable_default_console(struct console *newcon)
 
 static int unregister_console_locked(struct console *console);
 
-/*
- * The console driver calls this routine during kernel initialization
- * to register the console printing procedure with printk() and to
- * print any messages that were printed by the kernel before the
- * console driver was initialized.
- *
- * This can happen pretty early during the boot process (because of
- * early_printk) - sometimes before setup_arch() completes - be careful
- * of what kernel features are used - they may not be initialised yet.
- *
- * There are two types of consoles - bootconsoles (early_printk) and
- * "real" consoles (everything which is not a bootconsole) which are
- * handled differently.
- *  - Any number of bootconsoles can be registered at any time.
- *  - As soon as a "real" console is registered, all bootconsoles
- *    will be unregistered automatically.
- *  - Once a "real" console is registered, any attempt to register a
- *    bootconsoles will be rejected
- */
-void register_console(struct console *newcon)
+static void register_console_locked(struct console *newcon)
 {
 	struct console *con;
 	bool bootcon_enabled = false;
 	bool realcon_enabled = false;
 	int err;
 
-	console_list_lock();
-
 	for_each_console(con) {
 		if (WARN(con == newcon, "console '%s%d' already registered\n",
 					 con->name, con->index)) {
-			goto unlock;
+			return;
 		}
 
 		if (con->flags & CON_BOOT)
@@ -3251,7 +3230,7 @@ void register_console(struct console *newcon)
 	if (newcon->flags & CON_BOOT && realcon_enabled) {
 		pr_info("Too late to register bootconsole %s%d\n",
 			newcon->name, newcon->index);
-		goto unlock;
+		return;
 	}
 
 	/*
@@ -3282,7 +3261,7 @@ void register_console(struct console *newcon)
 
 	/* printk() messages are not printed to the Braille console. */
 	if (err || newcon->flags & CON_BRL)
-		goto unlock;
+		return;
 
 	/*
 	 * If we have a bootconsole, and are switching to a real console,
@@ -3346,7 +3325,31 @@ void register_console(struct console *newcon)
 				unregister_console_locked(con);
 		}
 	}
-unlock:
+}
+
+/*
+ * The console driver calls this routine during kernel initialization
+ * to register the console printing procedure with printk() and to
+ * print any messages that were printed by the kernel before the
+ * console driver was initialized.
+ *
+ * This can happen pretty early during the boot process (because of
+ * early_printk) - sometimes before setup_arch() completes - be careful
+ * of what kernel features are used - they may not be initialised yet.
+ *
+ * There are two types of consoles - bootconsoles (early_printk) and
+ * "real" consoles (everything which is not a bootconsole) which are
+ * handled differently.
+ *  - Any number of bootconsoles can be registered at any time.
+ *  - As soon as a "real" console is registered, all bootconsoles
+ *    will be unregistered automatically.
+ *  - Once a "real" console is registered, any attempt to register a
+ *    bootconsoles will be rejected
+ */
+void register_console(struct console *newcon)
+{
+	console_list_lock();
+	register_console_locked(newcon);
 	console_list_unlock();
 }
 EXPORT_SYMBOL(register_console);
@@ -3411,6 +3414,20 @@ int unregister_console(struct console *console)
 }
 EXPORT_SYMBOL(unregister_console);
 
+void console_force_preferred(struct console *c)
+{
+	console_list_lock();
+
+	if (unregister_console_locked(c) == 0) {
+		c->flags |= CON_CONSDEV;
+		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
+		register_console_locked(c);
+	}
+
+	console_list_unlock();
+}
+EXPORT_SYMBOL(console_force_preferred);
+
 /*
  * Initialize the console device. This is called *early*, so
  * we can't necessarily depend on lots of kernel help here.
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred
@ 2022-10-19 14:56   ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-19 14:56 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Juergen Gross, linux-fbdev, Greg Kroah-Hartman, Helge Deller,
	linux-kernel, Steven Rostedt, Javier Martinez Canillas,
	Sergey Senozhatsky, dri-devel, Thomas Zimmermann, Tom Rix,
	Thomas Gleixner, Boris Ostrovsky

With commit 9e124fe16ff2("xen: Enable console tty by default in domU
if it's not a dummy") a hack was implemented to make sure that the
tty console remains the console behind the /dev/console device. The
main problem with the hack is that, after getting the console pointer
to the tty console, it is assumed the pointer is still valid after
releasing the console_sem. This assumption is incorrect and unsafe.

Make the hack safe by introducing a new function
console_force_preferred() to perform the full operation under
the console_list_lock.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/video/fbdev/xen-fbfront.c |  8 +---
 include/linux/console.h           |  1 +
 kernel/printk/printk.c            | 69 +++++++++++++++++++------------
 3 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
index 2552c853c6c2..aa362b25a60f 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -512,12 +512,8 @@ static void xenfb_make_preferred_console(void)
 	}
 	console_srcu_read_unlock(cookie);
 
-	if (c) {
-		unregister_console(c);
-		c->flags |= CON_CONSDEV;
-		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
-		register_console(c);
-	}
+	if (c)
+		console_force_preferred(c);
 }
 
 static int xenfb_resume(struct xenbus_device *dev)
diff --git a/include/linux/console.h b/include/linux/console.h
index bf1e8136424a..41378b00bbdd 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -235,6 +235,7 @@ enum con_flush_mode {
 };
 
 extern int add_preferred_console(char *name, int idx, char *options);
+extern void console_force_preferred(struct console *c);
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
 extern void console_lock(void);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 840d581c4b23..9a056a42b8d8 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3207,38 +3207,17 @@ static void try_enable_default_console(struct console *newcon)
 
 static int unregister_console_locked(struct console *console);
 
-/*
- * The console driver calls this routine during kernel initialization
- * to register the console printing procedure with printk() and to
- * print any messages that were printed by the kernel before the
- * console driver was initialized.
- *
- * This can happen pretty early during the boot process (because of
- * early_printk) - sometimes before setup_arch() completes - be careful
- * of what kernel features are used - they may not be initialised yet.
- *
- * There are two types of consoles - bootconsoles (early_printk) and
- * "real" consoles (everything which is not a bootconsole) which are
- * handled differently.
- *  - Any number of bootconsoles can be registered at any time.
- *  - As soon as a "real" console is registered, all bootconsoles
- *    will be unregistered automatically.
- *  - Once a "real" console is registered, any attempt to register a
- *    bootconsoles will be rejected
- */
-void register_console(struct console *newcon)
+static void register_console_locked(struct console *newcon)
 {
 	struct console *con;
 	bool bootcon_enabled = false;
 	bool realcon_enabled = false;
 	int err;
 
-	console_list_lock();
-
 	for_each_console(con) {
 		if (WARN(con == newcon, "console '%s%d' already registered\n",
 					 con->name, con->index)) {
-			goto unlock;
+			return;
 		}
 
 		if (con->flags & CON_BOOT)
@@ -3251,7 +3230,7 @@ void register_console(struct console *newcon)
 	if (newcon->flags & CON_BOOT && realcon_enabled) {
 		pr_info("Too late to register bootconsole %s%d\n",
 			newcon->name, newcon->index);
-		goto unlock;
+		return;
 	}
 
 	/*
@@ -3282,7 +3261,7 @@ void register_console(struct console *newcon)
 
 	/* printk() messages are not printed to the Braille console. */
 	if (err || newcon->flags & CON_BRL)
-		goto unlock;
+		return;
 
 	/*
 	 * If we have a bootconsole, and are switching to a real console,
@@ -3346,7 +3325,31 @@ void register_console(struct console *newcon)
 				unregister_console_locked(con);
 		}
 	}
-unlock:
+}
+
+/*
+ * The console driver calls this routine during kernel initialization
+ * to register the console printing procedure with printk() and to
+ * print any messages that were printed by the kernel before the
+ * console driver was initialized.
+ *
+ * This can happen pretty early during the boot process (because of
+ * early_printk) - sometimes before setup_arch() completes - be careful
+ * of what kernel features are used - they may not be initialised yet.
+ *
+ * There are two types of consoles - bootconsoles (early_printk) and
+ * "real" consoles (everything which is not a bootconsole) which are
+ * handled differently.
+ *  - Any number of bootconsoles can be registered at any time.
+ *  - As soon as a "real" console is registered, all bootconsoles
+ *    will be unregistered automatically.
+ *  - Once a "real" console is registered, any attempt to register a
+ *    bootconsoles will be rejected
+ */
+void register_console(struct console *newcon)
+{
+	console_list_lock();
+	register_console_locked(newcon);
 	console_list_unlock();
 }
 EXPORT_SYMBOL(register_console);
@@ -3411,6 +3414,20 @@ int unregister_console(struct console *console)
 }
 EXPORT_SYMBOL(unregister_console);
 
+void console_force_preferred(struct console *c)
+{
+	console_list_lock();
+
+	if (unregister_console_locked(c) == 0) {
+		c->flags |= CON_CONSDEV;
+		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
+		register_console_locked(c);
+	}
+
+	console_list_unlock();
+}
+EXPORT_SYMBOL(console_force_preferred);
+
 /*
  * Initialize the console device. This is called *early*, so
  * we can't necessarily depend on lots of kernel help here.
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection
  2022-10-19 14:55 ` [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection John Ogness
@ 2022-10-19 15:16   ` Miguel Ojeda
  2022-10-19 17:12   ` Paul E. McKenney
  2022-10-21  8:34   ` Petr Mladek
  2 siblings, 0 replies; 151+ messages in thread
From: Miguel Ojeda @ 2022-10-19 15:16 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Miguel Ojeda, Paul E. McKenney, Greg Kroah-Hartman

On Wed, Oct 19, 2022 at 4:56 PM John Ogness <john.ogness@linutronix.de> wrote:
>
>  .clang-format           |  1 +

Acked-by: Miguel Ojeda <ojeda@kernel.org>

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 08/38] efi: earlycon: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 08/38] efi: earlycon: " John Ogness
@ 2022-10-19 15:32   ` Ard Biesheuvel
  2022-10-21 12:53   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Ard Biesheuvel @ 2022-10-19 15:32 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-efi

On Wed, 19 Oct 2022 at 16:56, John Ogness <john.ogness@linutronix.de> wrote:
>
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Acked-by: Ard BIesheuvel <ardb@kernel.org>

> ---
>  drivers/firmware/efi/earlycon.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/firmware/efi/earlycon.c b/drivers/firmware/efi/earlycon.c
> index a52236e11e5f..8c27eb941d8e 100644
> --- a/drivers/firmware/efi/earlycon.c
> +++ b/drivers/firmware/efi/earlycon.c
> @@ -30,7 +30,7 @@ static void *efi_fb;
>  static int __init efi_earlycon_remap_fb(void)
>  {
>         /* bail if there is no bootconsole or it has been disabled already */
> -       if (!earlycon_console || !(earlycon_console->flags & CON_ENABLED))
> +       if (!earlycon_console || !console_is_enabled(earlycon_console))
>                 return 0;
>
>         efi_fb = memremap(fb_base, screen_info.lfb_size,
> @@ -43,7 +43,7 @@ early_initcall(efi_earlycon_remap_fb);
>  static int __init efi_earlycon_unmap_fb(void)
>  {
>         /* unmap the bootconsole fb unless keep_bootcon has left it enabled */
> -       if (efi_fb && !(earlycon_console->flags & CON_ENABLED))
> +       if (efi_fb && !console_is_enabled(earlycon_console))
>                 memunmap(efi_fb);
>         return 0;
>  }
> --
> 2.30.2
>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function
  2022-10-19 14:55 ` [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function John Ogness
@ 2022-10-19 15:41   ` Greg Kroah-Hartman
  2022-10-24  5:22   ` Sergey Senozhatsky
  2022-10-25  0:34   ` Doug Anderson
  2 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 15:41 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Jiri Slaby, kgdb-bugreport, linux-serial

On Wed, Oct 19, 2022 at 05:01:23PM +0206, John Ogness wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
> 
> Unprotected list walks are not necessarily safe.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> Reviewed-by: Petr Mladek <pmladek@suse.com>
> ---
>  drivers/tty/serial/kgdboc.c | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist
  2022-10-19 14:55 ` [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist John Ogness
@ 2022-10-19 15:44   ` Greg Kroah-Hartman
  2022-10-19 21:46     ` John Ogness
  2022-10-20 12:36   ` Petr Mladek
  2022-10-24  5:23   ` Sergey Senozhatsky
  2 siblings, 1 reply; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 15:44 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel

On Wed, Oct 19, 2022 at 05:01:24PM +0206, John Ogness wrote:
> Replace the open coded single linked list with a hlist so a conversion
> to SRCU protected list walks can reuse the existing primitives.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  fs/proc/consoles.c      |  3 +-
>  include/linux/console.h |  8 ++--
>  kernel/printk/printk.c  | 99 +++++++++++++++++++++++------------------
>  3 files changed, 63 insertions(+), 47 deletions(-)
> 
> diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
> index dfe6ce3505ce..cf2e0788f9c7 100644
> --- a/fs/proc/consoles.c
> +++ b/fs/proc/consoles.c
> @@ -74,8 +74,9 @@ static void *c_start(struct seq_file *m, loff_t *pos)
>  static void *c_next(struct seq_file *m, void *v, loff_t *pos)
>  {
>  	struct console *con = v;
> +
>  	++*pos;
> -	return con->next;
> +	return hlist_entry_safe(con->node.next, struct console, node);
>  }
>  
>  static void c_stop(struct seq_file *m, void *v)
> diff --git a/include/linux/console.h b/include/linux/console.h
> index 8c1686e2c233..7b5f21f9e469 100644
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -15,6 +15,7 @@
>  #define _LINUX_CONSOLE_H_ 1
>  
>  #include <linux/atomic.h>
> +#include <linux/list.h>
>  #include <linux/types.h>
>  
>  struct vc_data;
> @@ -154,14 +155,16 @@ struct console {
>  	u64	seq;
>  	unsigned long dropped;
>  	void	*data;
> -	struct	 console *next;
> +	struct hlist_node node;
>  };
>  
> +extern struct hlist_head console_list;
> +
>  /*
>   * for_each_console() allows you to iterate on each console
>   */
>  #define for_each_console(con) \
> -	for (con = console_drivers; con != NULL; con = con->next)
> +	hlist_for_each_entry(con, &console_list, node)
>  
>  extern int console_set_on_cmdline;
>  extern struct console *early_console;
> @@ -174,7 +177,6 @@ enum con_flush_mode {
>  extern int add_preferred_console(char *name, int idx, char *options);
>  extern void register_console(struct console *);
>  extern int unregister_console(struct console *);
> -extern struct console *console_drivers;
>  extern void console_lock(void);
>  extern int console_trylock(void);
>  extern void console_unlock(void);
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index e4f1e7478b52..867becc40021 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -79,13 +79,12 @@ int oops_in_progress;
>  EXPORT_SYMBOL(oops_in_progress);
>  
>  /*
> - * console_sem protects the console_drivers list, and also
> - * provides serialisation for access to the entire console
> - * driver system.
> + * console_sem protects console_list and console->flags updates, and also
> + * provides serialization for access to the entire console driver system.
>   */
>  static DEFINE_SEMAPHORE(console_sem);
> -struct console *console_drivers;
> -EXPORT_SYMBOL_GPL(console_drivers);
> +HLIST_HEAD(console_list);
> +EXPORT_SYMBOL_GPL(console_list);
>  
>  /*
>   * System may need to suppress printk message under certain
> @@ -2556,7 +2555,7 @@ static int console_cpu_notify(unsigned int cpu)
>   * console_lock - lock the console system for exclusive use.
>   *
>   * Acquires a lock which guarantees that the caller has
> - * exclusive access to the console system and the console_drivers list.
> + * exclusive access to the console system and console_list.
>   *
>   * Can sleep, returns nothing.
>   */
> @@ -2576,7 +2575,7 @@ EXPORT_SYMBOL(console_lock);
>   * console_trylock - try to lock the console system for exclusive use.
>   *
>   * Try to acquire a lock which guarantees that the caller has exclusive
> - * access to the console system and the console_drivers list.
> + * access to the console system and console_list.
>   *
>   * returns 1 on success, and 0 on failure to acquire the lock.
>   */
> @@ -2940,11 +2939,20 @@ void console_flush_on_panic(enum con_flush_mode mode)
>  	console_may_schedule = 0;
>  
>  	if (mode == CONSOLE_REPLAY_ALL) {
> +		struct hlist_node *tmp;
>  		struct console *c;
>  		u64 seq;
>  
>  		seq = prb_first_valid_seq(prb);
> -		for_each_console(c)
> +		/*
> +		 * This cannot use for_each_console() because it's not established
> +		 * that the current context has console locked and neither there is
> +		 * a guarantee that there is no concurrency in that case.
> +		 *
> +		 * Open code it for documentation purposes and pretend that
> +		 * it works.
> +		 */
> +		hlist_for_each_entry_safe(c, tmp, &console_list, node)
>  			c->seq = seq;
>  	}
>  	console_unlock();
> @@ -3081,6 +3089,9 @@ static void try_enable_default_console(struct console *newcon)
>  	       (con->flags & CON_BOOT) ? "boot" : "",	\
>  	       con->name, con->index, ##__VA_ARGS__)
>  
> +#define console_first()				\
> +	hlist_entry(console_list.first, struct console, node)
> +
>  /*
>   * The console driver calls this routine during kernel initialization
>   * to register the console printing procedure with printk() and to
> @@ -3140,8 +3151,8 @@ void register_console(struct console *newcon)
>  	 * flag set and will be first in the list.
>  	 */
>  	if (preferred_console < 0) {
> -		if (!console_drivers || !console_drivers->device ||
> -		    console_drivers->flags & CON_BOOT) {
> +		if (hlist_empty(&console_list) || !console_first()->device ||
> +		    console_first()->flags & CON_BOOT) {
>  			try_enable_default_console(newcon);
>  		}
>  	}
> @@ -3169,20 +3180,22 @@ void register_console(struct console *newcon)
>  	}
>  
>  	/*
> -	 *	Put this console in the list - keep the
> -	 *	preferred driver at the head of the list.
> +	 * Put this console in the list - keep the
> +	 * preferred driver at the head of the list.
>  	 */
>  	console_lock();
> -	if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) {
> -		newcon->next = console_drivers;
> -		console_drivers = newcon;
> -		if (newcon->next)
> -			newcon->next->flags &= ~CON_CONSDEV;
> -		/* Ensure this flag is always set for the head of the list */
> +	if (hlist_empty(&console_list)) {
> +		/* Ensure CON_CONSDEV is always set for the head. */
>  		newcon->flags |= CON_CONSDEV;
> +		hlist_add_head(&newcon->node, &console_list);
> +
> +	} else if (newcon->flags & CON_CONSDEV) {
> +		/* Only the new head can have CON_CONSDEV set. */
> +		console_first()->flags &= ~CON_CONSDEV;
> +		hlist_add_head(&newcon->node, &console_list);
> +
>  	} else {
> -		newcon->next = console_drivers->next;
> -		console_drivers->next = newcon;
> +		hlist_add_behind(&newcon->node, console_list.first);
>  	}
>  
>  	newcon->dropped = 0;
> @@ -3209,16 +3222,18 @@ void register_console(struct console *newcon)
>  	if (bootcon_enabled &&
>  	    ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
>  	    !keep_bootcon) {
> -		for_each_console(con)
> +		struct hlist_node *tmp;
> +
> +		hlist_for_each_entry_safe(con, tmp, &console_list, node) {
>  			if (con->flags & CON_BOOT)
>  				unregister_console(con);
> +		}
>  	}
>  }
>  EXPORT_SYMBOL(register_console);
>  
>  int unregister_console(struct console *console)
>  {
> -	struct console *con;
>  	int res;
>  
>  	con_printk(KERN_INFO, console, "disabled\n");
> @@ -3229,32 +3244,30 @@ int unregister_console(struct console *console)
>  	if (res > 0)
>  		return 0;
>  
> -	res = -ENODEV;
>  	console_lock();
> -	if (console_drivers == console) {
> -		console_drivers=console->next;
> -		res = 0;
> -	} else {
> -		for_each_console(con) {
> -			if (con->next == console) {
> -				con->next = console->next;
> -				res = 0;
> -				break;
> -			}
> -		}
> +
> +	/* Disable it unconditionally */
> +	console->flags &= ~CON_ENABLED;
> +
> +	if (hlist_unhashed(&console->node)) {

How can this ever be hit?  The console lock is held, so it shouldn't
have gone away already.  Or am I missing something else here?

Other than that minor question, looks good to me!

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 17/38] tty: tty_io: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 17/38] tty: tty_io: " John Ogness
@ 2022-10-19 16:00   ` Greg Kroah-Hartman
  2022-10-21 14:24   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:00 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby

On Wed, Oct 19, 2022 at 05:01:39PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/tty_io.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 14/38] tty: serial: samsung_tty: use console_is_enabled()
  2022-10-19 14:55   ` John Ogness
@ 2022-10-19 16:00     ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:00 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Krzysztof Kozlowski, Alim Akhtar, Jiri Slaby,
	linux-arm-kernel, linux-samsung-soc, linux-serial

On Wed, Oct 19, 2022 at 05:01:36PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/samsung_tty.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 14/38] tty: serial: samsung_tty: use console_is_enabled()
@ 2022-10-19 16:00     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:00 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Krzysztof Kozlowski, Alim Akhtar, Jiri Slaby,
	linux-arm-kernel, linux-samsung-soc, linux-serial

On Wed, Oct 19, 2022 at 05:01:36PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/samsung_tty.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 15/38] tty: serial: serial_core: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 15/38] tty: serial: serial_core: " John Ogness
@ 2022-10-19 16:00   ` Greg Kroah-Hartman
  2022-10-21 14:14   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:00 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby, linux-serial

On Wed, Oct 19, 2022 at 05:01:37PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 12/38] tty: serial: kgdboc: " John Ogness
@ 2022-10-19 16:00   ` Greg Kroah-Hartman
  2022-10-21 14:10   ` Petr Mladek
  2022-10-24 22:46   ` Doug Anderson
  2 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:00 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Jiri Slaby, kgdb-bugreport, linux-serial

On Wed, Oct 19, 2022 at 05:01:34PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 13/38] tty: serial: pic32_uart: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 13/38] tty: serial: pic32_uart: " John Ogness
@ 2022-10-19 16:01   ` Greg Kroah-Hartman
  2022-10-21 14:11   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:01 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby, linux-serial

On Wed, Oct 19, 2022 at 05:01:35PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 11/38] tty: serial: earlycon: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 11/38] tty: serial: earlycon: " John Ogness
@ 2022-10-19 16:01   ` Greg Kroah-Hartman
  2022-10-21 13:51   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:01 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby, linux-serial

On Wed, Oct 19, 2022 at 05:01:33PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 10/38] tty: hvc: use console_is_enabled()
  2022-10-19 14:55   ` John Ogness
@ 2022-10-19 16:01     ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:01 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Xianting Tian, linuxppc-dev, Shile Zhang,
	linux-kernel, Steven Rostedt, Sergey Senozhatsky,
	Thomas Gleixner, Jiri Slaby

On Wed, Oct 19, 2022 at 05:01:32PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 10/38] tty: hvc: use console_is_enabled()
@ 2022-10-19 16:01     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:01 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby, Shile Zhang, Xianting Tian,
	linuxppc-dev

On Wed, Oct 19, 2022 at 05:01:32PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper
  2022-10-19 14:55 ` [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper John Ogness
@ 2022-10-19 16:01   ` Greg Kroah-Hartman
  2022-10-21  8:57   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:01 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel

On Wed, Oct 19, 2022 at 05:01:26PM +0206, John Ogness wrote:
> After switching to SRCU for console list iteration, some readers
> will begin accessing console->flags as a data race. This is safe
> because there is at most one CPU modifying console->flags and
> using rmw operations.
> 
> The primary reason for readers to access console->flags is to
> check if the console is enabled. Introduce console_is_enabled()
> to mark such access as a data race.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 16/38] tty: serial: xilinx_uartps: use console_is_enabled()
  2022-10-19 14:55   ` John Ogness
@ 2022-10-19 16:01     ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:01 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby, Michal Simek, linux-serial,
	linux-arm-kernel

On Wed, Oct 19, 2022 at 05:01:38PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 16/38] tty: serial: xilinx_uartps: use console_is_enabled()
@ 2022-10-19 16:01     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:01 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby, Michal Simek, linux-serial,
	linux-arm-kernel

On Wed, Oct 19, 2022 at 05:01:38PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 18/38] usb: early: xhci-dbc: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 18/38] usb: early: xhci-dbc: " John Ogness
@ 2022-10-19 16:01   ` Greg Kroah-Hartman
  2022-10-21 14:27   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:01 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Peter Zijlstra, Mike Rapoport, Mathias Nyman,
	Andrew Morton, linux-usb

On Wed, Oct 19, 2022 at 05:01:40PM +0206, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 21/38] serial: kgdboc: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 21/38] serial: kgdboc: " John Ogness
@ 2022-10-19 16:02   ` Greg Kroah-Hartman
  2022-10-21 15:09   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-19 16:02 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Jiri Slaby, kgdb-bugreport, linux-serial

On Wed, Oct 19, 2022 at 05:01:43PM +0206, John Ogness wrote:
> Use srcu console list iteration for safe console list traversal.
> 
> Note that configure_kgdboc() still requires the console_lock in
> order to ensure that no console is in its write() callback when
> its direct() callback is called. Add comments to clarify this.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection
  2022-10-19 14:55 ` [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection John Ogness
  2022-10-19 15:16   ` Miguel Ojeda
@ 2022-10-19 17:12   ` Paul E. McKenney
  2022-10-21  8:34   ` Petr Mladek
  2 siblings, 0 replies; 151+ messages in thread
From: Paul E. McKenney @ 2022-10-19 17:12 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Miguel Ojeda, Greg Kroah-Hartman

On Wed, Oct 19, 2022 at 05:01:25PM +0206, John Ogness wrote:
> Provide an NMI-safe SRCU protected variant to walk the console list.
> 
> Note that all console fields are now set before adding the console
> to the list to avoid the console becoming visible by SCRU readers
> before being fully initialized.
> 
> This is a preparatory change for a new console infrastructure which
> operates independent of the console BKL.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

From an RCU viewpoint:

Reviewed-by: Paul E. McKenney <paulmck@kernel.org>

> ---
>  .clang-format           |  1 +
>  include/linux/console.h | 28 +++++++++++++++-
>  kernel/printk/printk.c  | 72 ++++++++++++++++++++++++++++++++---------
>  3 files changed, 85 insertions(+), 16 deletions(-)
> 
> diff --git a/.clang-format b/.clang-format
> index 1247d54f9e49..04a675b56b57 100644
> --- a/.clang-format
> +++ b/.clang-format
> @@ -222,6 +222,7 @@ ForEachMacros:
>    - 'for_each_component_dais'
>    - 'for_each_component_dais_safe'
>    - 'for_each_console'
> +  - 'for_each_console_srcu'
>    - 'for_each_cpu'
>    - 'for_each_cpu_and'
>    - 'for_each_cpu_not'
> diff --git a/include/linux/console.h b/include/linux/console.h
> index 7b5f21f9e469..cff86cc615f8 100644
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -15,7 +15,7 @@
>  #define _LINUX_CONSOLE_H_ 1
>  
>  #include <linux/atomic.h>
> -#include <linux/list.h>
> +#include <linux/rculist.h>
>  #include <linux/types.h>
>  
>  struct vc_data;
> @@ -158,8 +158,34 @@ struct console {
>  	struct hlist_node node;
>  };
>  
> +#ifdef CONFIG_LOCKDEP
> +extern bool console_srcu_read_lock_is_held(void);
> +#else
> +static inline bool console_srcu_read_lock_is_held(void)
> +{
> +	return 1;
> +}
> +#endif
> +
> +extern int console_srcu_read_lock(void);
> +extern void console_srcu_read_unlock(int cookie);
> +
>  extern struct hlist_head console_list;
>  
> +/**
> + * for_each_console_srcu() - Iterator over registered consoles
> + * @con:	struct console pointer used as loop cursor
> + *
> + * Although SRCU guarantees the console list will be consistent, the
> + * struct console fields may be updated by other CPUs while iterating.
> + *
> + * Requires console_srcu_read_lock to be held. Can be invoked from
> + * any context.
> + */
> +#define for_each_console_srcu(con)					\
> +	hlist_for_each_entry_srcu(con, &console_list, node,		\
> +				  console_srcu_read_lock_is_held())
> +
>  /*
>   * for_each_console() allows you to iterate on each console
>   */
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 867becc40021..e8a56056cd50 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -85,6 +85,7 @@ EXPORT_SYMBOL(oops_in_progress);
>  static DEFINE_SEMAPHORE(console_sem);
>  HLIST_HEAD(console_list);
>  EXPORT_SYMBOL_GPL(console_list);
> +DEFINE_STATIC_SRCU(console_srcu);
>  
>  /*
>   * System may need to suppress printk message under certain
> @@ -102,6 +103,11 @@ static int __read_mostly suppress_panic_printk;
>  static struct lockdep_map console_lock_dep_map = {
>  	.name = "console_lock"
>  };
> +
> +bool console_srcu_read_lock_is_held(void)
> +{
> +	return srcu_read_lock_held(&console_srcu);
> +}
>  #endif
>  
>  enum devkmsg_log_bits {
> @@ -219,6 +225,32 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
>  }
>  #endif /* CONFIG_PRINTK && CONFIG_SYSCTL */
>  
> +/**
> + * console_srcu_read_lock - Register a new reader for the
> + *	SRCU-protected console list
> + *
> + * Use for_each_console_srcu() to iterate the console list
> + *
> + * Context: Any context.
> + */
> +int console_srcu_read_lock(void)
> +{
> +	return srcu_read_lock_nmisafe(&console_srcu);
> +}
> +EXPORT_SYMBOL(console_srcu_read_lock);
> +
> +/**
> + * console_srcu_read_unlock - Unregister an old reader from
> + *	the SRCU-protected console list
> + *
> + * Counterpart to console_srcu_read_lock()
> + */
> +void console_srcu_read_unlock(int cookie)
> +{
> +	srcu_read_unlock_nmisafe(&console_srcu, cookie);
> +}
> +EXPORT_SYMBOL(console_srcu_read_unlock);
> +
>  /*
>   * Helper macros to handle lockdep when locking/unlocking console_sem. We use
>   * macros instead of functions so that _RET_IP_ contains useful information.
> @@ -2989,6 +3021,9 @@ void console_stop(struct console *console)
>  	console_lock();
>  	console->flags &= ~CON_ENABLED;
>  	console_unlock();
> +
> +	/* Ensure that all SRCU list walks have completed */
> +	synchronize_srcu(&console_srcu);
>  }
>  EXPORT_SYMBOL(console_stop);
>  
> @@ -3179,6 +3214,17 @@ void register_console(struct console *newcon)
>  		newcon->flags &= ~CON_PRINTBUFFER;
>  	}
>  
> +	newcon->dropped = 0;
> +	if (newcon->flags & CON_PRINTBUFFER) {
> +		/* Get a consistent copy of @syslog_seq. */
> +		mutex_lock(&syslog_lock);
> +		newcon->seq = syslog_seq;
> +		mutex_unlock(&syslog_lock);
> +	} else {
> +		/* Begin with next message. */
> +		newcon->seq = prb_next_seq(prb);
> +	}
> +
>  	/*
>  	 * Put this console in the list - keep the
>  	 * preferred driver at the head of the list.
> @@ -3187,28 +3233,20 @@ void register_console(struct console *newcon)
>  	if (hlist_empty(&console_list)) {
>  		/* Ensure CON_CONSDEV is always set for the head. */
>  		newcon->flags |= CON_CONSDEV;
> -		hlist_add_head(&newcon->node, &console_list);
> +		hlist_add_head_rcu(&newcon->node, &console_list);
>  
>  	} else if (newcon->flags & CON_CONSDEV) {
>  		/* Only the new head can have CON_CONSDEV set. */
>  		console_first()->flags &= ~CON_CONSDEV;
> -		hlist_add_head(&newcon->node, &console_list);
> +		hlist_add_head_rcu(&newcon->node, &console_list);
>  
>  	} else {
> -		hlist_add_behind(&newcon->node, console_list.first);
> -	}
> -
> -	newcon->dropped = 0;
> -	if (newcon->flags & CON_PRINTBUFFER) {
> -		/* Get a consistent copy of @syslog_seq. */
> -		mutex_lock(&syslog_lock);
> -		newcon->seq = syslog_seq;
> -		mutex_unlock(&syslog_lock);
> -	} else {
> -		/* Begin with next message. */
> -		newcon->seq = prb_next_seq(prb);
> +		hlist_add_behind_rcu(&newcon->node, console_list.first);
>  	}
>  	console_unlock();
> +
> +	/* No need to synchronize SRCU here! */
> +
>  	console_sysfs_notify();
>  
>  	/*
> @@ -3254,7 +3292,7 @@ int unregister_console(struct console *console)
>  		goto out_unlock;
>  	}
>  
> -	hlist_del_init(&console->node);
> +	hlist_del_init_rcu(&console->node);
>  
>  	/*
>  	 * <HISTORICAL>
> @@ -3269,6 +3307,10 @@ int unregister_console(struct console *console)
>  		console_first()->flags |= CON_CONSDEV;
>  
>  	console_unlock();
> +
> +	/* Ensure that all SRCU list walks have completed */
> +	synchronize_srcu(&console_srcu);
> +
>  	console_sysfs_notify();
>  
>  	if (console->exit)
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist
  2022-10-19 15:44   ` Greg Kroah-Hartman
@ 2022-10-19 21:46     ` John Ogness
  2022-10-20  7:43       ` Greg Kroah-Hartman
  0 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-19 21:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel

On 2022-10-19, Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
>> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
>> index e4f1e7478b52..867becc40021 100644
>> --- a/kernel/printk/printk.c
>> +++ b/kernel/printk/printk.c
>> @@ -3229,32 +3244,30 @@ int unregister_console(struct console *console)
>>  	if (res > 0)
>>  		return 0;
>>  
>> -	res = -ENODEV;
>>  	console_lock();
>> -	if (console_drivers == console) {
>> -		console_drivers=console->next;
>> -		res = 0;
>> -	} else {
>> -		for_each_console(con) {
>> -			if (con->next == console) {
>> -				con->next = console->next;
>> -				res = 0;
>> -				break;
>> -			}
>> -		}
>> +
>> +	/* Disable it unconditionally */
>> +	console->flags &= ~CON_ENABLED;
>> +
>> +	if (hlist_unhashed(&console->node)) {
>
> How can this ever be hit?  The console lock is held, so it shouldn't
> have gone away already.  Or am I missing something else here?

Mainline also has this check. I expect it is for the case that some code
tries to call unregister_console() for a console that is not
registered.

Since register_console() does not return if it succeeded, I suppose some
code somewhere my try to unregister without knowing that it never
registered in the first place.

> Other than that minor question, looks good to me!
>
> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Thanks!

John

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage
  2022-10-19 14:55 ` [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage John Ogness
@ 2022-10-20  7:42   ` Greg Kroah-Hartman
  2022-10-25  0:36   ` Doug Anderson
  2022-10-25 10:09   ` Petr Mladek
  2 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-20  7:42 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Jiri Slaby, kgdb-bugreport, linux-serial

On Wed, Oct 19, 2022 at 05:01:44PM +0206, John Ogness wrote:
> kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
> are unregistered until the kgdboc_earlycon is setup. This is necessary
> because the trapping of the exit() callback assumes that the exit()
> callback is not called before the trap is setup.
> 
> Explicitly document this non-typical console_lock usage.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/kgdboc.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
> index e9d3f8c6e3dc..48000666789a 100644
> --- a/drivers/tty/serial/kgdboc.c
> +++ b/drivers/tty/serial/kgdboc.c
> @@ -545,6 +545,14 @@ static int __init kgdboc_earlycon_init(char *opt)
>  	 * Look for a matching console, or if the name was left blank just
>  	 * pick the first one we find.
>  	 */
> +
> +	/*
> +	 * Hold the console_lock to guarantee that no consoles are
> +	 * unregistered until the kgdboc_earlycon setup is complete.
> +	 * Trapping the exit() callback relies on exit() not being
> +	 * called until the trap is setup. This also allows safe
> +	 * traversal of the console list.
> +	 */
>  	console_lock();
>  	for_each_console(con) {
>  		if (con->write && con->read &&
> -- 
> 2.30.2
>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist
  2022-10-19 21:46     ` John Ogness
@ 2022-10-20  7:43       ` Greg Kroah-Hartman
  0 siblings, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-20  7:43 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel

On Wed, Oct 19, 2022 at 11:52:53PM +0206, John Ogness wrote:
> On 2022-10-19, Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
> >> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> >> index e4f1e7478b52..867becc40021 100644
> >> --- a/kernel/printk/printk.c
> >> +++ b/kernel/printk/printk.c
> >> @@ -3229,32 +3244,30 @@ int unregister_console(struct console *console)
> >>  	if (res > 0)
> >>  		return 0;
> >>  
> >> -	res = -ENODEV;
> >>  	console_lock();
> >> -	if (console_drivers == console) {
> >> -		console_drivers=console->next;
> >> -		res = 0;
> >> -	} else {
> >> -		for_each_console(con) {
> >> -			if (con->next == console) {
> >> -				con->next = console->next;
> >> -				res = 0;
> >> -				break;
> >> -			}
> >> -		}
> >> +
> >> +	/* Disable it unconditionally */
> >> +	console->flags &= ~CON_ENABLED;
> >> +
> >> +	if (hlist_unhashed(&console->node)) {
> >
> > How can this ever be hit?  The console lock is held, so it shouldn't
> > have gone away already.  Or am I missing something else here?
> 
> Mainline also has this check. I expect it is for the case that some code
> tries to call unregister_console() for a console that is not
> registered.
> 
> Since register_console() does not return if it succeeded, I suppose some
> code somewhere my try to unregister without knowing that it never
> registered in the first place.

Ick, ok, that's fine for now.

What a mess, thanks for working to unwind it!

greg k-h

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 23/38] tty: tty_io: document console_lock usage
  2022-10-19 14:55 ` [PATCH printk v2 23/38] tty: tty_io: " John Ogness
@ 2022-10-20  7:43   ` Greg Kroah-Hartman
  2022-10-25 13:31   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-20  7:43 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby

On Wed, Oct 19, 2022 at 05:01:45PM +0206, John Ogness wrote:
> show_cons_active() uses the console_lock to gather information
> on registered consoles. Since the console_lock is being used for
> multiple reasons, explicitly document these reasons. This will
> be useful when the console_lock is split into fine-grained
> locking.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/tty_io.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
> index 2050e63963bb..333579bfa335 100644
> --- a/drivers/tty/tty_io.c
> +++ b/drivers/tty/tty_io.c
> @@ -3526,6 +3526,14 @@ static ssize_t show_cons_active(struct device *dev,
>  	struct console *c;
>  	ssize_t count = 0;
>  
> +	/*
> +	 * Hold the console_lock to guarantee that no consoles are
> +	 * unregistered until all console processing is complete.
> +	 * This also allows safe traversal of the console list.
> +	 *
> +	 * Stop console printing because the device() callback may
> +	 * assume the console is not within its write() callback.
> +	 */
>  	console_lock();
>  	for_each_console(c) {
>  		if (!c->device)
> -- 
> 2.30.2
> 

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 35/38] tty: tty_io: use console_list_lock for list synchronization
  2022-10-19 14:55 ` [PATCH printk v2 35/38] tty: tty_io: use console_list_lock for list synchronization John Ogness
@ 2022-10-20  7:43   ` Greg Kroah-Hartman
  2022-10-27 10:17   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-20  7:43 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jiri Slaby

On Wed, Oct 19, 2022 at 05:01:57PM +0206, John Ogness wrote:
> show_cons_active() uses the console_lock to gather information
> on registered consoles. It requires that no consoles are unregistered
> until it is finished. The console_list_lock should be used because
> list synchronization repsponsibility will be removed from the
> console_lock in a later change.
> 
> Note, the console_lock is still needed to stop console printing.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 34/38] serial: kgdboc: use console_list_lock instead of console_lock
  2022-10-19 14:55 ` [PATCH printk v2 34/38] serial: kgdboc: use console_list_lock instead of console_lock John Ogness
@ 2022-10-20  7:52   ` Greg Kroah-Hartman
  2022-10-27 10:13   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-20  7:52 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Jiri Slaby, kgdb-bugreport, linux-serial

On Wed, Oct 19, 2022 at 05:01:56PM +0206, John Ogness wrote:
> kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
> are unregistered until the kgdboc_earlycon is setup. The console_list_lock
> should be used instead because list synchronization repsponsibility will
> be removed from the console_lock in a later change.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/kgdboc.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 33/38] printk: introduce console_list_lock
  2022-10-19 14:55 ` [PATCH printk v2 33/38] printk: introduce console_list_lock John Ogness
@ 2022-10-20  7:53   ` Greg Kroah-Hartman
  2022-10-27 10:09   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-20  7:53 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel

On Wed, Oct 19, 2022 at 05:01:55PM +0206, John Ogness wrote:
> Currently there exist races in console_register(), where the types
> of registered consoles are checked (without holding the console_lock)
> and then after acquiring the console_lock, it is assumed that the list
> has not changed. Also, some code that performs console_unregister()
> make similar assumptions.
> 
> Introduce a console_list_lock to provide full synchronization for any
> console list changes. The console_list_lock also provides
> synchronization for updates to console->flags.
> 
> Note that one of the various responsibilities of the console_lock is
> also intended to provide this synchronization. Later changes will
> update call sites relying on the console_lock for this purpose. Once
> all call sites have been updated, the console_lock will be relieved
> of synchronizing console_list and console->flags updates.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  include/linux/console.h | 20 ++++++++--
>  kernel/printk/printk.c  | 82 +++++++++++++++++++++++++++++++++++------
>  2 files changed, 88 insertions(+), 14 deletions(-)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist
  2022-10-19 14:55 ` [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist John Ogness
  2022-10-19 15:44   ` Greg Kroah-Hartman
@ 2022-10-20 12:36   ` Petr Mladek
  2022-10-24  5:23   ` Sergey Senozhatsky
  2 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-20 12:36 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, linux-fsdevel

On Wed 2022-10-19 17:01:24, John Ogness wrote:
> Replace the open coded single linked list with a hlist so a conversion
> to SRCU protected list walks can reuse the existing primitives.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Just one nit below.

> @@ -3229,32 +3244,30 @@ int unregister_console(struct console *console)
>  	if (res > 0)
>  		return 0;
>  
> -	res = -ENODEV;
>  	console_lock();
> -	if (console_drivers == console) {
> -		console_drivers=console->next;
> -		res = 0;
> -	} else {
> -		for_each_console(con) {
> -			if (con->next == console) {
> -				con->next = console->next;
> -				res = 0;
> -				break;
> -			}
> -		}
> +
> +	/* Disable it unconditionally */
> +	console->flags &= ~CON_ENABLED;
> +
> +	if (hlist_unhashed(&console->node)) {
> +		res = -ENODEV;
> +		goto out_unlock;

Nit: It might make sense to replace this with:

		console_unlock();
		return -ENODEV;

This is the only code path using the extra goto target.

It is just an idea. I do not resist on this change.

>  	}
>  
> -	if (res)
> -		goto out_disable_unlock;
> +	hlist_del_init(&console->node);
>  
>  	/*
> +	 * <HISTORICAL>
>  	 * If this isn't the last console and it has CON_CONSDEV set, we
>  	 * need to set it on the next preferred console.
> +	 * </HISTORICAL>
> +	 *
> +	 * The above makes no sense as there is no guarantee that the next
> +	 * console has any device attached. Oh well....
>  	 */
> -	if (console_drivers != NULL && console->flags & CON_CONSDEV)
> -		console_drivers->flags |= CON_CONSDEV;
> +	if (!hlist_empty(&console_list) && console->flags & CON_CONSDEV)
> +		console_first()->flags |= CON_CONSDEV;
>  
> -	console->flags &= ~CON_ENABLED;
>  	console_unlock();
>  	console_sysfs_notify();
>  
> @@ -3263,10 +3276,8 @@ int unregister_console(struct console *console)
>  
>  	return res;
>  
> -out_disable_unlock:
> -	console->flags &= ~CON_ENABLED;
> +out_unlock:
>  	console_unlock();
> -
>  	return res;
>  }
>  EXPORT_SYMBOL(unregister_console);

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection
  2022-10-19 14:55 ` [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection John Ogness
  2022-10-19 15:16   ` Miguel Ojeda
  2022-10-19 17:12   ` Paul E. McKenney
@ 2022-10-21  8:34   ` Petr Mladek
  2022-10-31 13:06     ` John Ogness
  2 siblings, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-10-21  8:34 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Miguel Ojeda, Paul E. McKenney, Greg Kroah-Hartman

On Wed 2022-10-19 17:01:25, John Ogness wrote:
> Provide an NMI-safe SRCU protected variant to walk the console list.
> 
> Note that all console fields are now set before adding the console
> to the list to avoid the console becoming visible by SCRU readers
> before being fully initialized.
> 
> This is a preparatory change for a new console infrastructure which
> operates independent of the console BKL.
> 
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -15,7 +15,7 @@
>  #define _LINUX_CONSOLE_H_ 1
>  
>  #include <linux/atomic.h>
> -#include <linux/list.h>
> +#include <linux/rculist.h>
>  #include <linux/types.h>
>  
>  struct vc_data;
> @@ -158,8 +158,34 @@ struct console {
>  	struct hlist_node node;
>  };
>  
> +#ifdef CONFIG_LOCKDEP

srcu_read_lock_held() actually depends on CONFIG_DEBUG_LOCK_ALLOC.
I suggest to avoid these problems and define:


extern struct srcu_struct console_srcu;

static inline bool console_srcu_read_lock_is_held(void)
{
	return srcu_read_lock_held(&console_srcu);
}

I guess that you wanted to keep console_srcu static to avoid
a misuse. It is true that we need to keep it NMI safe.

I do not have a strong opinion. I would personally risk it
and make it public. The CONFIG_* dependencies are hard to
maintain. We could add a comment that people need to use
the NMI safe API when manipulating the context.

> +extern bool console_srcu_read_lock_is_held(void);
> +#else
> +static inline bool console_srcu_read_lock_is_held(void)
> +{
> +	return 1;
> +}
> +#endif
> +
> +extern int console_srcu_read_lock(void);
> +extern void console_srcu_read_unlock(int cookie);
> +
>  extern struct hlist_head console_list;
>  
> +/**
> + * for_each_console_srcu() - Iterator over registered consoles
> + * @con:	struct console pointer used as loop cursor
> + *
> + * Although SRCU guarantees the console list will be consistent, the
> + * struct console fields may be updated by other CPUs while iterating.
> + *
> + * Requires console_srcu_read_lock to be held. Can be invoked from
> + * any context.
> + */
> +#define for_each_console_srcu(con)					\
> +	hlist_for_each_entry_srcu(con, &console_list, node,		\
> +				  console_srcu_read_lock_is_held())
> +
>  /*
>   * for_each_console() allows you to iterate on each console
>   */
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 867becc40021..e8a56056cd50 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2989,6 +3021,9 @@ void console_stop(struct console *console)
>  	console_lock();
>  	console->flags &= ~CON_ENABLED;
>  	console_unlock();
> +
> +	/* Ensure that all SRCU list walks have completed */
> +	synchronize_srcu(&console_srcu);

The comment is not much helpful. It describes the behavior
that is more or less obvious. The important question
is why it is needed. And it is not clear to me.

What is the motivation for this synchronization, please?

This function disables one particular console. What exact walk are
we waiting for, please?

Is it really needed?

>  }
>  EXPORT_SYMBOL(console_stop);
>  
> @@ -3179,6 +3214,17 @@ void register_console(struct console *newcon)
>  		newcon->flags &= ~CON_PRINTBUFFER;
>  	}
>  
> +	newcon->dropped = 0;
> +	if (newcon->flags & CON_PRINTBUFFER) {
> +		/* Get a consistent copy of @syslog_seq. */
> +		mutex_lock(&syslog_lock);
> +		newcon->seq = syslog_seq;
> +		mutex_unlock(&syslog_lock);
> +	} else {
> +		/* Begin with next message. */
> +		newcon->seq = prb_next_seq(prb);

Hmm, prb_next_seq() is the next-to-be written message. It does not
guarantee that all the existing messages already reached the boot console.

This used to be synchronized by console_lock(). But we broke this
by the commit a699449bb13b70b8bd10d ("printk: refactor and rework
printing logic") that removed the global console_seq.

It actually kind of worked because console_unlock() was called before
the boot consoles were removed. So that the boot console
printed the pending messages before it was removed. Except when
the console lock was passed to another printk() caller.

Ideally, we should set it to con->seq from the related boot consoles.
But we do not know which one it is.

A good enough solution would be to set it to the minimal con->seq
of all registered boot consoles. They would most likely be on
the same sequence number. Anyway, con->seq has to be read under
console_lock() at least at this stage of the patchset.


> +	}
> +
>  	/*
>  	 * Put this console in the list - keep the
>  	 * preferred driver at the head of the list.
> @@ -3187,28 +3233,20 @@ void register_console(struct console *newcon)
>  	if (hlist_empty(&console_list)) {
>  		/* Ensure CON_CONSDEV is always set for the head. */
>  		newcon->flags |= CON_CONSDEV;
> -		hlist_add_head(&newcon->node, &console_list);
> +		hlist_add_head_rcu(&newcon->node, &console_list);
>  
>  	} else if (newcon->flags & CON_CONSDEV) {
>  		/* Only the new head can have CON_CONSDEV set. */
>  		console_first()->flags &= ~CON_CONSDEV;
> -		hlist_add_head(&newcon->node, &console_list);
> +		hlist_add_head_rcu(&newcon->node, &console_list);
>  
>  	} else {
> -		hlist_add_behind(&newcon->node, console_list.first);
> -	}
> -
> -	newcon->dropped = 0;
> -	if (newcon->flags & CON_PRINTBUFFER) {
> -		/* Get a consistent copy of @syslog_seq. */
> -		mutex_lock(&syslog_lock);
> -		newcon->seq = syslog_seq;
> -		mutex_unlock(&syslog_lock);
> -	} else {
> -		/* Begin with next message. */
> -		newcon->seq = prb_next_seq(prb);
> +		hlist_add_behind_rcu(&newcon->node, console_list.first);
>  	}
>  	console_unlock();
> +
> +	/* No need to synchronize SRCU here! */

This would deserve explanation why it is not needed. At least some
hint.

I think that it is not needed here. I can't think about any function
that would depend on it.

Anyway, I do not see any difference against console_stop(). I do not
understand why the synchronization is needed there and not here.

> +
>  	console_sysfs_notify();
>  
>  	/*
> @@ -3254,7 +3292,7 @@ int unregister_console(struct console *console)
>  		goto out_unlock;
>  	}
>  
> -	hlist_del_init(&console->node);
> +	hlist_del_init_rcu(&console->node);
>  
>  	/*
>  	 * <HISTORICAL>
> @@ -3269,6 +3307,10 @@ int unregister_console(struct console *console)
>  		console_first()->flags |= CON_CONSDEV;
>  
>  	console_unlock();
> +
> +	/* Ensure that all SRCU list walks have completed */
> +	synchronize_srcu(&console_srcu);

Again, we should explain why.

I agree that it should be there. It makes sure that the driver
is not longer used for printing messages before it can be removed.

> +
>  	console_sysfs_notify();
>  
>  	if (console->exit)
> -- 
> 2.30.2

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper
  2022-10-19 14:55 ` [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper John Ogness
  2022-10-19 16:01   ` Greg Kroah-Hartman
@ 2022-10-21  8:57   ` Petr Mladek
  2022-10-21  9:37     ` Petr Mladek
  1 sibling, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-10-21  8:57 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman

On Wed 2022-10-19 17:01:26, John Ogness wrote:
> After switching to SRCU for console list iteration, some readers
> will begin accessing console->flags as a data race. This is safe
> because there is at most one CPU modifying console->flags and
> using rmw operations.
> 
> The primary reason for readers to access console->flags is to
> check if the console is enabled. Introduce console_is_enabled()
> to mark such access as a data race.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  include/linux/console.h | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/include/linux/console.h b/include/linux/console.h
> index cff86cc615f8..60195cd086dc 100644
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -172,6 +172,26 @@ extern void console_srcu_read_unlock(int cookie);
>  
>  extern struct hlist_head console_list;
>  
> +/**
> + * console_is_enabled - Check if the console is enabled
> + * @con:	struct console pointer of console to check
> + *
> + * This should be used instead of manually testing for the CON_ENABLED
> + * bit in the console->flags.
> + *
> + * Context: Any context.
> + */
> +static inline bool console_is_enabled(const struct console *con)
> +{
> +	/*
> +	 * If SRCU is used, reading of console->flags can be a data
> +	 * race. However, this is safe because there is at most one
> +	 * CPU modifying console->flags and it is using only
> +	 * read-modify-write operations to do so.

Hmm, I somehow do not understand the explanation. How does
read-modify-write operation make this safe, please?

We are interested into one bit. IMHO, it is not important
if the flags variable is modified atomically or byte by byte.
The important thing is if the reading is synchronized against
modifications.

This function does not do any synchronization on its own.
So, it depends on the caller.


I would personally do two variants. for example:

    console_is_enabled()
    console_is_enabled_safe()

The first variant would be called in situations where the race
does not matter and the other when it matters.



> +	 */
> +	return (data_race(READ_ONCE(con->flags)) & CON_ENABLED);
> +}
> +
>  /**
>   * for_each_console_srcu() - Iterator over registered consoles
>   * @con:	struct console pointer used as loop cursor

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 05/38] printk: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 05/38] printk: use console_is_enabled() John Ogness
@ 2022-10-21  9:25   ` Petr Mladek
  2022-10-31 15:39     ` John Ogness
  0 siblings, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-10-21  9:25 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:27, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  kernel/printk/printk.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index e8a56056cd50..7ff2fc75fc3b 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2658,7 +2658,7 @@ static bool abandon_console_lock_in_panic(void)
>   */
>  static inline bool console_is_usable(struct console *con)
>  {
> -	if (!(con->flags & CON_ENABLED))
> +	if (!console_is_enabled(con))
>  		return false;

This allows to use console_is_usable() without synchronization against
modification of the state. I guess that it will be needed for the
printk kthreads. But it is not needed at the moment.

We should document why it is needed and why it is safe.


>  
>  	if (!con->write)
> @@ -2944,7 +2944,7 @@ void console_unblank(void)
>  	console_locked = 1;
>  	console_may_schedule = 0;
>  	for_each_console(c)
> -		if ((c->flags & CON_ENABLED) && c->unblank)
> +		if (console_is_enabled(c) && c->unblank)
>  			c->unblank();
>  	console_unlock();

The reading of the flag is actually synchronized against modifications
here. I guess that we need this because c->unblank() probably is not safe
against other operations with the console, e.g. c->write().

Well, it probably does not matter if reading of CON_ENABLED flag is
serialized against modifications. So, it is perfectly fine to use
the "racy" function.


> @@ -3098,7 +3098,7 @@ static int try_enable_preferred_console(struct console *newcon,
>  	 * without matching. Accept the pre-enabled consoles only when match()
>  	 * and setup() had a chance to be called.
>  	 */
> -	if (newcon->flags & CON_ENABLED && c->user_specified ==	user_specified)
> +	if (console_is_enabled(newcon) && (c->user_specified == user_specified))

This is not racy because newcon is not in console_list at this
point. So that the state can't be modified by another callers.

Anyway, it is not explicitly synchronized, so we need to use
console_is_enabled with data_race() annotation.


>  		return 0;
>  
>  	return -ENOENT;

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper
  2022-10-21  8:57   ` Petr Mladek
@ 2022-10-21  9:37     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21  9:37 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman

On Fri 2022-10-21 10:57:58, Petr Mladek wrote:
> On Wed 2022-10-19 17:01:26, John Ogness wrote:
> > After switching to SRCU for console list iteration, some readers
> > will begin accessing console->flags as a data race. This is safe
> > because there is at most one CPU modifying console->flags and
> > using rmw operations.
> > 
> > The primary reason for readers to access console->flags is to
> > check if the console is enabled. Introduce console_is_enabled()
> > to mark such access as a data race.
> > 
> > Signed-off-by: John Ogness <john.ogness@linutronix.de>
> > ---
> >  include/linux/console.h | 20 ++++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> > 
> > diff --git a/include/linux/console.h b/include/linux/console.h
> > index cff86cc615f8..60195cd086dc 100644
> > --- a/include/linux/console.h
> > +++ b/include/linux/console.h
> > @@ -172,6 +172,26 @@ extern void console_srcu_read_unlock(int cookie);
> >  
> >  extern struct hlist_head console_list;
> >  
> > +/**
> > + * console_is_enabled - Check if the console is enabled
> > + * @con:	struct console pointer of console to check
> > + *
> > + * This should be used instead of manually testing for the CON_ENABLED
> > + * bit in the console->flags.
> > + *
> > + * Context: Any context.
> > + */
> > +static inline bool console_is_enabled(const struct console *con)
> > +{
> > +	/*
> > +	 * If SRCU is used, reading of console->flags can be a data
> > +	 * race. However, this is safe because there is at most one
> > +	 * CPU modifying console->flags and it is using only
> > +	 * read-modify-write operations to do so.
> 
> Hmm, I somehow do not understand the explanation. How does
> read-modify-write operation make this safe, please?
> 
> We are interested into one bit. IMHO, it is not important
> if the flags variable is modified atomically or byte by byte.
> The important thing is if the reading is synchronized against
> modifications.
> 
> This function does not do any synchronization on its own.
> So, it depends on the caller.
> 
> 
> I would personally do two variants. for example:
> 
>     console_is_enabled()
>     console_is_enabled_safe()
> 
> The first variant would be called in situations where the race
> does not matter and the other when it matters.

Still thinking about it.

It is possible that console_is_enabled_safe() variant won't be
needed because all the callers will be either naturally serialized
or can be racy.

By other words, it makes sense to use data_race() because there are
used racy checks. And there probably is not any caller that would
strictly require explicit synchronization when reading this flag.

Anyway, if there is any caller that would require explicit
synchronization than we need a variant without data_race().

It would be great to somehow explain this in the commit message.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 06/38] tty: nfcon: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 06/38] tty: nfcon: " John Ogness
@ 2022-10-21  9:55   ` Petr Mladek
  2022-10-31 15:59     ` John Ogness
  0 siblings, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-10-21  9:55 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Geert Uytterhoeven, linux-m68k

On Wed 2022-10-19 17:01:28, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  arch/m68k/emu/nfcon.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c
> index 557d60867f98..c542fc2b121f 100644
> --- a/arch/m68k/emu/nfcon.c
> +++ b/arch/m68k/emu/nfcon.c
> @@ -49,7 +49,7 @@ static void nfcon_write(struct console *con, const char *str,
>  static struct tty_driver *nfcon_device(struct console *con, int *index)
>  {
>  	*index = 0;
> -	return (con->flags & CON_ENABLED) ? nfcon_tty_driver : NULL;
> +	return console_is_enabled(con) ? nfcon_tty_driver : NULL;
>  }
>  
>  static struct console nf_console = {
> @@ -151,7 +151,7 @@ static int __init nfcon_init(void)
>  
>  	nfcon_tty_driver = driver;
>  
> -	if (!(nf_console.flags & CON_ENABLED))
> +	if (!console_is_enabled(&nf_console))

Heh, the check of CON_ENABLED does not make much sense. IMHO, the important
thing is whether the console is in console_list or not.

I would personally add a check at the beginning of register_console()
whether the console is already registered and enabled() and do
nothing when already done.

I would be nice to fix this. But it might be done later.

The replacement is straightforward. Both checks are or might be racy.
Feel free to use:

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

>  		register_console(&nf_console);
>  
>  	return 0;


^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 07/38] um: kmsg_dump: use console_is_enabled()
  2022-10-19 14:55   ` John Ogness
@ 2022-10-21 12:46     ` Petr Mladek
  -1 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 12:46 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Richard Weinberger, Anton Ivanov, Johannes Berg,
	linux-um

On Wed 2022-10-19 17:01:29, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 07/38] um: kmsg_dump: use console_is_enabled()
@ 2022-10-21 12:46     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 12:46 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Richard Weinberger, Anton Ivanov, Johannes Berg,
	linux-um

On Wed 2022-10-19 17:01:29, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 08/38] efi: earlycon: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 08/38] efi: earlycon: " John Ogness
  2022-10-19 15:32   ` Ard Biesheuvel
@ 2022-10-21 12:53   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 12:53 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Ard Biesheuvel, linux-efi

On Wed 2022-10-19 17:01:30, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 09/38] netconsole: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 09/38] netconsole: " John Ogness
@ 2022-10-21 13:14   ` Petr Mladek
  2022-11-04 15:12     ` John Ogness
  0 siblings, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 13:14 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, netdev

On Wed 2022-10-19 17:01:31, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

The change is straightforward:

Reviewed-by: Petr Mladek <pmladek@suse.com>

The comment below is just a lamentation about the netconsole code.

> ---
>  drivers/net/netconsole.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
> index bdff9ac5056d..073e59a06f21 100644
> --- a/drivers/net/netconsole.c
> +++ b/drivers/net/netconsole.c
> @@ -332,7 +332,7 @@ static ssize_t enabled_store(struct config_item *item,
>  	}
>  
>  	if (enabled) {	/* true */
> -		if (nt->extended && !(netconsole_ext.flags & CON_ENABLED)) {
> +		if (nt->extended && !console_is_enabled(&netconsole_ext)) {
>  			netconsole_ext.flags |= CON_ENABLED;
>  			register_console(&netconsole_ext);
>  		}
> @@ -915,7 +915,7 @@ static int __init init_netconsole(void)
>  	if (err)
>  		goto undonotifier;
>  
> -	if (netconsole_ext.flags & CON_ENABLED)
> +	if (console_is_enabled(&netconsole_ext))
>  		register_console(&netconsole_ext);
>  	register_console(&netconsole);
>  	pr_info("network logging started\n");

Just for record:

This looks like a (mis)use of CON_ENABLED flag. It took me some time
to understand why pre-enabled consoles are handled special way in
register_console(). I partly documented it in
try_enable_preferred_console():

	/*
	 * Some consoles, such as pstore and netconsole, can be enabled even
	 * without matching. Accept the pre-enabled consoles only when match()
	 * and setup() had a chance to be called.
	 */
	if (console_is_enabled(newcon) && (c->user_specified == user_specified))
		return 0;

In my bottom driver, I have a patch cleaning this. It is part of a bigger
clean up that is not ready for upstream :-/

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 10/38] tty: hvc: use console_is_enabled()
  2022-10-19 14:55   ` John Ogness
@ 2022-10-21 13:22     ` Petr Mladek
  -1 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 13:22 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, Shile Zhang,
	Xianting Tian, linuxppc-dev

On Wed 2022-10-19 17:01:32, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/hvc/hvc_console.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
> index 4802cfaa107f..6d1d7b72488c 100644
> --- a/drivers/tty/hvc/hvc_console.c
> +++ b/drivers/tty/hvc/hvc_console.c
> @@ -265,7 +265,7 @@ static void hvc_port_destruct(struct tty_port *port)
>  static void hvc_check_console(int index)
>  {
>  	/* Already enabled, bail out */
> -	if (hvc_console.flags & CON_ENABLED)
> +	if (console_is_enabled(&hvc_console))
>  		return;

The check is not reliable. The console might be disabled even when
it is already registered.

I would be nice to fix this. But it might be done later.
Feel free to use:

Reviewed-by: Petr Mladek <pmladek@suse.com>

>  
>   	/* If this index is what the user requested, then register

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 10/38] tty: hvc: use console_is_enabled()
@ 2022-10-21 13:22     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 13:22 UTC (permalink / raw)
  To: John Ogness
  Cc: linuxppc-dev, Xianting Tian, Greg Kroah-Hartman, Shile Zhang,
	linux-kernel, Steven Rostedt, Sergey Senozhatsky,
	Thomas Gleixner, Jiri Slaby

On Wed 2022-10-19 17:01:32, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/hvc/hvc_console.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
> index 4802cfaa107f..6d1d7b72488c 100644
> --- a/drivers/tty/hvc/hvc_console.c
> +++ b/drivers/tty/hvc/hvc_console.c
> @@ -265,7 +265,7 @@ static void hvc_port_destruct(struct tty_port *port)
>  static void hvc_check_console(int index)
>  {
>  	/* Already enabled, bail out */
> -	if (hvc_console.flags & CON_ENABLED)
> +	if (console_is_enabled(&hvc_console))
>  		return;

The check is not reliable. The console might be disabled even when
it is already registered.

I would be nice to fix this. But it might be done later.
Feel free to use:

Reviewed-by: Petr Mladek <pmladek@suse.com>

>  
>   	/* If this index is what the user requested, then register

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 11/38] tty: serial: earlycon: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 11/38] tty: serial: earlycon: " John Ogness
  2022-10-19 16:01   ` Greg Kroah-Hartman
@ 2022-10-21 13:51   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 13:51 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, linux-serial

On Wed 2022-10-19 17:01:33, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 12/38] tty: serial: kgdboc: " John Ogness
  2022-10-19 16:00   ` Greg Kroah-Hartman
@ 2022-10-21 14:10   ` Petr Mladek
  2022-10-24 22:46   ` Doug Anderson
  2 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:10 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

On Wed 2022-10-19 17:01:34, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 13/38] tty: serial: pic32_uart: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 13/38] tty: serial: pic32_uart: " John Ogness
  2022-10-19 16:01   ` Greg Kroah-Hartman
@ 2022-10-21 14:11   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:11 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, linux-serial

On Wed 2022-10-19 17:01:35, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 14/38] tty: serial: samsung_tty: use console_is_enabled()
  2022-10-19 14:55   ` John Ogness
@ 2022-10-21 14:14     ` Petr Mladek
  -1 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:14 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Krzysztof Kozlowski, Alim Akhtar,
	Greg Kroah-Hartman, Jiri Slaby, linux-arm-kernel,
	linux-samsung-soc, linux-serial

On Wed 2022-10-19 17:01:36, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/samsung_tty.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 77d1363029f5..8142a0e53ffa 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -1732,7 +1732,7 @@ static void __init s3c24xx_serial_register_console(void)
>  
>  static void s3c24xx_serial_unregister_console(void)
>  {
> -	if (s3c24xx_serial_console.flags & CON_ENABLED)
> +	if (console_is_enabled(&s3c24xx_serial_console))
>  		unregister_console(&s3c24xx_serial_console);
>  }

As on many other locations, it would be better to check if the console
is in console_list. CON_ENABLED might be disabled even when the
console is registered.

It would be nice to fix this. But it might be done later.

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 14/38] tty: serial: samsung_tty: use console_is_enabled()
@ 2022-10-21 14:14     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:14 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Krzysztof Kozlowski, Alim Akhtar,
	Greg Kroah-Hartman, Jiri Slaby, linux-arm-kernel,
	linux-samsung-soc, linux-serial

On Wed 2022-10-19 17:01:36, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/samsung_tty.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 77d1363029f5..8142a0e53ffa 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -1732,7 +1732,7 @@ static void __init s3c24xx_serial_register_console(void)
>  
>  static void s3c24xx_serial_unregister_console(void)
>  {
> -	if (s3c24xx_serial_console.flags & CON_ENABLED)
> +	if (console_is_enabled(&s3c24xx_serial_console))
>  		unregister_console(&s3c24xx_serial_console);
>  }

As on many other locations, it would be better to check if the console
is in console_list. CON_ENABLED might be disabled even when the
console is registered.

It would be nice to fix this. But it might be done later.

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 15/38] tty: serial: serial_core: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 15/38] tty: serial: serial_core: " John Ogness
  2022-10-19 16:00   ` Greg Kroah-Hartman
@ 2022-10-21 14:14   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:14 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, linux-serial

On Wed 2022-10-19 17:01:37, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 16/38] tty: serial: xilinx_uartps: use console_is_enabled()
  2022-10-19 14:55   ` John Ogness
@ 2022-10-21 14:23     ` Petr Mladek
  -1 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:23 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, Michal Simek,
	linux-serial, linux-arm-kernel

On Wed 2022-10-19 17:01:38, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index 2eff7cff57c4..e1fe95bd55c1 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -1631,7 +1631,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
>  #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
>  	/* This is not port which is used for console that's why clean it up */
>  	if (console_port == port &&
> -	    !(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) {
> +	    !console_is_enabled(cdns_uart_uart_driver.cons)) {
>  		console_port = NULL;
>  		cdns_uart_console.index = -1;

Again, IMHO, we should check here if the console is in console_list.
We should not clean the port and index when the console is already
registered.

Again, this is old problem that might be fixed later.

The change is straightforward. Feel free to use:

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 16/38] tty: serial: xilinx_uartps: use console_is_enabled()
@ 2022-10-21 14:23     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:23 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby, Michal Simek,
	linux-serial, linux-arm-kernel

On Wed 2022-10-19 17:01:38, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index 2eff7cff57c4..e1fe95bd55c1 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -1631,7 +1631,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
>  #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
>  	/* This is not port which is used for console that's why clean it up */
>  	if (console_port == port &&
> -	    !(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) {
> +	    !console_is_enabled(cdns_uart_uart_driver.cons)) {
>  		console_port = NULL;
>  		cdns_uart_console.index = -1;

Again, IMHO, we should check here if the console is in console_list.
We should not clean the port and index when the console is already
registered.

Again, this is old problem that might be fixed later.

The change is straightforward. Feel free to use:

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 17/38] tty: tty_io: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 17/38] tty: tty_io: " John Ogness
  2022-10-19 16:00   ` Greg Kroah-Hartman
@ 2022-10-21 14:24   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:24 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby

On Wed 2022-10-19 17:01:39, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 18/38] usb: early: xhci-dbc: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 18/38] usb: early: xhci-dbc: " John Ogness
  2022-10-19 16:01   ` Greg Kroah-Hartman
@ 2022-10-21 14:27   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:27 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Peter Zijlstra, Mike Rapoport,
	Mathias Nyman, Andrew Morton, linux-usb

On Wed 2022-10-19 17:01:40, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/usb/early/xhci-dbc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c
> index bfb7e2b85299..b1a9c393160b 100644
> --- a/drivers/usb/early/xhci-dbc.c
> +++ b/drivers/usb/early/xhci-dbc.c
> @@ -927,7 +927,7 @@ void __init early_xdbc_register_console(void)
>  
>  static void xdbc_unregister_console(void)
>  {
> -	if (early_xdbc_console.flags & CON_ENABLED)
> +	if (console_is_enabled(&early_xdbc_console))
>  		unregister_console(&early_xdbc_console);
>  }

Again, we should rather check here if the console is in console_list.

But it is old bug. It might be fixed later. The patch does not change
the existing behavior. Feel free to use:

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 19/38] kdb: kdb_io: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 19/38] kdb: kdb_io: " John Ogness
@ 2022-10-21 14:28   ` Petr Mladek
  2022-10-25  0:34   ` Doug Anderson
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:28 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Luis Chamberlain, Aaron Tomlin, kgdb-bugreport

On Wed 2022-10-19 17:01:41, John Ogness wrote:
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 20/38] um: kmsg_dumper: use srcu console list iterator
  2022-10-19 14:55   ` John Ogness
@ 2022-10-21 14:56     ` Petr Mladek
  -1 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:56 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Richard Weinberger, Anton Ivanov, Johannes Berg,
	Thomas Meyer, linux-um

On Wed 2022-10-19 17:01:42, John Ogness wrote:
> Rather than using the console_lock to guarantee safe console list
> traversal, use srcu console list iteration.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  arch/um/kernel/kmsg_dump.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
> index 3a3bbbb22090..44a418dec919 100644
> --- a/arch/um/kernel/kmsg_dump.c
> +++ b/arch/um/kernel/kmsg_dump.c
> @@ -16,20 +16,17 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
>  	struct console *con;
>  	unsigned long flags;
>  	size_t len = 0;
> +	int cookie;
>  
>  	/* only dump kmsg when no console is available */

I agree that it is perfectly fine to use RCU here. The previous
code was just a best effort. The kdump was done without console_lock()
so that the console might get available in the meantime.

I guess that it is not a big deal. The dumper is called typically only
during panic() where new consoles are not added.

> -	if (!console_trylock())
> -		return;
> -
> -	for_each_console(con) {
> +	cookie = console_srcu_read_lock();
> +	for_each_console_srcu(con) {
>  		if (strcmp(con->name, "tty") == 0 &&
>  		    (console_is_enabled(con) || (con->flags & CON_CONSDEV))) {

This is slightly more racy than the previous code. Only one console
could have CON_CONSDEV. It might be moved to another console when the
list is manipulated. As a result, rcu walk might see zero, one, or two
consoles with this flag unless the flag is moved carefully.

Anyway, this check does not match the comment and does not make much
sense to me. It is true that CON_CONSDEV flag is used only for
registered consoles. But messages are printed on the console only
when CON_ENABLED flag is set.

IMHO, we should check only console_is_enabled() here.

Adding Thomas Meyer and Richard Weinberger <richard@nod.at> into Cc.
Thomas added this check in the commit e23fe90dec286cd77e90
("um: kmsg_dumper: always dump when not tty console") and
Richard pushed it.

>  			break;
>  		}
>  	}
> -
> -	console_unlock();
> -
> +	console_srcu_read_unlock(cookie);
>
>  	if (con)
>  		return;

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 20/38] um: kmsg_dumper: use srcu console list iterator
@ 2022-10-21 14:56     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 14:56 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Richard Weinberger, Anton Ivanov, Johannes Berg,
	Thomas Meyer, linux-um

On Wed 2022-10-19 17:01:42, John Ogness wrote:
> Rather than using the console_lock to guarantee safe console list
> traversal, use srcu console list iteration.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  arch/um/kernel/kmsg_dump.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
> index 3a3bbbb22090..44a418dec919 100644
> --- a/arch/um/kernel/kmsg_dump.c
> +++ b/arch/um/kernel/kmsg_dump.c
> @@ -16,20 +16,17 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
>  	struct console *con;
>  	unsigned long flags;
>  	size_t len = 0;
> +	int cookie;
>  
>  	/* only dump kmsg when no console is available */

I agree that it is perfectly fine to use RCU here. The previous
code was just a best effort. The kdump was done without console_lock()
so that the console might get available in the meantime.

I guess that it is not a big deal. The dumper is called typically only
during panic() where new consoles are not added.

> -	if (!console_trylock())
> -		return;
> -
> -	for_each_console(con) {
> +	cookie = console_srcu_read_lock();
> +	for_each_console_srcu(con) {
>  		if (strcmp(con->name, "tty") == 0 &&
>  		    (console_is_enabled(con) || (con->flags & CON_CONSDEV))) {

This is slightly more racy than the previous code. Only one console
could have CON_CONSDEV. It might be moved to another console when the
list is manipulated. As a result, rcu walk might see zero, one, or two
consoles with this flag unless the flag is moved carefully.

Anyway, this check does not match the comment and does not make much
sense to me. It is true that CON_CONSDEV flag is used only for
registered consoles. But messages are printed on the console only
when CON_ENABLED flag is set.

IMHO, we should check only console_is_enabled() here.

Adding Thomas Meyer and Richard Weinberger <richard@nod.at> into Cc.
Thomas added this check in the commit e23fe90dec286cd77e90
("um: kmsg_dumper: always dump when not tty console") and
Richard pushed it.

>  			break;
>  		}
>  	}
> -
> -	console_unlock();
> -
> +	console_srcu_read_unlock(cookie);
>
>  	if (con)
>  		return;

Best Regards,
Petr

_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 21/38] serial: kgdboc: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 21/38] serial: kgdboc: " John Ogness
  2022-10-19 16:02   ` Greg Kroah-Hartman
@ 2022-10-21 15:09   ` Petr Mladek
  2022-10-25  0:33     ` Doug Anderson
  1 sibling, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-10-21 15:09 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

On Wed 2022-10-19 17:01:43, John Ogness wrote:
> Use srcu console list iteration for safe console list traversal.
>
> Note that configure_kgdboc() still requires the console_lock in
> order to ensure that no console is in its write() callback when
> its direct() callback is called. Add comments to clarify this.

s/direct()/device()/

Do you know about such requirements or is it just
a conservative approach, please?

I ask because the comment in the code says "may assume".


Anyway, this would deserve a comment why the SRCU list iteration is
needed even when console_lock() is needed as well.

The reason is that further patches are going to synchronize
console_list manipulation with another lock and console_lock()
will be used only to serialize accessing con->write() callbacks.

Best Regards,
Petr

> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/kgdboc.c | 21 ++++++++++++++++++---
>  1 file changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
> index b17aa7e49894..e9d3f8c6e3dc 100644
> --- a/drivers/tty/serial/kgdboc.c
> +++ b/drivers/tty/serial/kgdboc.c
> @@ -171,6 +171,7 @@ static int configure_kgdboc(void)
>  	int err = -ENODEV;
>  	char *cptr = config;
>  	struct console *cons;
> +	int cookie;
>  
>  	if (!strlen(config) || isspace(config[0])) {
>  		err = 0;
> @@ -193,8 +194,14 @@ static int configure_kgdboc(void)
>  	if (!p)
>  		goto noconfig;
>  
> +	/*
> +	 * Stop console printing because the device() callback may
> +	 * assume the console is not within its write() callback.
> +	 */
>  	console_lock();
> -	for_each_console(cons) {
> +
> +	cookie = console_srcu_read_lock();
> +	for_each_console_srcu(cons) {
>  		int idx;
>  		if (cons->device && cons->device(cons, &idx) == p &&
>  		    idx == tty_line) {
> @@ -202,6 +209,8 @@ static int configure_kgdboc(void)
>  			break;
>  		}
>  	}
> +	console_srcu_read_unlock(cookie);
> +
>  	console_unlock();
>  
>  	kgdb_tty_driver = p;
> @@ -451,6 +460,7 @@ static void kgdboc_earlycon_pre_exp_handler(void)
>  {
>  	struct console *con;
>  	static bool already_warned;
> +	int cookie;
>  
>  	if (already_warned)
>  		return;
> @@ -463,9 +473,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");
> -- 
> 2.30.2

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function
  2022-10-19 14:55 ` [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function John Ogness
  2022-10-19 15:41   ` Greg Kroah-Hartman
@ 2022-10-24  5:22   ` Sergey Senozhatsky
  2022-10-25  0:34   ` Doug Anderson
  2 siblings, 0 replies; 151+ messages in thread
From: Sergey Senozhatsky @ 2022-10-24  5:22 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

On (22/10/19 17:01), John Ogness wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
> 
> Unprotected list walks are not necessarily safe.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> Reviewed-by: Petr Mladek <pmladek@suse.com>

Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist
  2022-10-19 14:55 ` [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist John Ogness
  2022-10-19 15:44   ` Greg Kroah-Hartman
  2022-10-20 12:36   ` Petr Mladek
@ 2022-10-24  5:23   ` Sergey Senozhatsky
  2 siblings, 0 replies; 151+ messages in thread
From: Sergey Senozhatsky @ 2022-10-24  5:23 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, linux-fsdevel

On (22/10/19 17:01), John Ogness wrote:
> Replace the open coded single linked list with a hlist so a conversion
> to SRCU protected list walks can reuse the existing primitives.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 12/38] tty: serial: kgdboc: " John Ogness
  2022-10-19 16:00   ` Greg Kroah-Hartman
  2022-10-21 14:10   ` Petr Mladek
@ 2022-10-24 22:46   ` Doug Anderson
  2022-10-25  0:49     ` Doug Anderson
  2 siblings, 1 reply; 151+ messages in thread
From: Doug Anderson @ 2022-10-24 22:46 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Greg Kroah-Hartman,
	Jiri Slaby, kgdb-bugreport, linux-serial

Hi,

On Wed, Oct 19, 2022 at 7:56 AM John Ogness <john.ogness@linutronix.de> wrote:
>
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/kgdboc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
> index e76f0186c335..b17aa7e49894 100644
> --- a/drivers/tty/serial/kgdboc.c
> +++ b/drivers/tty/serial/kgdboc.c
> @@ -533,7 +533,7 @@ static int __init kgdboc_earlycon_init(char *opt)
>         console_lock();
>         for_each_console(con) {
>                 if (con->write && con->read &&
> -                   (con->flags & (CON_BOOT | CON_ENABLED)) &&
> +                   (console_is_enabled(con) || (con->flags & CON_BOOT)) &&

<shrug>. I guess this is OK, but it feels a little pointless. If we're
still directly looking at the CON_BOOT bit in con->flags it seems
weird to be accessing CON_ENABLED through a special wrapper that's
marked as a `data_race`. In our case it's _not_ a data race, right,
since this function continues to hold the console_lock() even at the
end of the series? I personally would drop this patch but if you
really want it I won't object.

-Doug

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 21/38] serial: kgdboc: use srcu console list iterator
  2022-10-21 15:09   ` Petr Mladek
@ 2022-10-25  0:33     ` Doug Anderson
  0 siblings, 0 replies; 151+ messages in thread
From: Doug Anderson @ 2022-10-25  0:33 UTC (permalink / raw)
  To: Petr Mladek
  Cc: John Ogness, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Greg Kroah-Hartman,
	Jiri Slaby, kgdb-bugreport, linux-serial

Hi,

On Fri, Oct 21, 2022 at 8:09 AM Petr Mladek <pmladek@suse.com> wrote:
>
> On Wed 2022-10-19 17:01:43, John Ogness wrote:
> > Use srcu console list iteration for safe console list traversal.
> >
> > Note that configure_kgdboc() still requires the console_lock in
> > order to ensure that no console is in its write() callback when
> > its direct() callback is called. Add comments to clarify this.
>
> s/direct()/device()/
>
> Do you know about such requirements or is it just
> a conservative approach, please?
>
> I ask because the comment in the code says "may assume".
>
>
> Anyway, this would deserve a comment why the SRCU list iteration is
> needed even when console_lock() is needed as well.
>
> The reason is that further patches are going to synchronize
> console_list manipulation with another lock and console_lock()
> will be used only to serialize accessing con->write() callbacks.

I had the same concern. I'll note that at the end of the series the
documentation for console_lock() still says:

 * Acquires a lock which guarantees that the caller has
 * exclusive access to the console system.

That seems to imply (at least to me) that if you're holding
console_lock() there's no need to hold the SRCU lock.

-Doug

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 19/38] kdb: kdb_io: use console_is_enabled()
  2022-10-19 14:55 ` [PATCH printk v2 19/38] kdb: kdb_io: " John Ogness
  2022-10-21 14:28   ` Petr Mladek
@ 2022-10-25  0:34   ` Doug Anderson
  1 sibling, 0 replies; 151+ messages in thread
From: Doug Anderson @ 2022-10-25  0:34 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Luis Chamberlain,
	Aaron Tomlin, kgdb-bugreport

Hi,

On Wed, Oct 19, 2022 at 7:56 AM John Ogness <john.ogness@linutronix.de> wrote:
>
> Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  kernel/debug/kdb/kdb_io.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function
  2022-10-19 14:55 ` [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function John Ogness
  2022-10-19 15:41   ` Greg Kroah-Hartman
  2022-10-24  5:22   ` Sergey Senozhatsky
@ 2022-10-25  0:34   ` Doug Anderson
  2 siblings, 0 replies; 151+ messages in thread
From: Doug Anderson @ 2022-10-25  0:34 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Greg Kroah-Hartman,
	Jiri Slaby, kgdb-bugreport, linux-serial

Hi,

On Wed, Oct 19, 2022 at 7:56 AM John Ogness <john.ogness@linutronix.de> wrote:
>
> From: Thomas Gleixner <tglx@linutronix.de>
>
> Unprotected list walks are not necessarily safe.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> Reviewed-by: Petr Mladek <pmladek@suse.com>
> ---
>  drivers/tty/serial/kgdboc.c | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage
  2022-10-19 14:55 ` [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage John Ogness
  2022-10-20  7:42   ` Greg Kroah-Hartman
@ 2022-10-25  0:36   ` Doug Anderson
  2022-10-25 10:09   ` Petr Mladek
  2 siblings, 0 replies; 151+ messages in thread
From: Doug Anderson @ 2022-10-25  0:36 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Greg Kroah-Hartman,
	Jiri Slaby, kgdb-bugreport, linux-serial

Hi,

On Wed, Oct 19, 2022 at 7:56 AM John Ogness <john.ogness@linutronix.de> wrote:
>
> kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
> are unregistered until the kgdboc_earlycon is setup. This is necessary
> because the trapping of the exit() callback assumes that the exit()
> callback is not called before the trap is setup.
>
> Explicitly document this non-typical console_lock usage.
>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/kgdboc.c | 8 ++++++++
>  1 file changed, 8 insertions(+)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 26/38] kdb: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 26/38] kdb: use srcu console list iterator John Ogness
@ 2022-10-25  0:47   ` Doug Anderson
  2022-10-25 14:59     ` Petr Mladek
  0 siblings, 1 reply; 151+ messages in thread
From: Doug Anderson @ 2022-10-25  0:47 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Luis Chamberlain,
	Aaron Tomlin, kgdb-bugreport

Hi,

On Wed, Oct 19, 2022 at 7:56 AM John Ogness <john.ogness@linutronix.de> wrote:
>
> Guarantee safe iteration of the console list by using SRCU.
>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  kernel/debug/kdb/kdb_io.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
> index 550fe8b456ec..5c0bd93c3574 100644
> --- a/kernel/debug/kdb/kdb_io.c
> +++ b/kernel/debug/kdb/kdb_io.c
> @@ -545,6 +545,7 @@ static void kdb_msg_write(const char *msg, int msg_len)
>  {
>         struct console *c;
>         const char *cp;
> +       int cookie;
>         int len;
>
>         if (msg_len == 0)
> @@ -558,7 +559,8 @@ static void kdb_msg_write(const char *msg, int msg_len)
>                 cp++;
>         }
>
> -       for_each_console(c) {
> +       cookie = console_srcu_read_lock();
> +       for_each_console_srcu(c) {

Maybe it wouldn't hurt to also have a comment saying that normally the
console_srcu_read_lock() wouldn't be enough given that we're poking
into each individual console and calling ->write() but that we're
relying on the fact that all the other CPUs are stopped at the moment
and thus we should be safe.

-Doug

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-10-24 22:46   ` Doug Anderson
@ 2022-10-25  0:49     ` Doug Anderson
  2022-10-25 11:28       ` John Ogness
  0 siblings, 1 reply; 151+ messages in thread
From: Doug Anderson @ 2022-10-25  0:49 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Greg Kroah-Hartman,
	Jiri Slaby, kgdb-bugreport, linux-serial

Hi,

On Mon, Oct 24, 2022 at 3:46 PM Doug Anderson <dianders@chromium.org> wrote:
>
> Hi,
>
> On Wed, Oct 19, 2022 at 7:56 AM John Ogness <john.ogness@linutronix.de> wrote:
> >
> > Replace (console->flags & CON_ENABLED) usage with console_is_enabled().
> >
> > Signed-off-by: John Ogness <john.ogness@linutronix.de>
> > ---
> >  drivers/tty/serial/kgdboc.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
> > index e76f0186c335..b17aa7e49894 100644
> > --- a/drivers/tty/serial/kgdboc.c
> > +++ b/drivers/tty/serial/kgdboc.c
> > @@ -533,7 +533,7 @@ static int __init kgdboc_earlycon_init(char *opt)
> >         console_lock();
> >         for_each_console(con) {
> >                 if (con->write && con->read &&
> > -                   (con->flags & (CON_BOOT | CON_ENABLED)) &&
> > +                   (console_is_enabled(con) || (con->flags & CON_BOOT)) &&
>
> <shrug>. I guess this is OK, but it feels a little pointless. If we're
> still directly looking at the CON_BOOT bit in con->flags it seems
> weird to be accessing CON_ENABLED through a special wrapper that's
> marked as a `data_race`. In our case it's _not_ a data race, right,
> since this function continues to hold the console_lock() even at the
> end of the series? I personally would drop this patch but if you
> really want it I won't object.

I realized that my statement isn't quite true. It actually only holds
console_list_lock() even at the end of the series. Still, it seems
weird that we're declaring the `data_race` on CON_ENABLED but not
CON_BOOT ?

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage
  2022-10-19 14:55 ` [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage John Ogness
  2022-10-20  7:42   ` Greg Kroah-Hartman
  2022-10-25  0:36   ` Doug Anderson
@ 2022-10-25 10:09   ` Petr Mladek
  2 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 10:09 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

On Wed 2022-10-19 17:01:44, John Ogness wrote:
> kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
> are unregistered until the kgdboc_earlycon is setup. This is necessary
> because the trapping of the exit() callback assumes that the exit()
> callback is not called before the trap is setup.

Great catch!

Note: This behavior might be dangerous. printk_late_init() checks if
      the early console code is in the init section. It unregisters
      such consoles even when keep_bootcon parameter is used.

      Well, it is "not serious" and might be improved later.
      If the early console has this code in the early section
      then it is a bug and should be fixed. printk_late_init() does
      the best effort because this problem would block all consoles
      and would be hard to debug. It is the same with kgdb but
      it is still only a corner case and just the best effort.

> Explicitly document this non-typical console_lock usage.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-10-25  0:49     ` Doug Anderson
@ 2022-10-25 11:28       ` John Ogness
  2022-11-04 16:23         ` John Ogness
  0 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-25 11:28 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Greg Kroah-Hartman,
	Jiri Slaby, kgdb-bugreport, linux-serial

On 2022-10-24, Doug Anderson <dianders@chromium.org> wrote:
> It actually only holds console_list_lock() even at the end of the
> series. Still, it seems weird that we're declaring the `data_race` on
> CON_ENABLED but not CON_BOOT ?

You are correct that it is not a data race (because of the
console_list_lock being held.) Petr has suggested adding a separate
function for non-data-race callers. For v3 I will do this and use it
here, probably called console_is_enabled_locked().

Usually CON_ENABLED is the only flag that is interesting during normal
operation. The kgdboc case is an exception. I thought about if we should
have console_flags() and console_flags_locked() to be able to handle
general con->flags access. console_flags() would be marked with
data_race(), console_flags_locked() would use lockdep to ensure the
console_list_lock is held.

But I would also like to have the _is_enabled special variant because
how we check if a console is enabled will be different for the atomic
consoles. I would like to hide those details in the _is_enabled
implementation.

John Ogness

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 23/38] tty: tty_io: document console_lock usage
  2022-10-19 14:55 ` [PATCH printk v2 23/38] tty: tty_io: " John Ogness
  2022-10-20  7:43   ` Greg Kroah-Hartman
@ 2022-10-25 13:31   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 13:31 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby

On Wed 2022-10-19 17:01:45, John Ogness wrote:
> show_cons_active() uses the console_lock to gather information
> on registered consoles. Since the console_lock is being used for
> multiple reasons, explicitly document these reasons. This will
> be useful when the console_lock is split into fine-grained
> locking.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/tty_io.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
> index 2050e63963bb..333579bfa335 100644
> --- a/drivers/tty/tty_io.c
> +++ b/drivers/tty/tty_io.c
> @@ -3526,6 +3526,14 @@ static ssize_t show_cons_active(struct device *dev,
>  	struct console *c;
>  	ssize_t count = 0;
>  
> +	/*
> +	 * Hold the console_lock to guarantee that no consoles are
> +	 * unregistered until all console processing is complete.
> +	 * This also allows safe traversal of the console list.

This is more or less clear. show_cons_active() reads a lot of
information from the registered consoles.

> +	 *
> +	 * Stop console printing because the device() callback may
> +	 * assume the console is not within its write() callback.

I wonder if this is based on some real example or if you just want
to stay on the safe side.

It is perfectly fine to stay on the safe side. But we should make
it clear if the dependency really exists or if it has to be
investigated later during the clean up.

> +	 */
>  	console_lock();
>  	for_each_console(c) {
>  		if (!c->device)

Anyway, thanks for adding the comment.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 24/38] xen: fbfront: use srcu console list iterator
  2022-10-19 14:55   ` John Ogness
@ 2022-10-25 13:39     ` Petr Mladek
  -1 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 13:39 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Helge Deller, Thomas Zimmermann,
	Javier Martinez Canillas, Boris Ostrovsky, Juergen Gross,
	Tom Rix, linux-fbdev, dri-devel

On Wed 2022-10-19 17:01:46, John Ogness wrote:
> Since the console_lock is not being used for anything other than
> safe console list traversal, use srcu console list iteration instead.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

> ---
>  drivers/video/fbdev/xen-fbfront.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
> index 4d2694d904aa..2552c853c6c2 100644
> --- a/drivers/video/fbdev/xen-fbfront.c
> +++ b/drivers/video/fbdev/xen-fbfront.c
> @@ -500,16 +500,18 @@ static int xenfb_probe(struct xenbus_device *dev,
>  static void xenfb_make_preferred_console(void)

Just for record. This function is a dirty hack how to associate "ttyX"
console with /dev/console.

A clean solution would be to just reshuffle console_drivers list. I
have a patch for this in my bottom drawer. It is part of a bigger
clean up that it not ready for upstreaming yet.

Best Regards,
Petr

>  {
>  	struct console *c;
> +	int cookie;
>  
>  	if (console_set_on_cmdline)
>  		return;
>  
> -	console_lock();
> -	for_each_console(c) {
> +	cookie = console_srcu_read_lock();
> +	for_each_console_srcu(c) {
>  		if (!strcmp(c->name, "tty") && c->index == 0)
>  			break;
>  	}
> -	console_unlock();
> +	console_srcu_read_unlock(cookie);
> +
>  	if (c) {
>  		unregister_console(c);
>  		c->flags |= CON_CONSDEV;
> -- 
> 2.30.2

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 24/38] xen: fbfront: use srcu console list iterator
@ 2022-10-25 13:39     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 13:39 UTC (permalink / raw)
  To: John Ogness
  Cc: Juergen Gross, linux-fbdev, Tom Rix, Helge Deller, linux-kernel,
	Steven Rostedt, Javier Martinez Canillas, Sergey Senozhatsky,
	dri-devel, Thomas Zimmermann, Thomas Gleixner, Boris Ostrovsky

On Wed 2022-10-19 17:01:46, John Ogness wrote:
> Since the console_lock is not being used for anything other than
> safe console list traversal, use srcu console list iteration instead.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

> ---
>  drivers/video/fbdev/xen-fbfront.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
> index 4d2694d904aa..2552c853c6c2 100644
> --- a/drivers/video/fbdev/xen-fbfront.c
> +++ b/drivers/video/fbdev/xen-fbfront.c
> @@ -500,16 +500,18 @@ static int xenfb_probe(struct xenbus_device *dev,
>  static void xenfb_make_preferred_console(void)

Just for record. This function is a dirty hack how to associate "ttyX"
console with /dev/console.

A clean solution would be to just reshuffle console_drivers list. I
have a patch for this in my bottom drawer. It is part of a bigger
clean up that it not ready for upstreaming yet.

Best Regards,
Petr

>  {
>  	struct console *c;
> +	int cookie;
>  
>  	if (console_set_on_cmdline)
>  		return;
>  
> -	console_lock();
> -	for_each_console(c) {
> +	cookie = console_srcu_read_lock();
> +	for_each_console_srcu(c) {
>  		if (!strcmp(c->name, "tty") && c->index == 0)
>  			break;
>  	}
> -	console_unlock();
> +	console_srcu_read_unlock(cookie);
> +
>  	if (c) {
>  		unregister_console(c);
>  		c->flags |= CON_CONSDEV;
> -- 
> 2.30.2

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 25/38] proc: consoles: document console_lock usage
  2022-10-19 14:55 ` [PATCH printk v2 25/38] proc: consoles: document console_lock usage John Ogness
@ 2022-10-25 14:40   ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 14:40 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel

On Wed 2022-10-19 17:01:47, John Ogness wrote:
> The console_lock is held throughout the start/show/stop procedure
> to print out device/driver information about all registered
> consoles. Since the console_lock is being used for multiple reasons,
> explicitly document these reasons. This will be useful when the
> console_lock is split into fine-grained locking.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  fs/proc/consoles.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
> index cf2e0788f9c7..32512b477605 100644
> --- a/fs/proc/consoles.c
> +++ b/fs/proc/consoles.c
> @@ -63,6 +63,14 @@ static void *c_start(struct seq_file *m, loff_t *pos)
>  	struct console *con;
>  	loff_t off = 0;
>  
> +	/*
> +	 * Stop console printing because the device() callback may
> +	 * assume the console is not within its write() callback.

Like in previous patches, I would prefer to add more information
about this dependency. An example or if it is just to stay
on the safe side.

> +	 *
> +	 * Hold the console_lock to guarantee safe traversal of the
> +	 * console list. SRCU cannot be used because there is no
> +	 * place to store the SRCU cookie.

It might be possible to crate a custom struct for passing both
the next struct console and SRCU cookie. But it probably
is not worth it.

> +	 */
>  	console_lock();
>  	for_each_console(con)
>  		if (off++ == *pos)

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 26/38] kdb: use srcu console list iterator
  2022-10-25  0:47   ` Doug Anderson
@ 2022-10-25 14:59     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 14:59 UTC (permalink / raw)
  To: Doug Anderson
  Cc: John Ogness, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Luis Chamberlain,
	Aaron Tomlin, kgdb-bugreport

On Mon 2022-10-24 17:47:25, Doug Anderson wrote:
> Hi,
> 
> On Wed, Oct 19, 2022 at 7:56 AM John Ogness <john.ogness@linutronix.de> wrote:
> >
> > Guarantee safe iteration of the console list by using SRCU.
> >
> > Signed-off-by: John Ogness <john.ogness@linutronix.de>
> > ---
> >  kernel/debug/kdb/kdb_io.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
> > index 550fe8b456ec..5c0bd93c3574 100644
> > --- a/kernel/debug/kdb/kdb_io.c
> > +++ b/kernel/debug/kdb/kdb_io.c
> > @@ -545,6 +545,7 @@ static void kdb_msg_write(const char *msg, int msg_len)
> >  {
> >         struct console *c;
> >         const char *cp;
> > +       int cookie;
> >         int len;
> >
> >         if (msg_len == 0)
> > @@ -558,7 +559,8 @@ static void kdb_msg_write(const char *msg, int msg_len)
> >                 cp++;
> >         }
> >
> > -       for_each_console(c) {
> > +       cookie = console_srcu_read_lock();
> > +       for_each_console_srcu(c) {
> 
> Maybe it wouldn't hurt to also have a comment saying that normally the
> console_srcu_read_lock() wouldn't be enough given that we're poking
> into each individual console and calling ->write() but that we're
> relying on the fact that all the other CPUs are stopped at the moment
> and thus we should be safe.

True. I guess that the SRCU lock is not really needed from the same
reason.

Well, the SRCU walk makes sense. It makes sure that the list can be
safely traversed. I mean that pointers are updated and read in
the right order with the right barriers.

Yes, it would be nice to add a comment.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 27/38] printk: console_flush_all: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 27/38] printk: console_flush_all: " John Ogness
@ 2022-10-25 15:17   ` Petr Mladek
  2022-11-07  0:00     ` John Ogness
  0 siblings, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 15:17 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:49, John Ogness wrote:
> Guarantee safe iteration of the console list by using SRCU.
> 
> Note that in the case of a handover, the SRCU read lock is also
> released. This is documented in the function description and as
> comments in the code. It is a bit tricky, but this preserves the
> lockdep lock ordering for the context handing over the
> console_lock:
> 
>   console_lock()
>   | mutex_acquire(&console_lock_dep_map)       <-- console lock
>   |
>   console_unlock()
>   | console_flush_all()
>   | | srcu_read_lock(&console_srcu)            <-- srcu lock
>   | | console_emit_next_record()
>   | | | console_lock_spinning_disable_and_check()
>   | | | | srcu_read_unlock(&console_srcu)      <-- srcu unlock
>   | | | | mutex_release(&console_lock_dep_map) <-- console unlock

I believe that we could avoid this complexity, see below.

> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  kernel/printk/printk.c | 38 ++++++++++++++++++++++++++++----------
>  1 file changed, 28 insertions(+), 10 deletions(-)
> 
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 7ff2fc75fc3b..c4d5d58b5977 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2808,7 +2815,8 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
>  	do {
>  		any_progress = false;
>  
> -		for_each_console(con) {
> +		cookie = console_srcu_read_lock();
> +		for_each_console_srcu(con) {
>  			bool progress;
>  
>  			if (!console_is_usable(con))
> @@ -2819,12 +2827,17 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
>  				/* Extended consoles do not print "dropped messages". */
>  				progress = console_emit_next_record(con, &text[0],
>  								    &ext_text[0], NULL,
> -								    handover);
> +								    handover, cookie);
>  			} else {
>  				progress = console_emit_next_record(con, &text[0],
>  								    NULL, &dropped_text[0],
> -								    handover);
> +								    handover, cookie);
>  			}
> +
> +			/*
> +			 * If a handover has occurred, the SRCU read lock
> +			 * is already released.
> +			 */
>  			if (*handover)
>  				return false;

Please, release the SRCU read lock here:

			if (*handover) {
				console_srcu_read_unlock(cookie);
				return false;
			}

The lock should be released in the same function where it was taken.
It does not require passing the cookie and looks more straightforward.

We actually do the same when abandon_console_lock_in_panic()
returns true. We could share the code:

handover_abandon:
	console_srcu_read_unlock(cookie);
	return false;


Or do I miss anything, please?

> @@ -2838,14 +2851,19 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
>  
>  			/* Allow panic_cpu to take over the consoles safely. */
>  			if (abandon_console_lock_in_panic())
> -				return false;
> +				goto abandon;
>  
>  			if (do_cond_resched)
>  				cond_resched();
>  		}
> +		console_srcu_read_unlock(cookie);
>  	} while (any_progress);
>  
>  	return any_usable;
> +
> +abandon:
> +	console_srcu_read_unlock(cookie);
> +	return false;
>  }

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 28/38] printk: console_unblank: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 28/38] printk: console_unblank: " John Ogness
@ 2022-10-25 15:28   ` Petr Mladek
  2022-10-25 15:31   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 15:28 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:50, John Ogness wrote:
> Use srcu console list iteration for console list traversal.
> 
> Document why the console_lock is still necessary.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

See a note below.

> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2948,10 +2948,14 @@ EXPORT_SYMBOL(console_conditional_schedule);
>  void console_unblank(void)
>  {
>  	struct console *c;
> +	int cookie;
>  
>  	/*
> -	 * console_unblank can no longer be called in interrupt context unless
> -	 * oops_in_progress is set to 1..
> +	 * Stop console printing because the unblank() callback may
> +	 * assume the console is not within its write() callback.

From some reason, I believe this even without more details. I expect
that unbank() would need to refresh the screen and use similar
code as the write() callback.

It is different than the device() callback where the dependency is
less obvious.

Best Regards,
Petr

> +	 *
> +	 * If @oops_in_progress is set, this may be an atomic context.
> +	 * In that case, attempt a trylock as best-effort.
>  	 */
>  	if (oops_in_progress) {
>  		if (down_trylock_console_sem() != 0)
> @@ -2961,9 +2965,14 @@ void console_unblank(void)
>  
>  	console_locked = 1;
>  	console_may_schedule = 0;
> -	for_each_console(c)
> +
> +	cookie = console_srcu_read_lock();
> +	for_each_console_srcu(c) {
>  		if (console_is_enabled(c) && c->unblank)
>  			c->unblank();
> +	}
> +	console_srcu_read_unlock(cookie);
> +
>  	console_unlock();
>  
>  	if (!oops_in_progress)

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 28/38] printk: console_unblank: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 28/38] printk: console_unblank: " John Ogness
  2022-10-25 15:28   ` Petr Mladek
@ 2022-10-25 15:31   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 15:31 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:50, John Ogness wrote:
> Use srcu console list iteration for console list traversal.
> 
> Document why the console_lock is still necessary.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 29/38] printk: console_flush_on_panic: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 29/38] printk: console_flush_on_panic: " John Ogness
@ 2022-10-25 15:32   ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 15:32 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:51, John Ogness wrote:
> With SRCU it is now safe to traverse the console list, even if
> the console_trylock() failed. However, overwriting console->seq
> when console_trylock() failed is still an issue.
> 
> Switch to SRCU iteration and document remaining issue with
> console->seq.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 30/38] printk: console_device: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 30/38] printk: console_device: " John Ogness
@ 2022-10-25 15:35   ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-25 15:35 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:52, John Ogness wrote:
> Use srcu console list iteration for console list traversal.
> 
> Document why the console_lock is still necessary.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  kernel/printk/printk.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index e478cb92e7ba..410ad9d5649c 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -3025,15 +3025,24 @@ struct tty_driver *console_device(int *index)
>  {
>  	struct console *c;
>  	struct tty_driver *driver = NULL;
> +	int cookie;
>  
> +	/*
> +	 * Stop console printing because the device() callback may
> +	 * assume the console is not within its write() callback.

Again, I would like to know more details about the possible races
with the write() callback. It is not that obvious.

> +	 */
>  	console_lock();
> -	for_each_console(c) {
> +
> +	cookie = console_srcu_read_lock();
> +	for_each_console_srcu(c) {
>  		if (!c->device)
>  			continue;
>  		driver = c->device(c, index);
>  		if (driver)
>  			break;
>  	}
> +	console_srcu_read_unlock(cookie);
> +
>  	console_unlock();
>  	return driver;

Otherwise, the change looks good.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 31/38] printk: register_console: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 31/38] printk: register_console: " John Ogness
@ 2022-10-26  8:20   ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-26  8:20 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:53, John Ogness wrote:
> Use srcu console list iteration for console list traversal. Now
> the traversal at the beginning of register_console() is safe.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

That said, I think that we could omit this patch. It does not harm.
It prevents a crash when iterating the list but it is only small part
of the races here.

For example, it sets "realcon_enabled" but the list might change before the
value is used. Also the later hlist_empty(&console_list) and
!console_first->device checks are not secure against each other.

The real solution is the introduction of console_list_lock in 33th
patch. That patch removes the rcu read lock. From this POV, this patch
is just unnecessary churn.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 32/38] printk: __pr_flush: use srcu console list iterator
  2022-10-19 14:55 ` [PATCH printk v2 32/38] printk: __pr_flush: " John Ogness
@ 2022-10-26  8:33   ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-26  8:33 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:54, John Ogness wrote:
> Use srcu console list iteration for console list traversal.
>
> Document why the console_lock is still necessary.

When thinking about it. It might be worth explaining why the srcu
traversal is added even when console_lock is still needed.
It would make the life of code archaeologists easier.

I mean to add a note that it will keep the traversal safe
even after console_drivers list manipulation will not longer be
serialized using console_lock(). Or something like this.

It would be nice to add this to all other patches the introduced
srcu and kept console_lock.

> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Anyway, the change looks good. Feel free to use:

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 33/38] printk: introduce console_list_lock
  2022-10-19 14:55 ` [PATCH printk v2 33/38] printk: introduce console_list_lock John Ogness
  2022-10-20  7:53   ` Greg Kroah-Hartman
@ 2022-10-27 10:09   ` Petr Mladek
  2022-10-27 18:50     ` Paul E. McKenney
  1 sibling, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 10:09 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Paul E. McKenney

Adding Paul into Cc so that he is aware of using a custom SRCU lockdep
check in console_list_lock().

On Wed 2022-10-19 17:01:55, John Ogness wrote:
> Currently there exist races in console_register(), where the types
> of registered consoles are checked (without holding the console_lock)
> and then after acquiring the console_lock, it is assumed that the list
> has not changed. Also, some code that performs console_unregister()
> make similar assumptions.

This sounds like that the list lock is added just to fix the races.
People might wonder why it is not done using console_lock().
My understanding is that removing this responsibility from console_lock() is
the main motivation. It would deserve a comment, e.g.

<proposal>
A solution would be to synchronize this using console_lock(). But it
would require a complex analyze of all console drivers to make sure
that console_lock() is not taken in match() and setup() callbacks.
And splitting the responsibilities of console_lock() is actually
one big motivation here.

Instead, introduce a console_list_lock...
</proposal>

> Introduce a console_list_lock to provide full synchronization for any
> console list changes.

> The console_list_lock also provides synchronization for updates
> to console->flags.

This would deserve some explanation. The synchronization of the list
manipulation is obvious, especially when the lock is called
console_list_lock. But the motivation to use this lock
for console->flags is much more complicated.

I had some problems to create a reasonable mental model about it.
I did split the flags into groups:

  1. Flags that are driver-specific and static. They do not need
     any synchronization:

       + CON_BOOT
       + CON_ANYTIME


  2. Flags that are modified only during console registration [*]:

       + CON_PRINTBUFFER
       + CON_CONSDEV
       + CON_BRL
       + CON_EXTENDED

  3. Flags that might be modified by more operations, namely: console
     registration, start, and stop [*].

       + CON_ENABLED

[*] It is actually more complicated. Some flags are modified also
    outside console registration code. But we are not going to
    synchronize these changes because they are not visible
    to others via console_drivers list.

This explained why it made sense to synchronize console->flags using
console_list_lock. Also this explained why
console_start()/console_stop() were updated in this patch.

The following description would have helped me:

<proposal>
In addition, use console_list_lock also for synchronization of
console->flags updates. All flags are either static or modified
only during the console registration. There are only few
exceptions.

The only exception is CON_ENABLED that is modified also by
console_start()/console_stop(). We need to take console_list_lock()
here as well.

Another exception is when the flags are modified by the console
driver init code before the console gets registered. These will
be ignored because they are not visible to the rest of the system
via console_drivers list.
</proposal>

> Note that one of the various responsibilities of the console_lock is
> also intended to provide this synchronization. Later changes will
> update call sites relying on the console_lock for this purpose. Once
> all call sites have been updated, the console_lock will be relieved
> of synchronizing console_list and console->flags updates.

It seems that this patch actually updates all writers. It would be
nice to mention it to define the scope of this patch.

<proposal>
Note that one of the various responsibilities of the console_lock is
also intended to provide this synchronization. Only the callers that
modify the list or flags are updated here. Later changes will
update the readers Once all call sites have been updated,
the console_lock will be relieved of synchronizing console_list
and console->flags updates.
</proposal>

> diff --git a/include/linux/console.h b/include/linux/console.h
> index 60195cd086dc..bf1e8136424a 100644
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -159,8 +159,12 @@ struct console {
>  };
>  
>  #ifdef CONFIG_LOCKDEP
> +extern void lockdep_assert_console_list_lock_held(void);
>  extern bool console_srcu_read_lock_is_held(void);
>  #else
> +static inline void lockdep_assert_console_list_lock_held(void)
> +{
> +}
>  static inline bool console_srcu_read_lock_is_held(void)
>  {
>  	return 1;
> @@ -170,6 +174,9 @@ static inline bool console_srcu_read_lock_is_held(void)
>  extern int console_srcu_read_lock(void);
>  extern void console_srcu_read_unlock(int cookie);
>  
> +extern void console_list_lock(void) __acquires(console_mutex);
> +extern void console_list_unlock(void) __releases(console_mutex);
> +
>  extern struct hlist_head console_list;
>  
>  /**
> @@ -206,10 +213,17 @@ static inline bool console_is_enabled(const struct console *con)
>  	hlist_for_each_entry_srcu(con, &console_list, node,		\
>  				  console_srcu_read_lock_is_held())
>  
> -/*
> - * for_each_console() allows you to iterate on each console
> +/**
> + * for_each_console() - Iterator over registered consoles
> + * @con:	struct console pointer used as loop cursor
> + *
> + * The console list and all struct console fields are immutable while
> + * iterating.

s/all struct console fields/console->flags/  ?

> + *
> + * Requires console_list_lock to be held.
>   */
> -#define for_each_console(con) \
> +#define for_each_console(con)						\
> +	lockdep_assert_console_list_lock_held();			\
>  	hlist_for_each_entry(con, &console_list, node)
>  
>  extern int console_set_on_cmdline;
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 2faa6e3e2fb8..3615ee6d68fd 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -78,6 +78,9 @@ EXPORT_SYMBOL(ignore_console_lock_warning);
>  int oops_in_progress;
>  EXPORT_SYMBOL(oops_in_progress);
>  
> +/* console_mutex protects console_list and console->flags updates. */

  /*
   * console_mutex protects console_list updates and console->flags updates.
   * The flags are synchronized only for consoles that are registered,
   * accessible via the list.
   */

> +static DEFINE_MUTEX(console_mutex);
> +
>  /*
>   * console_sem protects console_list and console->flags updates, and also
>   * provides serialization for access to the entire console driver system.
> @@ -104,6 +107,11 @@ static struct lockdep_map console_lock_dep_map = {
>  	.name = "console_lock"
>  };
>  
> +void lockdep_assert_console_list_lock_held(void)
> +{
> +	lockdep_assert_held(&console_mutex);
> +}
> +
>  bool console_srcu_read_lock_is_held(void)
>  {
>  	return srcu_read_lock_held(&console_srcu);
> @@ -225,6 +233,40 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
>  }
>  #endif /* CONFIG_PRINTK && CONFIG_SYSCTL */
>  
> +/**
> + * console_list_lock - Lock the console list
> + *
> + * For console list or console->flags updates
> + */
> +void console_list_lock(void)
> +{
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +	/*
> +	 * In unregister_console(), synchronize_srcu() is called with the
> +	 * console_list_lock held. Therefore it is not allowed that the
> +	 * console_list_lock is taken with the srcu_lock held.
> +	 *
> +	 * Whether or not this context is in the read-side critical section
> +	 * can only be detected if the appropriate debug options are enabled.
> +	 */
> +	WARN_ON_ONCE(debug_lockdep_rcu_enabled() &&
> +		     srcu_read_lock_held(&console_srcu));
> +#endif
> +	mutex_lock(&console_mutex);
> +}
> +EXPORT_SYMBOL(console_list_lock);
> +
> +/**
> + * console_list_unlock - Unlock the console list
> + *
> + * Counterpart to console_list_lock()
> + */
> +void console_list_unlock(void)
> +{
> +	mutex_unlock(&console_mutex);
> +}
> +EXPORT_SYMBOL(console_list_unlock);
> +
>  /**
>   * console_srcu_read_lock - Register a new reader for the
>   *	SRCU-protected console list
> @@ -3304,13 +3350,15 @@ void register_console(struct console *newcon)
>  
>  		hlist_for_each_entry_safe(con, tmp, &console_list, node) {
>  			if (con->flags & CON_BOOT)
> -				unregister_console(con);
> +				unregister_console_locked(con);
>  		}
>  	}
> +unlock:
> +	console_list_unlock();
>  }
>  EXPORT_SYMBOL(register_console);
>  
> -int unregister_console(struct console *console)

We should make it clear that it must be locked by console_list_lock().
Many people would expect console_lock() ;-) I would add a comment
and assert.

/* Must be called under console_list_lock(). */

> +static int unregister_console_locked(struct console *console)
>  {

	assert_console_list_lock_held();

>  	int res;
>  

With updated comments:

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 34/38] serial: kgdboc: use console_list_lock instead of console_lock
  2022-10-19 14:55 ` [PATCH printk v2 34/38] serial: kgdboc: use console_list_lock instead of console_lock John Ogness
  2022-10-20  7:52   ` Greg Kroah-Hartman
@ 2022-10-27 10:13   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 10:13 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Douglas Anderson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

On Wed 2022-10-19 17:01:56, John Ogness wrote:
> kgdboc_earlycon_init() uses the console_lock to ensure that no consoles
> are unregistered until the kgdboc_earlycon is setup. The console_list_lock
> should be used instead because list synchronization repsponsibility will
> be removed from the console_lock in a later change.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 35/38] tty: tty_io: use console_list_lock for list synchronization
  2022-10-19 14:55 ` [PATCH printk v2 35/38] tty: tty_io: use console_list_lock for list synchronization John Ogness
  2022-10-20  7:43   ` Greg Kroah-Hartman
@ 2022-10-27 10:17   ` Petr Mladek
  1 sibling, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 10:17 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, Jiri Slaby

On Wed 2022-10-19 17:01:57, John Ogness wrote:
> show_cons_active() uses the console_lock to gather information
> on registered consoles. It requires that no consoles are unregistered
> until it is finished. The console_list_lock should be used because
> list synchronization repsponsibility will be removed from the
> console_lock in a later change.
> 
> Note, the console_lock is still needed to stop console printing.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 36/38] proc: consoles: use console_list_lock for list iteration
  2022-10-19 14:55 ` [PATCH printk v2 36/38] proc: consoles: use console_list_lock for list iteration John Ogness
@ 2022-10-27 12:02   ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 12:02 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel

On Wed 2022-10-19 17:01:58, John Ogness wrote:
> The console_lock is used in part to guarantee safe list iteration.
> The console_list_lock should be used because list synchronization
> repsponsibility will be removed from the console_lock in a later
> change.
> 
> Note, the console_lock is still needed to stop console printing.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 37/38] printk: relieve console_lock of list synchronization duties
  2022-10-19 14:55 ` [PATCH printk v2 37/38] printk: relieve console_lock of list synchronization duties John Ogness
@ 2022-10-27 12:40   ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 12:40 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Wed 2022-10-19 17:01:59, John Ogness wrote:
> The console_list_lock provides synchronization for console list and
> console->flags updates. All call sites that were using the console_lock
> for this synchronization have either switched to use the
> console_list_lock or the SRCU list iterator.
> 
> Remove console_lock usage for console list updates and console->flags
> updates.
> 
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 3615ee6d68fd..840d581c4b23 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -3370,8 +3363,6 @@ static int unregister_console_locked(struct console *console)
>  	if (res > 0)
>  		return 0;
>  
> -	console_lock();
> -
>  	/* Disable it unconditionally */
>  	console->flags &= ~CON_ENABLED;
>  
> @@ -3394,8 +3385,6 @@ static int unregister_console_locked(struct console *console)
>  	if (!hlist_empty(&console_list) && console->flags & CON_CONSDEV)
>  		console_first()->flags |= CON_CONSDEV;
>  
> -	console_unlock();
> -
>  	/* Ensure that all SRCU list walks have completed */
>  	synchronize_srcu(&console_srcu);

In addition, in unregister_console_locked(), we need to remove goto out_unlock:

	if (hlist_unhashed(&console->node)) {
		res = -ENODEV;
		goto out_unlock;
	}

out_unlock:
	console_unlock();
	return res;


I did my best to check all users that either iterate over the list
and/or access console->flags. And I did not find any real problems.

With the removal of the above mentioned out_unlock:

Reviewed-by: Petr Mladek <pmladek@suse.com>


Best Regards,
Petr

PS: Two ideas for possible future improvement:

  1. It might make sense to synchronize also @console_cmdline using
     the console_list_lock. It is modified only in
     __add_preferred_console() and read only from register_console().

     It would remove another possible race. Well, it is probably hard
     to hit, especially when new entries are always added at the end.


  2. It might make sense to create an API to modify and check
     console->flags. It might print a warning when the flags
     are accessed without console_list_lock or console_srcu.

     These days, it is pretty hard to catch all users.


^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred
  2022-10-19 14:56   ` John Ogness
@ 2022-10-27 13:18     ` Petr Mladek
  -1 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 13:18 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Helge Deller, Greg Kroah-Hartman,
	Javier Martinez Canillas, Thomas Zimmermann, Juergen Gross,
	Boris Ostrovsky, Tom Rix, linux-fbdev, dri-devel

On Wed 2022-10-19 17:02:00, John Ogness wrote:
> With commit 9e124fe16ff2("xen: Enable console tty by default in domU
> if it's not a dummy") a hack was implemented to make sure that the
> tty console remains the console behind the /dev/console device. The
> main problem with the hack is that, after getting the console pointer
> to the tty console, it is assumed the pointer is still valid after
> releasing the console_sem. This assumption is incorrect and unsafe.
> 
> Make the hack safe by introducing a new function
> console_force_preferred() to perform the full operation under
> the console_list_lock.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/video/fbdev/xen-fbfront.c |  8 +---
>  include/linux/console.h           |  1 +
>  kernel/printk/printk.c            | 69 +++++++++++++++++++------------
>  3 files changed, 46 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
> index 2552c853c6c2..aa362b25a60f 100644
> --- a/drivers/video/fbdev/xen-fbfront.c
> +++ b/drivers/video/fbdev/xen-fbfront.c
> @@ -512,12 +512,8 @@ static void xenfb_make_preferred_console(void)
>  	}
>  	console_srcu_read_unlock(cookie);
>  
> -	if (c) {
> -		unregister_console(c);
> -		c->flags |= CON_CONSDEV;
> -		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
> -		register_console(c);
> -	}
> +	if (c)
> +		console_force_preferred(c);

I would prefer to fix this a clean way. The current code is a real hack.
It tries to find a console under console_srcu. Then the console
is unregistered, flags are modified, and gets registered again.
The locks are released between all these operations.

I would suggest to implement:

void console_force_preferred_locked(struct console *new_pref_con)
{
	struct console *cur_pref_con;

	assert_console_list_lock_held();

	if (hlist_unhashed(&new_pref_con->node))
		return;

	for_each_console(cur_pref_con) {
		if (cur_pref_con->flags & CON_CONSDEV)
			break;
	}

	/* Already preferred? */
	if (cur_pref_con == new_pref_con)
		return;

	hlist_del_init_rcu(&new_pref_con->node);
	/*
	 * Ensure that all SRCU list walks have completed before @con
	 * is added back as the first console
	 */
	synchronize_srcu()
	hlist_add_behind_rcu(&new_pref_con->node, console_list.first);

	cur_pref_con->flags &= ~CON_CONSDEV;
	new_pref_con->flags |= CON_CONSDEV;
}

And do:

static void xenfb_make_preferred_console(void)
{
	struct console *c;

	if (console_set_on_cmdline)
		return;

	console_list_lock();
	for_each_console(c) {
		if (!strcmp(c->name, "tty") && c->index == 0)
			break;
	}

	if (c)
		console_force_preferred_locked(c);

	console_list_unlock();
}

It is a more code. But it is race-free. Also it is much more clear
what is going on.

How does this sound, please?

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred
@ 2022-10-27 13:18     ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 13:18 UTC (permalink / raw)
  To: John Ogness
  Cc: Juergen Gross, linux-fbdev, Greg Kroah-Hartman, Helge Deller,
	linux-kernel, Steven Rostedt, Javier Martinez Canillas,
	Sergey Senozhatsky, dri-devel, Thomas Zimmermann, Tom Rix,
	Thomas Gleixner, Boris Ostrovsky

On Wed 2022-10-19 17:02:00, John Ogness wrote:
> With commit 9e124fe16ff2("xen: Enable console tty by default in domU
> if it's not a dummy") a hack was implemented to make sure that the
> tty console remains the console behind the /dev/console device. The
> main problem with the hack is that, after getting the console pointer
> to the tty console, it is assumed the pointer is still valid after
> releasing the console_sem. This assumption is incorrect and unsafe.
> 
> Make the hack safe by introducing a new function
> console_force_preferred() to perform the full operation under
> the console_list_lock.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/video/fbdev/xen-fbfront.c |  8 +---
>  include/linux/console.h           |  1 +
>  kernel/printk/printk.c            | 69 +++++++++++++++++++------------
>  3 files changed, 46 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
> index 2552c853c6c2..aa362b25a60f 100644
> --- a/drivers/video/fbdev/xen-fbfront.c
> +++ b/drivers/video/fbdev/xen-fbfront.c
> @@ -512,12 +512,8 @@ static void xenfb_make_preferred_console(void)
>  	}
>  	console_srcu_read_unlock(cookie);
>  
> -	if (c) {
> -		unregister_console(c);
> -		c->flags |= CON_CONSDEV;
> -		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
> -		register_console(c);
> -	}
> +	if (c)
> +		console_force_preferred(c);

I would prefer to fix this a clean way. The current code is a real hack.
It tries to find a console under console_srcu. Then the console
is unregistered, flags are modified, and gets registered again.
The locks are released between all these operations.

I would suggest to implement:

void console_force_preferred_locked(struct console *new_pref_con)
{
	struct console *cur_pref_con;

	assert_console_list_lock_held();

	if (hlist_unhashed(&new_pref_con->node))
		return;

	for_each_console(cur_pref_con) {
		if (cur_pref_con->flags & CON_CONSDEV)
			break;
	}

	/* Already preferred? */
	if (cur_pref_con == new_pref_con)
		return;

	hlist_del_init_rcu(&new_pref_con->node);
	/*
	 * Ensure that all SRCU list walks have completed before @con
	 * is added back as the first console
	 */
	synchronize_srcu()
	hlist_add_behind_rcu(&new_pref_con->node, console_list.first);

	cur_pref_con->flags &= ~CON_CONSDEV;
	new_pref_con->flags |= CON_CONSDEV;
}

And do:

static void xenfb_make_preferred_console(void)
{
	struct console *c;

	if (console_set_on_cmdline)
		return;

	console_list_lock();
	for_each_console(c) {
		if (!strcmp(c->name, "tty") && c->index == 0)
			break;
	}

	if (c)
		console_force_preferred_locked(c);

	console_list_unlock();
}

It is a more code. But it is race-free. Also it is much more clear
what is going on.

How does this sound, please?

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred
  2022-10-27 13:18     ` Petr Mladek
@ 2022-10-27 13:35       ` John Ogness
  -1 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-27 13:35 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Helge Deller, Greg Kroah-Hartman,
	Javier Martinez Canillas, Thomas Zimmermann, Juergen Gross,
	Boris Ostrovsky, Tom Rix, linux-fbdev, dri-devel

On 2022-10-27, Petr Mladek <pmladek@suse.com> wrote:
>> -	if (c) {
>> -		unregister_console(c);
>> -		c->flags |= CON_CONSDEV;
>> -		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
>> -		register_console(c);
>> -	}
>> +	if (c)
>> +		console_force_preferred(c);
>
> I would prefer to fix this a clean way.
>
> [...]
>
> I would suggest to implement:
>
> [...]
>
> It is a more code. But it is race-free. Also it is much more clear
> what is going on.
>
> How does this sound, please?

I wasn't sure if any of the other preferred-console magic in
register_console() was needed, which is why I kept a full
register_console() call. But if it really is just about forcing it the
head and setting a new CON_CONSDEV, then your suggestion is much
simpler. Thanks.

John

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred
@ 2022-10-27 13:35       ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-27 13:35 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Juergen Gross, linux-fbdev, Greg Kroah-Hartman, Helge Deller,
	linux-kernel, Steven Rostedt, Javier Martinez Canillas,
	Sergey Senozhatsky, dri-devel, Thomas Zimmermann, Tom Rix,
	Thomas Gleixner, Boris Ostrovsky

On 2022-10-27, Petr Mladek <pmladek@suse.com> wrote:
>> -	if (c) {
>> -		unregister_console(c);
>> -		c->flags |= CON_CONSDEV;
>> -		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
>> -		register_console(c);
>> -	}
>> +	if (c)
>> +		console_force_preferred(c);
>
> I would prefer to fix this a clean way.
>
> [...]
>
> I would suggest to implement:
>
> [...]
>
> It is a more code. But it is race-free. Also it is much more clear
> what is going on.
>
> How does this sound, please?

I wasn't sure if any of the other preferred-console magic in
register_console() was needed, which is why I kept a full
register_console() call. But if it really is just about forcing it the
head and setting a new CON_CONSDEV, then your suggestion is much
simpler. Thanks.

John

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred
  2022-10-27 13:35       ` John Ogness
@ 2022-10-27 14:27         ` Petr Mladek
  -1 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 14:27 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Helge Deller, Greg Kroah-Hartman,
	Javier Martinez Canillas, Thomas Zimmermann, Juergen Gross,
	Boris Ostrovsky, Tom Rix, linux-fbdev, dri-devel

On Thu 2022-10-27 15:41:23, John Ogness wrote:
> On 2022-10-27, Petr Mladek <pmladek@suse.com> wrote:
> >> -	if (c) {
> >> -		unregister_console(c);
> >> -		c->flags |= CON_CONSDEV;
> >> -		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
> >> -		register_console(c);
> >> -	}
> >> +	if (c)
> >> +		console_force_preferred(c);
> >
> > I would prefer to fix this a clean way.
> >
> > [...]
> >
> > I would suggest to implement:
> >
> > [...]
> >
> > It is a more code. But it is race-free. Also it is much more clear
> > what is going on.
> >
> > How does this sound, please?
> 
> I wasn't sure if any of the other preferred-console magic in
> register_console() was needed, which is why I kept a full
> register_console() call. But if it really is just about forcing it the
> head and setting a new CON_CONSDEV, then your suggestion is much
> simpler. Thanks.

I believe that it is just this. I have spent a lot of time
investigating these hacks when thinking about refactoring
of register_console().

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred
@ 2022-10-27 14:27         ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-27 14:27 UTC (permalink / raw)
  To: John Ogness
  Cc: Juergen Gross, linux-fbdev, Greg Kroah-Hartman, Helge Deller,
	linux-kernel, Steven Rostedt, Javier Martinez Canillas,
	Sergey Senozhatsky, dri-devel, Thomas Zimmermann, Tom Rix,
	Thomas Gleixner, Boris Ostrovsky

On Thu 2022-10-27 15:41:23, John Ogness wrote:
> On 2022-10-27, Petr Mladek <pmladek@suse.com> wrote:
> >> -	if (c) {
> >> -		unregister_console(c);
> >> -		c->flags |= CON_CONSDEV;
> >> -		c->flags &= ~CON_PRINTBUFFER; /* don't print again */
> >> -		register_console(c);
> >> -	}
> >> +	if (c)
> >> +		console_force_preferred(c);
> >
> > I would prefer to fix this a clean way.
> >
> > [...]
> >
> > I would suggest to implement:
> >
> > [...]
> >
> > It is a more code. But it is race-free. Also it is much more clear
> > what is going on.
> >
> > How does this sound, please?
> 
> I wasn't sure if any of the other preferred-console magic in
> register_console() was needed, which is why I kept a full
> register_console() call. But if it really is just about forcing it the
> head and setting a new CON_CONSDEV, then your suggestion is much
> simpler. Thanks.

I believe that it is just this. I have spent a lot of time
investigating these hacks when thinking about refactoring
of register_console().

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 33/38] printk: introduce console_list_lock
  2022-10-27 10:09   ` Petr Mladek
@ 2022-10-27 18:50     ` Paul E. McKenney
  2022-10-28 18:09       ` Boqun Feng
  2022-11-07 10:10       ` John Ogness
  0 siblings, 2 replies; 151+ messages in thread
From: Paul E. McKenney @ 2022-10-27 18:50 UTC (permalink / raw)
  To: Petr Mladek
  Cc: John Ogness, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, boqun.feng

On Thu, Oct 27, 2022 at 12:09:32PM +0200, Petr Mladek wrote:
> Adding Paul into Cc so that he is aware of using a custom SRCU lockdep
> check in console_list_lock().

[ . . . ]

> > +/**
> > + * console_list_lock - Lock the console list
> > + *
> > + * For console list or console->flags updates
> > + */
> > +void console_list_lock(void)
> > +{
> > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > +	/*
> > +	 * In unregister_console(), synchronize_srcu() is called with the
> > +	 * console_list_lock held. Therefore it is not allowed that the
> > +	 * console_list_lock is taken with the srcu_lock held.
> > +	 *
> > +	 * Whether or not this context is in the read-side critical section
> > +	 * can only be detected if the appropriate debug options are enabled.
> > +	 */
> > +	WARN_ON_ONCE(debug_lockdep_rcu_enabled() &&
> > +		     srcu_read_lock_held(&console_srcu));

Yes, this is an interesting case.

The problem that John is facing is that srcu_read_lock_held() believes
that it is safer to err on the side of there being an SRCU reader.
This is because the standard use is to complain if there is -not-
an SRCU reader.  So as soon as there is a lockdep issue anywhere,
srcu_read_lock_held() switches to unconditionally returning true.

Which is exactly what John does not want in this case.

So he excludes the CONFIG_DEBUG_LOCK_ALLOC=n case and the
!debug_lockdep_rcu_enabled() case, both of which cause
srcu_read_lock_held() to unconditionally return true.

This can result in false-positive splats if some other CPU issues a
lockdep warning after debug_lockdep_rcu_enabled() is invoked but before
srcu_read_lock_held() is invoked.  But similar vulnerabilities are
present in RCU_LOCKDEP_WARN(), so unless and until there is a problem,
this code should suffice.

One way to save a line is as follows:

	WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_LOCK_ALLOC) &&
		     debug_lockdep_rcu_enabled() &&
		     srcu_read_lock_held(&console_srcu));

Longer term, it might be possible to teach lockdep about this sort of
SRCU deadlock.  This is not an issue for vanilla RCU because the RCU
reader context prohibits such deadlocks.  This isn't exactly the same
as reader-writer locking because this is perfectly OK with SRCU:

	CPU 0:
		spin_lock(&mylock);
		idx = srcu_read_lock(&mysrcu);
		do_something();
		srcu_read_unlock(&mysrcu, idx);
		spin_unlock(&mylock);

	CPU 1:
		idx = srcu_read_lock(&mysrcu);
		spin_lock(&mylock);
		do_something();
		spin_unlock(&mylock);
		srcu_read_unlock(&mysrcu, idx);

Adding Boqun on CC in case it is easier than I think.  ;-)

							Thanx, Paul

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 33/38] printk: introduce console_list_lock
  2022-10-27 18:50     ` Paul E. McKenney
@ 2022-10-28 18:09       ` Boqun Feng
  2022-10-28 18:42         ` Paul E. McKenney
  2022-11-07 10:10       ` John Ogness
  1 sibling, 1 reply; 151+ messages in thread
From: Boqun Feng @ 2022-10-28 18:09 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Petr Mladek, John Ogness, Sergey Senozhatsky, Steven Rostedt,
	Thomas Gleixner, linux-kernel, Greg Kroah-Hartman

On Thu, Oct 27, 2022 at 11:50:07AM -0700, Paul E. McKenney wrote:
> On Thu, Oct 27, 2022 at 12:09:32PM +0200, Petr Mladek wrote:
> > Adding Paul into Cc so that he is aware of using a custom SRCU lockdep
> > check in console_list_lock().
> 
> [ . . . ]
> 
> > > +/**
> > > + * console_list_lock - Lock the console list
> > > + *
> > > + * For console list or console->flags updates
> > > + */
> > > +void console_list_lock(void)
> > > +{
> > > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > > +	/*
> > > +	 * In unregister_console(), synchronize_srcu() is called with the
> > > +	 * console_list_lock held. Therefore it is not allowed that the
> > > +	 * console_list_lock is taken with the srcu_lock held.
> > > +	 *
> > > +	 * Whether or not this context is in the read-side critical section
> > > +	 * can only be detected if the appropriate debug options are enabled.
> > > +	 */
> > > +	WARN_ON_ONCE(debug_lockdep_rcu_enabled() &&
> > > +		     srcu_read_lock_held(&console_srcu));
> 
> Yes, this is an interesting case.
> 
> The problem that John is facing is that srcu_read_lock_held() believes
> that it is safer to err on the side of there being an SRCU reader.
> This is because the standard use is to complain if there is -not-
> an SRCU reader.  So as soon as there is a lockdep issue anywhere,
> srcu_read_lock_held() switches to unconditionally returning true.
> 
> Which is exactly what John does not want in this case.
> 
> So he excludes the CONFIG_DEBUG_LOCK_ALLOC=n case and the
> !debug_lockdep_rcu_enabled() case, both of which cause
> srcu_read_lock_held() to unconditionally return true.
> 
> This can result in false-positive splats if some other CPU issues a
> lockdep warning after debug_lockdep_rcu_enabled() is invoked but before
> srcu_read_lock_held() is invoked.  But similar vulnerabilities are
> present in RCU_LOCKDEP_WARN(), so unless and until there is a problem,
> this code should suffice.
> 
> One way to save a line is as follows:
> 
> 	WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_LOCK_ALLOC) &&
> 		     debug_lockdep_rcu_enabled() &&
> 		     srcu_read_lock_held(&console_srcu));
> 
> Longer term, it might be possible to teach lockdep about this sort of
> SRCU deadlock.  This is not an issue for vanilla RCU because the RCU
> reader context prohibits such deadlocks.  This isn't exactly the same
> as reader-writer locking because this is perfectly OK with SRCU:
> 
> 	CPU 0:
> 		spin_lock(&mylock);
> 		idx = srcu_read_lock(&mysrcu);
> 		do_something();
> 		srcu_read_unlock(&mysrcu, idx);
> 		spin_unlock(&mylock);
> 
> 	CPU 1:
> 		idx = srcu_read_lock(&mysrcu);
> 		spin_lock(&mylock);
> 		do_something();
> 		spin_unlock(&mylock);
> 		srcu_read_unlock(&mysrcu, idx);
> 
> Adding Boqun on CC in case it is easier than I think.  ;-)
> 

First I think reader-writer deadlock detection won't treat this as a
deadlock, because srcu_read_lock() is a recursive read lock ;-) in other
words, lockdep knows they don't block each other.

I was actually considering to equip SRCU with reader-writer deadlock
detection when:

	https://lore.kernel.org/lkml/20180412021233.ewncg5jjuzjw3x62@tardis/

The problem (for SRCU to use reader-writer deadlock detection) is
letting lockdep know synchronize_srcu() doesn't block srcu_read_lock(), 
so looks like I owe you a new lockdep annotation primitive ;-)

Regards,
Boqun

> 							Thanx, Paul

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 33/38] printk: introduce console_list_lock
  2022-10-28 18:09       ` Boqun Feng
@ 2022-10-28 18:42         ` Paul E. McKenney
  0 siblings, 0 replies; 151+ messages in thread
From: Paul E. McKenney @ 2022-10-28 18:42 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Petr Mladek, John Ogness, Sergey Senozhatsky, Steven Rostedt,
	Thomas Gleixner, linux-kernel, Greg Kroah-Hartman

On Fri, Oct 28, 2022 at 11:09:35AM -0700, Boqun Feng wrote:
> On Thu, Oct 27, 2022 at 11:50:07AM -0700, Paul E. McKenney wrote:
> > On Thu, Oct 27, 2022 at 12:09:32PM +0200, Petr Mladek wrote:
> > > Adding Paul into Cc so that he is aware of using a custom SRCU lockdep
> > > check in console_list_lock().
> > 
> > [ . . . ]
> > 
> > > > +/**
> > > > + * console_list_lock - Lock the console list
> > > > + *
> > > > + * For console list or console->flags updates
> > > > + */
> > > > +void console_list_lock(void)
> > > > +{
> > > > +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> > > > +	/*
> > > > +	 * In unregister_console(), synchronize_srcu() is called with the
> > > > +	 * console_list_lock held. Therefore it is not allowed that the
> > > > +	 * console_list_lock is taken with the srcu_lock held.
> > > > +	 *
> > > > +	 * Whether or not this context is in the read-side critical section
> > > > +	 * can only be detected if the appropriate debug options are enabled.
> > > > +	 */
> > > > +	WARN_ON_ONCE(debug_lockdep_rcu_enabled() &&
> > > > +		     srcu_read_lock_held(&console_srcu));
> > 
> > Yes, this is an interesting case.
> > 
> > The problem that John is facing is that srcu_read_lock_held() believes
> > that it is safer to err on the side of there being an SRCU reader.
> > This is because the standard use is to complain if there is -not-
> > an SRCU reader.  So as soon as there is a lockdep issue anywhere,
> > srcu_read_lock_held() switches to unconditionally returning true.
> > 
> > Which is exactly what John does not want in this case.
> > 
> > So he excludes the CONFIG_DEBUG_LOCK_ALLOC=n case and the
> > !debug_lockdep_rcu_enabled() case, both of which cause
> > srcu_read_lock_held() to unconditionally return true.
> > 
> > This can result in false-positive splats if some other CPU issues a
> > lockdep warning after debug_lockdep_rcu_enabled() is invoked but before
> > srcu_read_lock_held() is invoked.  But similar vulnerabilities are
> > present in RCU_LOCKDEP_WARN(), so unless and until there is a problem,
> > this code should suffice.
> > 
> > One way to save a line is as follows:
> > 
> > 	WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_LOCK_ALLOC) &&
> > 		     debug_lockdep_rcu_enabled() &&
> > 		     srcu_read_lock_held(&console_srcu));
> > 
> > Longer term, it might be possible to teach lockdep about this sort of
> > SRCU deadlock.  This is not an issue for vanilla RCU because the RCU
> > reader context prohibits such deadlocks.  This isn't exactly the same
> > as reader-writer locking because this is perfectly OK with SRCU:
> > 
> > 	CPU 0:
> > 		spin_lock(&mylock);
> > 		idx = srcu_read_lock(&mysrcu);
> > 		do_something();
> > 		srcu_read_unlock(&mysrcu, idx);
> > 		spin_unlock(&mylock);
> > 
> > 	CPU 1:
> > 		idx = srcu_read_lock(&mysrcu);
> > 		spin_lock(&mylock);
> > 		do_something();
> > 		spin_unlock(&mylock);
> > 		srcu_read_unlock(&mysrcu, idx);
> > 
> > Adding Boqun on CC in case it is easier than I think.  ;-)
> 
> First I think reader-writer deadlock detection won't treat this as a
> deadlock, because srcu_read_lock() is a recursive read lock ;-) in other
> words, lockdep knows they don't block each other.

Nice!

> I was actually considering to equip SRCU with reader-writer deadlock
> detection when:
> 
> 	https://lore.kernel.org/lkml/20180412021233.ewncg5jjuzjw3x62@tardis/
> 
> The problem (for SRCU to use reader-writer deadlock detection) is
> letting lockdep know synchronize_srcu() doesn't block srcu_read_lock(), 
> so looks like I owe you a new lockdep annotation primitive ;-)

Even better!  ;-)

							Thanx, Paul

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection
  2022-10-21  8:34   ` Petr Mladek
@ 2022-10-31 13:06     ` John Ogness
  2022-10-31 14:09       ` Petr Mladek
  0 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-31 13:06 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Miguel Ojeda, Paul E. McKenney, Greg Kroah-Hartman

On 2022-10-21, Petr Mladek <pmladek@suse.com> wrote:
>> +#ifdef CONFIG_LOCKDEP
>> +bool console_srcu_read_lock_is_held(void)

>> +#ifdef CONFIG_LOCKDEP
>> +extern bool console_srcu_read_lock_is_held(void);
>> +#else
>> +static inline bool console_srcu_read_lock_is_held(void)
>> +{
>> +	return 1;
>> +}
>> +#endif
>
> srcu_read_lock_held() actually depends on CONFIG_DEBUG_LOCK_ALLOC.

I really want to keep @console_srcu private. For v3 I am changing it to
depend on ifdef CONFIG_DEBUG_LOCK_ALLOC.

>> @@ -2989,6 +3021,9 @@ void console_stop(struct console *console)
>>  	console_lock();
>>  	console->flags &= ~CON_ENABLED;
>>  	console_unlock();
>> +
>> +	/* Ensure that all SRCU list walks have completed */
>> +	synchronize_srcu(&console_srcu);
>
> What is the motivation for this synchronization, please?

For v3 I change it to:

    /*
     * Ensure that all SRCU list walks have completed. All contexts must
     * be able to see that this console is disabled so that (for example)
     * the caller can suspend the port without risk of another context
     * using the port.
     */

>> @@ -3179,6 +3214,17 @@ void register_console(struct console *newcon)
>>  		newcon->flags &= ~CON_PRINTBUFFER;
>>  	}
>>  
>> +	newcon->dropped = 0;
>> +	if (newcon->flags & CON_PRINTBUFFER) {
>> +		/* Get a consistent copy of @syslog_seq. */
>> +		mutex_lock(&syslog_lock);
>> +		newcon->seq = syslog_seq;
>> +		mutex_unlock(&syslog_lock);
>> +	} else {
>> +		/* Begin with next message. */
>> +		newcon->seq = prb_next_seq(prb);
>
> Hmm, prb_next_seq() is the next-to-be written message. It does not
> guarantee that all the existing messages already reached the boot
> console.
>
> Ideally, we should set it to con->seq from the related boot
> consoles. But we do not know which one it is.

Yes. It is really sad that we do not know this. We need to fix this boot
console handover at some point in the future.

> A good enough solution would be to set it to the minimal con->seq
> of all registered boot consoles. They would most likely be on
> the same sequence number. Anyway, con->seq has to be read under
> console_lock() at least at this stage of the patchset.

Well, for v3 I would do the following:

- explicitly have boot consoles also behave like CON_PRINTBUFFER

- use the oldest boot+enabled message

The code would include the additional changes:

-	if (newcon->flags & CON_PRINTBUFFER) {
+	if (newcon->flags & (CON_PRINTBUFFER | CON_BOOT)) {
 		/* Get a consistent copy of @syslog_seq. */
 		mutex_lock(&syslog_lock);
 		newcon->seq = syslog_seq;
 		mutex_unlock(&syslog_lock);
 	} else {
-		/* Begin with next message. */
+		/* Begin with next message added to the ringbuffer. */
 		newcon->seq = prb_next_seq(prb);
+
+		/*
+		 * If an enabled boot console is not caught up, start with
+		 * that message instead. That boot console will be
+		 * unregistered shortly and may be the same device.
+		 */
+		for_each_console(con) {
+			if ((con->flags & (CON_BOOT | CON_ENABLED)) == (CON_BOOT | CON_ENABLED) &&
+			    con->seq < newcon->seq) {
+				newcon->seq = con->seq;
+			}
+		}
 	}
>> +		hlist_add_behind_rcu(&newcon->node, console_list.first);
>>  	}
>>  	console_unlock();
>> +
>> +	/* No need to synchronize SRCU here! */
>
> This would deserve explanation why it is not needed. At least some
> hint.

For v3 I change it to:

    /*
     * No need to synchronize SRCU here! The caller does not rely
     * on all contexts being able to see the new console before
     * register_console() completes.
     */

>> @@ -3269,6 +3307,10 @@ int unregister_console(struct console *console)
>>  		console_first()->flags |= CON_CONSDEV;
>>  
>>  	console_unlock();
>> +
>> +	/* Ensure that all SRCU list walks have completed */
>> +	synchronize_srcu(&console_srcu);
>
> Again, we should explain why.

For v3 I change it to:

    /*
     * Ensure that all SRCU list walks have completed. All contexts
     * must not be able to see this console in the list so that any
     * exit/cleanup routines can be performed safely.
     */

John

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection
  2022-10-31 13:06     ` John Ogness
@ 2022-10-31 14:09       ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-10-31 14:09 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Miguel Ojeda, Paul E. McKenney, Greg Kroah-Hartman

On Mon 2022-10-31 14:12:36, John Ogness wrote:
> On 2022-10-21, Petr Mladek <pmladek@suse.com> wrote:
> >> @@ -3179,6 +3214,17 @@ void register_console(struct console *newcon)
> >>  		newcon->flags &= ~CON_PRINTBUFFER;
> >>  	}
> >>  
> >> +	newcon->dropped = 0;
> >> +	if (newcon->flags & CON_PRINTBUFFER) {
> >> +		/* Get a consistent copy of @syslog_seq. */
> >> +		mutex_lock(&syslog_lock);
> >> +		newcon->seq = syslog_seq;
> >> +		mutex_unlock(&syslog_lock);
> >> +	} else {
> >> +		/* Begin with next message. */
> >> +		newcon->seq = prb_next_seq(prb);
> >
> > Hmm, prb_next_seq() is the next-to-be written message. It does not
> > guarantee that all the existing messages already reached the boot
> > console.
> >
> > Ideally, we should set it to con->seq from the related boot
> > consoles. But we do not know which one it is.
> 
> Yes. It is really sad that we do not know this. We need to fix this boot
> console handover at some point in the future.
> 
> > A good enough solution would be to set it to the minimal con->seq
> > of all registered boot consoles. They would most likely be on
> > the same sequence number. Anyway, con->seq has to be read under
> > console_lock() at least at this stage of the patchset.
> 
> Well, for v3 I would do the following:
> 
> - explicitly have boot consoles also behave like CON_PRINTBUFFER
> 
> - use the oldest boot+enabled message
> 
> The code would include the additional changes:
> 
> -	if (newcon->flags & CON_PRINTBUFFER) {
> +	if (newcon->flags & (CON_PRINTBUFFER | CON_BOOT)) {
>  		/* Get a consistent copy of @syslog_seq. */
>  		mutex_lock(&syslog_lock);
>  		newcon->seq = syslog_seq;
>  		mutex_unlock(&syslog_lock);
>  	} else {
> -		/* Begin with next message. */
> +		/* Begin with next message added to the ringbuffer. */
>  		newcon->seq = prb_next_seq(prb);
> +
> +		/*
> +		 * If an enabled boot console is not caught up, start with
> +		 * that message instead. That boot console will be
> +		 * unregistered shortly and may be the same device.
> +		 */
> +		for_each_console(con) {
> +			if ((con->flags & (CON_BOOT | CON_ENABLED)) == (CON_BOOT | CON_ENABLED) &&
> +			    con->seq < newcon->seq) {
> +				newcon->seq = con->seq;
> +			}
> +		}
>  	}

Makes sense. Just please do it in a separate patch. It might
potentially change the behavior. And the problem have been
there since the global "console_seq" was moved to struct console_seq.

> >> +		hlist_add_behind_rcu(&newcon->node, console_list.first);
> >>  	}
> >>  	console_unlock();
> >> +

All the other proposed changes look good.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 05/38] printk: use console_is_enabled()
  2022-10-21  9:25   ` Petr Mladek
@ 2022-10-31 15:39     ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-10-31 15:39 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On 2022-10-21, Petr Mladek <pmladek@suse.com> wrote:
>>  static inline bool console_is_usable(struct console *con)
>>  {
>> -	if (!(con->flags & CON_ENABLED))
>> +	if (!console_is_enabled(con))
>>  		return false;
>
> This allows to use console_is_usable() without synchronization against
> modification of the state. I guess that it will be needed for the
> printk kthreads. But it is not needed at the moment.

It will be needed once console_lock is no longer providing the
synchronization for console->flags (later in _this_ series).

I will add to the commit message that this is a preparatory change for
when console_lock no longer provides this synchronization.

>> @@ -2944,7 +2944,7 @@ void console_unblank(void)
>>  	console_locked = 1;
>>  	console_may_schedule = 0;
>>  	for_each_console(c)
>> -		if ((c->flags & CON_ENABLED) && c->unblank)
>> +		if (console_is_enabled(c) && c->unblank)
>>  			c->unblank();
>>  	console_unlock();
>
> The reading of the flag is actually synchronized against modifications
> here. I guess that we need this because c->unblank() probably is not safe
> against other operations with the console, e.g. c->write().

Again, we will need it later in this series when holding console_lock
does not provide the necessary synchronization.

>> @@ -3098,7 +3098,7 @@ static int try_enable_preferred_console(struct console *newcon,
>>  	 * without matching. Accept the pre-enabled consoles only when match()
>>  	 * and setup() had a chance to be called.
>>  	 */
>> -	if (newcon->flags & CON_ENABLED && c->user_specified ==	user_specified)
>> +	if (console_is_enabled(newcon) && (c->user_specified == user_specified))
>
> This is not racy because newcon is not in console_list at this
> point. So that the state can't be modified by another callers.
>
> Anyway, it is not explicitly synchronized, so we need to use
> console_is_enabled with data_race() annotation.

For this case, it makes sense to _not_ use console_is_enabled(). This
code will be synchronized against writes even after console_lock has
been relieved of this responsibility.

Originally I wanted to replace _all_ checks with console_is_enabled(),
but since synchronization is rare, I'll keep the manual checks for those
(and add a comment that it is not a data race).

John

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 06/38] tty: nfcon: use console_is_enabled()
  2022-10-21  9:55   ` Petr Mladek
@ 2022-10-31 15:59     ` John Ogness
  2022-11-01  8:57       ` Petr Mladek
  0 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-10-31 15:59 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Geert Uytterhoeven, linux-m68k

On 2022-10-21, Petr Mladek <pmladek@suse.com> wrote:
>> diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c
>> index 557d60867f98..c542fc2b121f 100644
>> --- a/arch/m68k/emu/nfcon.c
>> +++ b/arch/m68k/emu/nfcon.c
>> @@ -151,7 +151,7 @@ static int __init nfcon_init(void)
>>  
>>  	nfcon_tty_driver = driver;
>>  
>> -	if (!(nf_console.flags & CON_ENABLED))
>> +	if (!console_is_enabled(&nf_console))
>
> Heh, the check of CON_ENABLED does not make much sense. IMHO, the
> important thing is whether the console is in console_list or not.
>
> I would personally add a check at the beginning of register_console()
> whether the console is already registered and enabled() and do
> nothing when already done.

Actually, register_console() already has this check, but it does a
WARN(). If the debug setup is used for nfcon, this situation is
normal. So probably to avoid the WARN, the CON_ENABLED code was added.

> I would be nice to fix this. But it might be done later.

I could add a console_is_registered() function that checks if the
console is in the console list and use that instead. If we are going to
touch this code, we might as well touch it correctly, right?

John

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 06/38] tty: nfcon: use console_is_enabled()
  2022-10-31 15:59     ` John Ogness
@ 2022-11-01  8:57       ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-11-01  8:57 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Geert Uytterhoeven, linux-m68k

On Mon 2022-10-31 17:05:54, John Ogness wrote:
> On 2022-10-21, Petr Mladek <pmladek@suse.com> wrote:
> >> diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c
> >> index 557d60867f98..c542fc2b121f 100644
> >> --- a/arch/m68k/emu/nfcon.c
> >> +++ b/arch/m68k/emu/nfcon.c
> >> @@ -151,7 +151,7 @@ static int __init nfcon_init(void)
> >>  
> >>  	nfcon_tty_driver = driver;
> >>  
> >> -	if (!(nf_console.flags & CON_ENABLED))
> >> +	if (!console_is_enabled(&nf_console))
> >
> > Heh, the check of CON_ENABLED does not make much sense. IMHO, the
> > important thing is whether the console is in console_list or not.
> >
> > I would personally add a check at the beginning of register_console()
> > whether the console is already registered and enabled() and do
> > nothing when already done.
> 
> Actually, register_console() already has this check, but it does a
> WARN(). If the debug setup is used for nfcon, this situation is
> normal.

I see.

> So probably to avoid the WARN, the CON_ENABLED code was added.

I though more about it. I would keep the warning for the case
when the 2nd registration is not intentional.

This driver has two ways how the console can be registered.
It can happen either in nfcon_init() or in nf_debug_setup().
It is better to have an explicit check to show that it is intentional.


> > I would be nice to fix this. But it might be done later.
> 
> I could add a console_is_registered() function that checks if the
> console is in the console list and use that instead. If we are going to
> touch this code, we might as well touch it correctly, right?

It would be great. It is actually much easier after switching
to the hlist.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 09/38] netconsole: use console_is_enabled()
  2022-10-21 13:14   ` Petr Mladek
@ 2022-11-04 15:12     ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-11-04 15:12 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, netdev

On 2022-10-21, Petr Mladek <pmladek@suse.com> wrote:
>> diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
>> index bdff9ac5056d..073e59a06f21 100644
>> --- a/drivers/net/netconsole.c
>> +++ b/drivers/net/netconsole.c
>> @@ -332,7 +332,7 @@ static ssize_t enabled_store(struct config_item *item,
>>  	}
>>  
>>  	if (enabled) {	/* true */
>> -		if (nt->extended && !(netconsole_ext.flags & CON_ENABLED)) {
>> +		if (nt->extended && !console_is_enabled(&netconsole_ext)) {
>>  			netconsole_ext.flags |= CON_ENABLED;
>>  			register_console(&netconsole_ext);
>>  		}
>> @@ -915,7 +915,7 @@ static int __init init_netconsole(void)
>>  	if (err)
>>  		goto undonotifier;
>>  
>> -	if (netconsole_ext.flags & CON_ENABLED)
>> +	if (console_is_enabled(&netconsole_ext))
>>  		register_console(&netconsole_ext);
>>  	register_console(&netconsole);
>>  	pr_info("network logging started\n");
>
> This looks like a (mis)use of CON_ENABLED flag.

Yes. When @netconsole_ext is registered, CON_ENABLED is always set. So
it should be set in the static initialization. The first hunk should be
using the new console_is_registered(). The second hunk should be using a
local @extended bool variable. Also, in cleanup_netconsole() it should
check if the console is registered:

if (console_is_registered(&netconsole_ext))
        unregister_console(&netconsole_ext);

I will make all of these changes for v3. Then there will be no
checking/setting of CON_ENABLED in the driver.

John Ogness

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-10-25 11:28       ` John Ogness
@ 2022-11-04 16:23         ` John Ogness
  2022-11-07  8:47           ` Petr Mladek
  0 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-11-04 16:23 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Jason Wessel, Daniel Thompson, Greg Kroah-Hartman,
	Jiri Slaby, kgdb-bugreport, linux-serial

On 2022-10-24, Doug Anderson <dianders@chromium.org> wrote:
> It actually only holds console_list_lock() even at the end of the
> series. Still, it seems weird that we're declaring the `data_race` on
> CON_ENABLED but not CON_BOOT ?

For my upcoming v3 I decided to drop this patch and will keep the
existing direct reading of @flags. Instead of this patch, for v3 the
comment will additionally mention why @flags is allowed to be directly
read:

/*
 * Hold the console_lock to guarantee that no consoles are
 * unregistered until the kgdboc_earlycon setup is complete.
 * Trapping the exit() callback relies on exit() not being
 * called until the trap is setup. This also allows safe
 * traversal of the console list and race-free reading of @flags.
 */

John Ogness

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 27/38] printk: console_flush_all: use srcu console list iterator
  2022-10-25 15:17   ` Petr Mladek
@ 2022-11-07  0:00     ` John Ogness
  2022-11-07 13:03       ` Petr Mladek
  0 siblings, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-11-07  0:00 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On 2022-10-25, Petr Mladek <pmladek@suse.com> wrote:
>>   console_lock()
>>   | mutex_acquire(&console_lock_dep_map)       <-- console lock
>>   |
>>   console_unlock()
>>   | console_flush_all()
>>   | | srcu_read_lock(&console_srcu)            <-- srcu lock
>>   | | console_emit_next_record()
>>   | | | console_lock_spinning_disable_and_check()
>>   | | | | srcu_read_unlock(&console_srcu)      <-- srcu unlock
>>   | | | | mutex_release(&console_lock_dep_map) <-- console unlock
>>
>> @@ -2819,12 +2827,17 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
>>  				/* Extended consoles do not print "dropped messages". */
>>  				progress = console_emit_next_record(con, &text[0],
>>  								    &ext_text[0], NULL,
>> -								    handover);
>> +								    handover, cookie);
>>  			} else {
>>  				progress = console_emit_next_record(con, &text[0],
>>  								    NULL, &dropped_text[0],
>> -								    handover);
>> +								    handover, cookie);
>>  			}
>> +
>> +			/*
>> +			 * If a handover has occurred, the SRCU read lock
>> +			 * is already released.
>> +			 */
>>  			if (*handover)
>>  				return false;
>
> Please, release the SRCU read lock here:
>
> 			if (*handover) {
> 				console_srcu_read_unlock(cookie);
> 				return false;
> 			}
>
> The lock should be released in the same function where it was taken.
> It does not require passing the cookie and looks more straightforward.

It looks more straight forward, but it is incorrect from a locking
perspective.

The locking order was:

console_lock()
console_srcu_read_lock()

But for a handover at this point in code, console_emit_next_record() has
already released the console_lock (to the spinning context). The
console_srcu_read_lock should have been released first.

> We actually do the same when abandon_console_lock_in_panic()
> returns true. We could share the code:
>
> handover_abandon:
> 	console_srcu_read_unlock(cookie);
> 	return false;

This case is different. Here the console_lock was not released yet so it
is fine to perform the console_srcu_read_unlock() here.

John Ogness

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-11-04 16:23         ` John Ogness
@ 2022-11-07  8:47           ` Petr Mladek
  2022-11-07  9:45             ` John Ogness
  0 siblings, 1 reply; 151+ messages in thread
From: Petr Mladek @ 2022-11-07  8:47 UTC (permalink / raw)
  To: John Ogness
  Cc: Doug Anderson, Sergey Senozhatsky, Steven Rostedt,
	Thomas Gleixner, linux-kernel, Jason Wessel, Daniel Thompson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

On Fri 2022-11-04 17:29:15, John Ogness wrote:
> On 2022-10-24, Doug Anderson <dianders@chromium.org> wrote:
> > It actually only holds console_list_lock() even at the end of the
> > series. Still, it seems weird that we're declaring the `data_race` on
> > CON_ENABLED but not CON_BOOT ?
> 
> For my upcoming v3 I decided to drop this patch and will keep the
> existing direct reading of @flags. Instead of this patch, for v3 the
> comment will additionally mention why @flags is allowed to be directly
> read:
> 
> /*
>  * Hold the console_lock to guarantee that no consoles are
              ^^^^^^^^^^^^
>  * unregistered until the kgdboc_earlycon setup is complete.

My understanding is that this is synchronized by console_list_lock.
Or do I miss something?

>  * Trapping the exit() callback relies on exit() not being
>  * called until the trap is setup. This also allows safe
>  * traversal of the console list and race-free reading of @flags.
>  */

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 12/38] tty: serial: kgdboc: use console_is_enabled()
  2022-11-07  8:47           ` Petr Mladek
@ 2022-11-07  9:45             ` John Ogness
  0 siblings, 0 replies; 151+ messages in thread
From: John Ogness @ 2022-11-07  9:45 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Doug Anderson, Sergey Senozhatsky, Steven Rostedt,
	Thomas Gleixner, linux-kernel, Jason Wessel, Daniel Thompson,
	Greg Kroah-Hartman, Jiri Slaby, kgdb-bugreport, linux-serial

On 2022-11-07, Petr Mladek <pmladek@suse.com> wrote:
>> /*
>>  * Hold the console_lock to guarantee that no consoles are
>               ^^^^^^^^^^^^
>>  * unregistered until the kgdboc_earlycon setup is complete.
>
> My understanding is that this is synchronized by console_list_lock.
> Or do I miss something?

Yes, in the end the comment will say console_list_lock. At this point in
the series, the console_lock is still used. The comment is updated later
(as in patch 34 of the v2 series).

John

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 33/38] printk: introduce console_list_lock
  2022-10-27 18:50     ` Paul E. McKenney
  2022-10-28 18:09       ` Boqun Feng
@ 2022-11-07 10:10       ` John Ogness
  2022-11-07 16:16         ` Paul E. McKenney
  1 sibling, 1 reply; 151+ messages in thread
From: John Ogness @ 2022-11-07 10:10 UTC (permalink / raw)
  To: paulmck, Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, boqun.feng

On 2022-10-27, "Paul E. McKenney" <paulmck@kernel.org> wrote:
> One way to save a line is as follows:
>
> 	WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_LOCK_ALLOC) &&
> 		     debug_lockdep_rcu_enabled() &&
> 		     srcu_read_lock_held(&console_srcu));

Unfortunately this suggestion does not work because
debug_lockdep_rcu_enabled() only exists if CONFIG_DEBUG_LOCK_ALLOC is
enabled. Would you be interested in having an empty implementation?
Then my check would not need to be concerned about
CONFIG_DEBUG_LOCK_ALLOC at all. It would become:

 	WARN_ON_ONCE(debug_lockdep_rcu_enabled() &&
 		     srcu_read_lock_held(&console_srcu));

The patch below could be used to achieve that.

John

--------8<-------------
From 71d9e484d5128cd1e57e5bff5391d91789f444fa Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Mon, 7 Nov 2022 11:06:40 +0106
Subject: [PATCH] rcu: implement lockdep_rcu_enabled for
 !CONFIG_DEBUG_LOCK_ALLOC

Provide an implementation for debug_lockdep_rcu_enabled() when
CONFIG_DEBUG_LOCK_ALLOC is not enabled. This allows code to check
if rcu lockdep debugging is available without needing an extra
check if CONFIG_DEBUG_LOCK_ALLOC is enabled.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 include/linux/rcupdate.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 08605ce7379d..65178c40ab6f 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -340,6 +340,11 @@ static inline int rcu_read_lock_any_held(void)
 	return !preemptible();
 }
 
+static inline int debug_lockdep_rcu_enabled(void)
+{
+	return 0;
+}
+
 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
 #ifdef CONFIG_PROVE_RCU
-- 
2.30.2

^ permalink raw reply related	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 27/38] printk: console_flush_all: use srcu console list iterator
  2022-11-07  0:00     ` John Ogness
@ 2022-11-07 13:03       ` Petr Mladek
  0 siblings, 0 replies; 151+ messages in thread
From: Petr Mladek @ 2022-11-07 13:03 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner, linux-kernel

On Mon 2022-11-07 01:06:02, John Ogness wrote:
> On 2022-10-25, Petr Mladek <pmladek@suse.com> wrote:
> >>   console_lock()
> >>   | mutex_acquire(&console_lock_dep_map)       <-- console lock
> >>   |
> >>   console_unlock()
> >>   | console_flush_all()
> >>   | | srcu_read_lock(&console_srcu)            <-- srcu lock
> >>   | | console_emit_next_record()
> >>   | | | console_lock_spinning_disable_and_check()
> >>   | | | | srcu_read_unlock(&console_srcu)      <-- srcu unlock
> >>   | | | | mutex_release(&console_lock_dep_map) <-- console unlock
> >>
> >> @@ -2819,12 +2827,17 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
> >>  				/* Extended consoles do not print "dropped messages". */
> >>  				progress = console_emit_next_record(con, &text[0],
> >>  								    &ext_text[0], NULL,
> >> -								    handover);
> >> +								    handover, cookie);
> >>  			} else {
> >>  				progress = console_emit_next_record(con, &text[0],
> >>  								    NULL, &dropped_text[0],
> >> -								    handover);
> >> +								    handover, cookie);
> >>  			}
> >> +
> >> +			/*
> >> +			 * If a handover has occurred, the SRCU read lock
> >> +			 * is already released.
> >> +			 */
> >>  			if (*handover)
> >>  				return false;
> >
> > Please, release the SRCU read lock here:
> >
> > 			if (*handover) {
> > 				console_srcu_read_unlock(cookie);
> > 				return false;
> > 			}
> >
> > The lock should be released in the same function where it was taken.
> > It does not require passing the cookie and looks more straightforward.
> 
> It looks more straight forward, but it is incorrect from a locking
> perspective.
> 
> The locking order was:
> 
> console_lock()
> console_srcu_read_lock()
> 
> But for a handover at this point in code, console_emit_next_record() has
> already released the console_lock (to the spinning context). The
> console_srcu_read_lock should have been released first.

Ah, I see. I should be read all the comments more carefully.
I do not know about any better solution. Feel free to use:

Reviewed-by: Petr Mladek <pmladek@suse.com>


Note:

The complexity is caused by calling
mutex_release() in console_lock_spinning_disable_and_check() and
mutex_acquire() in console_trylock_spinning().

I wondered if we really need to do so. These functions actually do not
release or acquire the console_lock. But it seems that it is necessary
because lockdep is not able to track the lock when it was moved into
another process.

I even tried to replace mutex_acquire()/mutex_release() with
rwsem_acquire()/rwsem_release(). But it did not help. lockdep
still complained when I removed these calls from
the _spinning_() API. Sigh.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 151+ messages in thread

* Re: [PATCH printk v2 33/38] printk: introduce console_list_lock
  2022-11-07 10:10       ` John Ogness
@ 2022-11-07 16:16         ` Paul E. McKenney
  0 siblings, 0 replies; 151+ messages in thread
From: Paul E. McKenney @ 2022-11-07 16:16 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, Greg Kroah-Hartman, boqun.feng

On Mon, Nov 07, 2022 at 11:16:56AM +0106, John Ogness wrote:
> On 2022-10-27, "Paul E. McKenney" <paulmck@kernel.org> wrote:
> > One way to save a line is as follows:
> >
> > 	WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_LOCK_ALLOC) &&
> > 		     debug_lockdep_rcu_enabled() &&
> > 		     srcu_read_lock_held(&console_srcu));
> 
> Unfortunately this suggestion does not work because
> debug_lockdep_rcu_enabled() only exists if CONFIG_DEBUG_LOCK_ALLOC is
> enabled. Would you be interested in having an empty implementation?
> Then my check would not need to be concerned about
> CONFIG_DEBUG_LOCK_ALLOC at all. It would become:
> 
>  	WARN_ON_ONCE(debug_lockdep_rcu_enabled() &&
>  		     srcu_read_lock_held(&console_srcu));
> 
> The patch below could be used to achieve that.

Looks quite sensible to me!  There are probably a few other places
where it might be used.

							Thanx, Paul

> John
> 
> --------8<-------------
> >From 71d9e484d5128cd1e57e5bff5391d91789f444fa Mon Sep 17 00:00:00 2001
> From: John Ogness <john.ogness@linutronix.de>
> Date: Mon, 7 Nov 2022 11:06:40 +0106
> Subject: [PATCH] rcu: implement lockdep_rcu_enabled for
>  !CONFIG_DEBUG_LOCK_ALLOC
> 
> Provide an implementation for debug_lockdep_rcu_enabled() when
> CONFIG_DEBUG_LOCK_ALLOC is not enabled. This allows code to check
> if rcu lockdep debugging is available without needing an extra
> check if CONFIG_DEBUG_LOCK_ALLOC is enabled.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  include/linux/rcupdate.h | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> index 08605ce7379d..65178c40ab6f 100644
> --- a/include/linux/rcupdate.h
> +++ b/include/linux/rcupdate.h
> @@ -340,6 +340,11 @@ static inline int rcu_read_lock_any_held(void)
>  	return !preemptible();
>  }
>  
> +static inline int debug_lockdep_rcu_enabled(void)
> +{
> +	return 0;
> +}
> +
>  #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
>  
>  #ifdef CONFIG_PROVE_RCU
> -- 
> 2.30.2

^ permalink raw reply	[flat|nested] 151+ messages in thread

end of thread, other threads:[~2022-11-07 16:16 UTC | newest]

Thread overview: 151+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-19 14:55 [PATCH printk v2 00/38] reduce console_lock scope John Ogness
2022-10-19 14:55 ` John Ogness
2022-10-19 14:55 ` John Ogness
2022-10-19 14:55 ` John Ogness
2022-10-19 14:55 ` [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function John Ogness
2022-10-19 15:41   ` Greg Kroah-Hartman
2022-10-24  5:22   ` Sergey Senozhatsky
2022-10-25  0:34   ` Doug Anderson
2022-10-19 14:55 ` [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist John Ogness
2022-10-19 15:44   ` Greg Kroah-Hartman
2022-10-19 21:46     ` John Ogness
2022-10-20  7:43       ` Greg Kroah-Hartman
2022-10-20 12:36   ` Petr Mladek
2022-10-24  5:23   ` Sergey Senozhatsky
2022-10-19 14:55 ` [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection John Ogness
2022-10-19 15:16   ` Miguel Ojeda
2022-10-19 17:12   ` Paul E. McKenney
2022-10-21  8:34   ` Petr Mladek
2022-10-31 13:06     ` John Ogness
2022-10-31 14:09       ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21  8:57   ` Petr Mladek
2022-10-21  9:37     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 05/38] printk: use console_is_enabled() John Ogness
2022-10-21  9:25   ` Petr Mladek
2022-10-31 15:39     ` John Ogness
2022-10-19 14:55 ` [PATCH printk v2 06/38] tty: nfcon: " John Ogness
2022-10-21  9:55   ` Petr Mladek
2022-10-31 15:59     ` John Ogness
2022-11-01  8:57       ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 07/38] um: kmsg_dump: " John Ogness
2022-10-19 14:55   ` John Ogness
2022-10-21 12:46   ` Petr Mladek
2022-10-21 12:46     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 08/38] efi: earlycon: " John Ogness
2022-10-19 15:32   ` Ard Biesheuvel
2022-10-21 12:53   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 09/38] netconsole: " John Ogness
2022-10-21 13:14   ` Petr Mladek
2022-11-04 15:12     ` John Ogness
2022-10-19 14:55 ` [PATCH printk v2 10/38] tty: hvc: " John Ogness
2022-10-19 14:55   ` John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-19 16:01     ` Greg Kroah-Hartman
2022-10-21 13:22   ` Petr Mladek
2022-10-21 13:22     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 11/38] tty: serial: earlycon: " John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21 13:51   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 12/38] tty: serial: kgdboc: " John Ogness
2022-10-19 16:00   ` Greg Kroah-Hartman
2022-10-21 14:10   ` Petr Mladek
2022-10-24 22:46   ` Doug Anderson
2022-10-25  0:49     ` Doug Anderson
2022-10-25 11:28       ` John Ogness
2022-11-04 16:23         ` John Ogness
2022-11-07  8:47           ` Petr Mladek
2022-11-07  9:45             ` John Ogness
2022-10-19 14:55 ` [PATCH printk v2 13/38] tty: serial: pic32_uart: " John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21 14:11   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 14/38] tty: serial: samsung_tty: " John Ogness
2022-10-19 14:55   ` John Ogness
2022-10-19 16:00   ` Greg Kroah-Hartman
2022-10-19 16:00     ` Greg Kroah-Hartman
2022-10-21 14:14   ` Petr Mladek
2022-10-21 14:14     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 15/38] tty: serial: serial_core: " John Ogness
2022-10-19 16:00   ` Greg Kroah-Hartman
2022-10-21 14:14   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 16/38] tty: serial: xilinx_uartps: " John Ogness
2022-10-19 14:55   ` John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-19 16:01     ` Greg Kroah-Hartman
2022-10-21 14:23   ` Petr Mladek
2022-10-21 14:23     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 17/38] tty: tty_io: " John Ogness
2022-10-19 16:00   ` Greg Kroah-Hartman
2022-10-21 14:24   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 18/38] usb: early: xhci-dbc: " John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21 14:27   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 19/38] kdb: kdb_io: " John Ogness
2022-10-21 14:28   ` Petr Mladek
2022-10-25  0:34   ` Doug Anderson
2022-10-19 14:55 ` [PATCH printk v2 20/38] um: kmsg_dumper: use srcu console list iterator John Ogness
2022-10-19 14:55   ` John Ogness
2022-10-21 14:56   ` Petr Mladek
2022-10-21 14:56     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 21/38] serial: kgdboc: " John Ogness
2022-10-19 16:02   ` Greg Kroah-Hartman
2022-10-21 15:09   ` Petr Mladek
2022-10-25  0:33     ` Doug Anderson
2022-10-19 14:55 ` [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage John Ogness
2022-10-20  7:42   ` Greg Kroah-Hartman
2022-10-25  0:36   ` Doug Anderson
2022-10-25 10:09   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 23/38] tty: tty_io: " John Ogness
2022-10-20  7:43   ` Greg Kroah-Hartman
2022-10-25 13:31   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 24/38] xen: fbfront: use srcu console list iterator John Ogness
2022-10-19 14:55   ` John Ogness
2022-10-25 13:39   ` Petr Mladek
2022-10-25 13:39     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 25/38] proc: consoles: document console_lock usage John Ogness
2022-10-25 14:40   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 26/38] kdb: use srcu console list iterator John Ogness
2022-10-25  0:47   ` Doug Anderson
2022-10-25 14:59     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 27/38] printk: console_flush_all: " John Ogness
2022-10-25 15:17   ` Petr Mladek
2022-11-07  0:00     ` John Ogness
2022-11-07 13:03       ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 28/38] printk: console_unblank: " John Ogness
2022-10-25 15:28   ` Petr Mladek
2022-10-25 15:31   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 29/38] printk: console_flush_on_panic: " John Ogness
2022-10-25 15:32   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 30/38] printk: console_device: " John Ogness
2022-10-25 15:35   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 31/38] printk: register_console: " John Ogness
2022-10-26  8:20   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 32/38] printk: __pr_flush: " John Ogness
2022-10-26  8:33   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 33/38] printk: introduce console_list_lock John Ogness
2022-10-20  7:53   ` Greg Kroah-Hartman
2022-10-27 10:09   ` Petr Mladek
2022-10-27 18:50     ` Paul E. McKenney
2022-10-28 18:09       ` Boqun Feng
2022-10-28 18:42         ` Paul E. McKenney
2022-11-07 10:10       ` John Ogness
2022-11-07 16:16         ` Paul E. McKenney
2022-10-19 14:55 ` [PATCH printk v2 34/38] serial: kgdboc: use console_list_lock instead of console_lock John Ogness
2022-10-20  7:52   ` Greg Kroah-Hartman
2022-10-27 10:13   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 35/38] tty: tty_io: use console_list_lock for list synchronization John Ogness
2022-10-20  7:43   ` Greg Kroah-Hartman
2022-10-27 10:17   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 36/38] proc: consoles: use console_list_lock for list iteration John Ogness
2022-10-27 12:02   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 37/38] printk: relieve console_lock of list synchronization duties John Ogness
2022-10-27 12:40   ` Petr Mladek
2022-10-19 14:56 ` [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred John Ogness
2022-10-19 14:56   ` John Ogness
2022-10-27 13:18   ` Petr Mladek
2022-10-27 13:18     ` Petr Mladek
2022-10-27 13:35     ` John Ogness
2022-10-27 13:35       ` John Ogness
2022-10-27 14:27       ` Petr Mladek
2022-10-27 14:27         ` Petr Mladek

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.