Hi, This is v4 of a series to wire up the nbcon consoles so that they actually perform printing using their write_atomic() callback. v3 is here [0]. For information about the motivation of the atomic consoles, please read the cover letter of v1 [1]. The main focus of this series: - For nbcon consoles, always call write_atomic() directly from printk() caller context for the panic CPU. - For nbcon consoles, call write_atomic() when unlocking the console lock. - Only perform the console lock/unlock dance if legacy or boot consoles are registered. - For legacy consoles, if nbcon consoles are registered, do not attempt to print from printk() caller context for the panic CPU until nbcon consoles have had a chance to print the most significant messages. - Mark emergency sections. In these sections printk() calls will only store the messages. Upon exiting the emergency section, nbcon consoles are flushed directly and legacy console flushing is triggered via irq_work. This series does _not_ include threaded printing or nbcon drivers. Those features will be added in separate follow-up series. Note: With this series, a system with _only_ nbcon consoles registered will not perform console printing unless the console lock is used (for synchronization), or when exiting emergency sections, or on panic. This is on purpose. When nbcon kthreads are introduced, they will fill the gaps. The changes since v3: - Modify the documentation of console_srcu_read_flags() to clarify that it is needed anytime a console _might_ be registered and the caller is not holding the console_list_lock. Hopefully this makes it clear when this helper function is needed. - Create a function uart_port_set_cons() for setting @cons of struct uart_port. It modifies @cons under the port lock to avoid possible races within the port lock wrapper. All (5) code sites are modified to use the new function. - Introduce 2 new required nbcon console callbacks device_lock()/device_unlock() to implement any internal locking required by the driver. (For example, for uart serial consoles it is locking/unlocking the port lock.) This is used during console registration to ensure that the hardware is not in use while the console transitions to registered. This avoids the risk that the port lock wrappers do not lock the nbcon console lock while the console was being registered on another CPU. These callbacks also will be used later by the printing kthreads. - Introduce struct nbcon_drvdata to track ownership state when using the port lock wrappers. This provides a race-free alternative to the @nbcon_locked_port flag used in v3. - Split the functionality of uart_nbcon_acquire() and uart_nbcon_release() into driver-specific and generic parts. The generic functions are named nbcon_driver_acquire() and nbcon_driver_release(). The driver-specific part is moved into serial_core.h into the new helper functions __uart_port_nbcon_acquire() and __uart_port_nbcon_release(). - Rename nbcon_atomic_flush_all() to nbcon_atomic_flush_pending() to emphasize that it only prints up to the latest record at the time of the call. Also, flush all the pending records of a console (without releasing ownership in between) before flushing the next nbcon console. This allows the full emergency block to be printed on at least one atomic console before trying the next. - Flush nbcon consoles directly in the caller context when exiting an emergency section. - If a CPU is in EMERGENCY context, do not trigger printing of legacy consoles via irq_work. - In panic, allow synchronous legacy printing before calling the panic handlers. Attempt to flush there in the panic context as well. - Remove the return value for the nbcon console atomic_write() callback. If ownership has not been lost, it is assumed the printing was successful. - Add a WARN_ON_ONCE if nbcon_emit_next_record() is called for a console that has not provided a write_atomic() callback. - Change the meaning of the return value of nbcon_atomic_emit_one() to allow nbcon_legacy_emit_next_record() to have the same return value meaning as console_emit_next_record(). - Remove all legacy @seq handling from nbcon.c. For nbcon consoles, printk.c handles the transfer and resetting of the legacy @seq value to @nbcon_seq. - Add a compiler barrier in __pr_flush() to ensure the compiler does not optimize out a local variable by replacing it with a racy read of multiple global variables. - Let __wake_up_klogd() remove unnecessary flags before possibly queuing irq_work. - Eliminate header proxying in nbcon.c. - Mark _all_ lockdep output blocks as emergency sections. - Mark _all_ rcu stall blocks as emergency sections. - Remove "(Optional)" in the documentation of the write_atomic() callback. Once threads are available, it will be optional. But at this point in the rework it is not. John Ogness [0] https://lore.kernel.org/lkml/20240218185726.1994771-1-john.ogness@xxxxxxxxxxxxx [1] https://lore.kernel.org/lkml/20230302195618.156940-1-john.ogness@xxxxxxxxxxxxx John Ogness (23): printk: Add notation to console_srcu locking printk: Properly deal with nbcon consoles on seq init printk: nbcon: Remove return value for write_atomic() printk: nbcon: Add detailed doc for write_atomic() printk: nbcon: Add callbacks to synchronize with driver printk: nbcon: Use driver synchronization while registering serial: core: Provide low-level functions to lock port printk: nbcon: Implement processing in port->lock wrapper printk: nbcon: Do not rely on proxy headers printk: nbcon: Fix kerneldoc for enums printk: Make console_is_usable() available to nbcon printk: Let console_is_usable() handle nbcon printk: Add @flags argument for console_is_usable() printk: Track registered boot consoles printk: nbcon: Use nbcon consoles in console_flush_all() printk: nbcon: Assign priority based on CPU state printk: nbcon: Add unsafe flushing on panic printk: Avoid console_lock dance if no legacy or boot consoles printk: Track nbcon consoles printk: Coordinate direct printing in panic panic: Mark emergency section in oops rcu: Mark emergency section in rcu stalls lockdep: Mark emergency sections in lockdep splats Sebastian Andrzej Siewior (1): printk: Check printk_deferred_enter()/_exit() usage Thomas Gleixner (3): printk: nbcon: Provide function to flush using write_atomic() printk: nbcon: Implement emergency sections panic: Mark emergency section in warn drivers/tty/serial/8250/8250_core.c | 6 +- drivers/tty/serial/amba-pl011.c | 2 +- drivers/tty/serial/serial_core.c | 2 +- include/linux/console.h | 138 ++++++++-- include/linux/printk.h | 32 ++- include/linux/serial_core.h | 116 ++++++++- kernel/locking/lockdep.c | 91 ++++++- kernel/panic.c | 9 + kernel/printk/internal.h | 56 +++- kernel/printk/nbcon.c | 382 ++++++++++++++++++++++++++-- kernel/printk/printk.c | 287 ++++++++++++++++----- kernel/printk/printk_ringbuffer.h | 2 + kernel/printk/printk_safe.c | 12 + kernel/rcu/tree_exp.h | 7 + kernel/rcu/tree_stall.h | 9 + 15 files changed, 1038 insertions(+), 113 deletions(-) base-commit: a2b4cab9da7746c42f87c13721d305baf0085a20 -- 2.39.2