diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 18:50:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 18:50:59 +0000 |
commit | ba6b167af6ee5e63ca79ad22e7719644aed12b2c (patch) | |
tree | 62272cbe2fb256ecb90fa6e2cbfa509541954d28 /debian/patches-rt | |
parent | Merging upstream version 6.8.9. (diff) | |
download | linux-ba6b167af6ee5e63ca79ad22e7719644aed12b2c.tar.xz linux-ba6b167af6ee5e63ca79ad22e7719644aed12b2c.zip |
Merging debian version 6.8.9-1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
130 files changed, 5813 insertions, 1985 deletions
diff --git a/debian/patches-rt/0001-ARM-vfp-Provide-vfp_lock-for-VFP-locking.patch b/debian/patches-rt/0001-ARM-vfp-Provide-vfp_lock-for-VFP-locking.patch index cd81c1d780..b2ee39b051 100644 --- a/debian/patches-rt/0001-ARM-vfp-Provide-vfp_lock-for-VFP-locking.patch +++ b/debian/patches-rt/0001-ARM-vfp-Provide-vfp_lock-for-VFP-locking.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri, 19 May 2023 16:57:29 +0200 Subject: [PATCH 1/4] ARM: vfp: Provide vfp_lock() for VFP locking. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz kernel_neon_begin() uses local_bh_disable() to ensure exclusive access to the VFP unit. This is broken on PREEMPT_RT because a BH disabled @@ -55,7 +55,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Is 'thread's most up to date state stored in this CPUs hardware? * Must be called from non-preemptible context. */ -@@ -819,7 +847,7 @@ void kernel_neon_begin(void) +@@ -837,7 +865,7 @@ void kernel_neon_begin(void) unsigned int cpu; u32 fpexc; @@ -64,7 +64,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Kernel mode NEON is only allowed outside of hardirq context with -@@ -850,7 +878,7 @@ void kernel_neon_end(void) +@@ -868,7 +896,7 @@ void kernel_neon_end(void) { /* Disable the NEON/VFP unit. */ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); diff --git a/debian/patches-rt/0001-arm-Disable-jump-label-on-PREEMPT_RT.patch b/debian/patches-rt/0001-arm-Disable-jump-label-on-PREEMPT_RT.patch index c312f1b8a3..7fbdfa5062 100644 --- a/debian/patches-rt/0001-arm-Disable-jump-label-on-PREEMPT_RT.patch +++ b/debian/patches-rt/0001-arm-Disable-jump-label-on-PREEMPT_RT.patch @@ -1,7 +1,7 @@ From: Thomas Gleixner <tglx@linutronix.de> Date: Wed, 8 Jul 2015 17:14:48 +0200 Subject: [PATCH 1/2] arm: Disable jump-label on PREEMPT_RT. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz jump-labels are used to efficiently switch between two possible code paths. To achieve this, stop_machine() is used to keep the CPU in a @@ -25,7 +25,7 @@ Link: https://lkml.kernel.org/r/20220613182447.112191-2-bigeasy@linutronix.de --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -74,7 +74,7 @@ config ARM +@@ -75,7 +75,7 @@ config ARM select HAS_IOPORT select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 diff --git a/debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch b/debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch new file mode 100644 index 0000000000..ae507f979e --- /dev/null +++ b/debian/patches-rt/0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch @@ -0,0 +1,75 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Sat, 9 Mar 2024 10:05:09 +0100 +Subject: [PATCH 1/4] net: Remove conditional threaded-NAPI wakeup based on + task state. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +A NAPI thread is scheduled by first setting NAPI_STATE_SCHED bit. If +successful (the bit was not yet set) then the NAPI_STATE_SCHED_THREADED +is set but only if thread's state is not TASK_INTERRUPTIBLE (is +TASK_RUNNING) followed by task wakeup. + +If the task is idle (TASK_INTERRUPTIBLE) then the +NAPI_STATE_SCHED_THREADED bit is not set. The thread is no relying on +the bit but always leaving the wait-loop after returning from schedule() +because there must have been a wakeup. + +The smpboot-threads implementation for per-CPU threads requires an +explicit condition and does not support "if we get out of schedule() +then there must be something to do". + +Removing this optimisation simplifies the following integration. + +Set NAPI_STATE_SCHED_THREADED unconditionally on wakeup and rely on it +in the wait path by removing the `woken' condition. + +Acked-by: Jakub Kicinski <kuba@kernel.org> +Link: https://lore.kernel.org/r/20240309090824.2956805-2-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + net/core/dev.c | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4452,13 +4452,7 @@ static inline void ____napi_schedule(str + */ + thread = READ_ONCE(napi->thread); + if (thread) { +- /* Avoid doing set_bit() if the thread is in +- * INTERRUPTIBLE state, cause napi_thread_wait() +- * makes sure to proceed with napi polling +- * if the thread is explicitly woken from here. +- */ +- if (READ_ONCE(thread->__state) != TASK_INTERRUPTIBLE) +- set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); ++ set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); + wake_up_process(thread); + return; + } +@@ -6654,8 +6648,6 @@ static int napi_poll(struct napi_struct + + static int napi_thread_wait(struct napi_struct *napi) + { +- bool woken = false; +- + set_current_state(TASK_INTERRUPTIBLE); + + while (!kthread_should_stop()) { +@@ -6664,15 +6656,13 @@ static int napi_thread_wait(struct napi_ + * Testing SCHED bit is not enough because SCHED bit might be + * set by some other busy poll thread or by napi_disable(). + */ +- if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state) || woken) { ++ if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state)) { + WARN_ON(!list_empty(&napi->poll_list)); + __set_current_state(TASK_RUNNING); + return 0; + } + + schedule(); +- /* woken being true indicates this thread owns this napi. */ +- woken = true; + set_current_state(TASK_INTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); diff --git a/debian/patches-rt/0001-perf-Move-irq_work_queue-where-the-event-is-prepared.patch b/debian/patches-rt/0001-perf-Move-irq_work_queue-where-the-event-is-prepared.patch new file mode 100644 index 0000000000..08a2950a4a --- /dev/null +++ b/debian/patches-rt/0001-perf-Move-irq_work_queue-where-the-event-is-prepared.patch @@ -0,0 +1,42 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Tue, 12 Mar 2024 19:01:49 +0100 +Subject: [PATCH 1/4] perf: Move irq_work_queue() where the event is prepared. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Only if perf_event::pending_sigtrap is zero, the irq_work accounted by +increminging perf_event::nr_pending. The member perf_event::pending_addr +might be overwritten by a subsequent event if the signal was not yet +delivered and is expected. The irq_work will not be enqeueued again +because it has a check to be only enqueued once. + +Move irq_work_queue() to where the counter is incremented and +perf_event::pending_sigtrap is set to make it more obvious that the +irq_work is scheduled once. + +Tested-by: Marco Elver <elver@google.com> +Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Link: https://lore.kernel.org/r/20240312180814.3373778-2-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/events/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -9595,6 +9595,7 @@ static int __perf_event_overflow(struct + if (!event->pending_sigtrap) { + event->pending_sigtrap = pending_id; + local_inc(&event->ctx->nr_pending); ++ irq_work_queue(&event->pending_irq); + } else if (event->attr.exclude_kernel && valid_sample) { + /* + * Should not be able to return to user space without +@@ -9614,7 +9615,6 @@ static int __perf_event_overflow(struct + event->pending_addr = 0; + if (valid_sample && (data->sample_flags & PERF_SAMPLE_ADDR)) + event->pending_addr = data->addr; +- irq_work_queue(&event->pending_irq); + } + + READ_ONCE(event->overflow_handler)(event, data, regs); diff --git a/debian/patches-rt/0005-printk-ringbuffer-Clarify-special-lpos-values.patch b/debian/patches-rt/0001-printk-ringbuffer-Clarify-special-lpos-values.patch index f2b8ffcb0e..e4ea76a5c3 100644 --- a/debian/patches-rt/0005-printk-ringbuffer-Clarify-special-lpos-values.patch +++ b/debian/patches-rt/0001-printk-ringbuffer-Clarify-special-lpos-values.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> -Date: Mon, 23 Oct 2023 11:11:05 +0000 -Subject: [PATCH 05/50] printk: ringbuffer: Clarify special lpos values -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Date: Wed, 7 Feb 2024 14:46:54 +0106 +Subject: [PATCH 01/48] printk: ringbuffer: Clarify special lpos values +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz For empty line records, no data blocks are created. Instead, these valid records are identified by special logical position @@ -19,6 +19,9 @@ as clarification to the values used to represent data-less blocks. Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Petr Mladek <pmladek@suse.com> +Link: https://lore.kernel.org/r/20240207134103.1357162-6-john.ogness@linutronix.de +Signed-off-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- kernel/printk/printk_ringbuffer.c | 20 ++++++++++++++++---- diff --git a/debian/patches-rt/0001-sched-core-Provide-a-method-to-check-if-a-task-is-PI.patch b/debian/patches-rt/0001-sched-core-Provide-a-method-to-check-if-a-task-is-PI.patch index 9cab94caae..366fb021df 100644 --- a/debian/patches-rt/0001-sched-core-Provide-a-method-to-check-if-a-task-is-PI.patch +++ b/debian/patches-rt/0001-sched-core-Provide-a-method-to-check-if-a-task-is-PI.patch @@ -2,7 +2,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri, 4 Aug 2023 13:30:37 +0200 Subject: [PATCH 1/3] sched/core: Provide a method to check if a task is PI-boosted. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Provide a method to check if a task inherited the priority from another task. This happens if a task owns a lock which is requested by a task @@ -20,7 +20,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1910,6 +1910,7 @@ static inline int dl_task_check_affinity +@@ -1791,6 +1791,7 @@ static inline int dl_task_check_affinity } #endif @@ -30,7 +30,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> extern int task_prio(const struct task_struct *p); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -8865,6 +8865,21 @@ static inline void preempt_dynamic_init( +@@ -8890,6 +8890,21 @@ static inline void preempt_dynamic_init( #endif /* #ifdef CONFIG_PREEMPT_DYNAMIC */ diff --git a/debian/patches-rt/0001-serial-amba-pl011-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0001-serial-amba-pl011-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..9acb1fcaa1 --- /dev/null +++ b/debian/patches-rt/0001-serial-amba-pl011-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,92 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:14 +0100 +Subject: [PATCH 01/18] serial: amba-pl011: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Cc: Russell King <linux@armlinux.org.uk> +Link: https://lore.kernel.org/r/20240301215246.891055-2-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/amba-pl011.c | 24 ++++++++---------------- + 1 file changed, 8 insertions(+), 16 deletions(-) + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -348,10 +348,7 @@ static int pl011_fifo_to_tty(struct uart + flag = TTY_FRAME; + } + +- uart_port_unlock(&uap->port); +- sysrq = uart_handle_sysrq_char(&uap->port, ch & 255); +- uart_port_lock(&uap->port); +- ++ sysrq = uart_prepare_sysrq_char(&uap->port, ch & 255); + if (!sysrq) + uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); + } +@@ -1017,7 +1014,7 @@ static void pl011_dma_rx_callback(void * + ret = pl011_dma_rx_trigger_dma(uap); + + pl011_dma_rx_chars(uap, pending, lastbuf, false); +- uart_port_unlock_irq(&uap->port); ++ uart_unlock_and_check_sysrq(&uap->port); + /* + * Do this check after we picked the DMA chars so we don't + * get some IRQ immediately from RX. +@@ -1540,11 +1537,10 @@ static void check_apply_cts_event_workar + static irqreturn_t pl011_int(int irq, void *dev_id) + { + struct uart_amba_port *uap = dev_id; +- unsigned long flags; + unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; + int handled = 0; + +- uart_port_lock_irqsave(&uap->port, &flags); ++ uart_port_lock(&uap->port); + status = pl011_read(uap, REG_RIS) & uap->im; + if (status) { + do { +@@ -1573,7 +1569,7 @@ static irqreturn_t pl011_int(int irq, vo + handled = 1; + } + +- uart_port_unlock_irqrestore(&uap->port, flags); ++ uart_unlock_and_check_sysrq(&uap->port); + + return IRQ_RETVAL(handled); + } +@@ -2322,13 +2318,10 @@ pl011_console_write(struct console *co, + + clk_enable(uap->clk); + +- local_irq_save(flags); +- if (uap->port.sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(&uap->port); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(&uap->port, &flags); + else +- uart_port_lock(&uap->port); ++ uart_port_lock_irqsave(&uap->port, &flags); + + /* + * First save the CR then disable the interrupts +@@ -2354,8 +2347,7 @@ pl011_console_write(struct console *co, + pl011_write(old_cr, uap, REG_CR); + + if (locked) +- uart_port_unlock(&uap->port); +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(&uap->port, flags); + + clk_disable(uap->clk); + } diff --git a/debian/patches-rt/0002-ARM-vfp-Use-vfp_lock-in-vfp_sync_hwstate.patch b/debian/patches-rt/0002-ARM-vfp-Use-vfp_lock-in-vfp_sync_hwstate.patch index c9c30ad81c..8cff78066f 100644 --- a/debian/patches-rt/0002-ARM-vfp-Use-vfp_lock-in-vfp_sync_hwstate.patch +++ b/debian/patches-rt/0002-ARM-vfp-Use-vfp_lock-in-vfp_sync_hwstate.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri, 19 May 2023 16:57:30 +0200 Subject: [PATCH 2/4] ARM: vfp: Use vfp_lock() in vfp_sync_hwstate(). -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz vfp_sync_hwstate() uses preempt_disable() followed by local_bh_disable() to ensure that it won't get interrupted while checking the VFP state. diff --git a/debian/patches-rt/0002-net-Allow-to-use-SMP-threads-for-backlog-NAPI.patch b/debian/patches-rt/0002-net-Allow-to-use-SMP-threads-for-backlog-NAPI.patch new file mode 100644 index 0000000000..acdfbddf5a --- /dev/null +++ b/debian/patches-rt/0002-net-Allow-to-use-SMP-threads-for-backlog-NAPI.patch @@ -0,0 +1,330 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Sat, 9 Mar 2024 10:05:10 +0100 +Subject: [PATCH 2/4] net: Allow to use SMP threads for backlog NAPI. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Backlog NAPI is a per-CPU NAPI struct only (with no device behind it) +used by drivers which don't do NAPI them self, RPS and parts of the +stack which need to avoid recursive deadlocks while processing a packet. + +The non-NAPI driver use the CPU local backlog NAPI. If RPS is enabled +then a flow for the skb is computed and based on the flow the skb can be +enqueued on a remote CPU. Scheduling/ raising the softirq (for backlog's +NAPI) on the remote CPU isn't trivial because the softirq is only +scheduled on the local CPU and performed after the hardirq is done. +In order to schedule a softirq on the remote CPU, an IPI is sent to the +remote CPU which schedules the backlog-NAPI on the then local CPU. + +On PREEMPT_RT interrupts are force-threaded. The soft interrupts are +raised within the interrupt thread and processed after the interrupt +handler completed still within the context of the interrupt thread. The +softirq is handled in the context where it originated. + +With force-threaded interrupts enabled, ksoftirqd is woken up if a +softirq is raised from hardirq context. This is the case if it is raised +from an IPI. Additionally there is a warning on PREEMPT_RT if the +softirq is raised from the idle thread. +This was done for two reasons: +- With threaded interrupts the processing should happen in thread + context (where it originated) and ksoftirqd is the only thread for + this context if raised from hardirq. Using the currently running task + instead would "punish" a random task. +- Once ksoftirqd is active it consumes all further softirqs until it + stops running. This changed recently and is no longer the case. + +Instead of keeping the backlog NAPI in ksoftirqd (in force-threaded/ +PREEMPT_RT setups) I am proposing NAPI-threads for backlog. +The "proper" setup with threaded-NAPI is not doable because the threads +are not pinned to an individual CPU and can be modified by the user. +Additionally a dummy network device would have to be assigned. Also +CPU-hotplug has to be considered if additional CPUs show up. +All this can be probably done/ solved but the smpboot-threads already +provide this infrastructure. + +Sending UDP packets over loopback expects that the packet is processed +within the call. Delaying it by handing it over to the thread hurts +performance. It is not beneficial to the outcome if the context switch +happens immediately after enqueue or after a while to process a few +packets in a batch. +There is no need to always use the thread if the backlog NAPI is +requested on the local CPU. This restores the loopback throuput. The +performance drops mostly to the same value after enabling RPS on the +loopback comparing the IPI and the tread result. + +Create NAPI-threads for backlog if request during boot. The thread runs +the inner loop from napi_threaded_poll(), the wait part is different. It +checks for NAPI_STATE_SCHED (the backlog NAPI can not be disabled). + +The NAPI threads for backlog are optional, it has to be enabled via the boot +argument "thread_backlog_napi". It is mandatory for PREEMPT_RT to avoid the +wakeup of ksoftirqd from the IPI. + +Acked-by: Jakub Kicinski <kuba@kernel.org> +Link: https://lore.kernel.org/r/20240309090824.2956805-3-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + net/core/dev.c | 152 +++++++++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 115 insertions(+), 37 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -78,6 +78,7 @@ + #include <linux/slab.h> + #include <linux/sched.h> + #include <linux/sched/mm.h> ++#include <linux/smpboot.h> + #include <linux/mutex.h> + #include <linux/rwsem.h> + #include <linux/string.h> +@@ -216,6 +217,31 @@ static inline struct hlist_head *dev_ind + return &net->dev_index_head[ifindex & (NETDEV_HASHENTRIES - 1)]; + } + ++#ifndef CONFIG_PREEMPT_RT ++ ++static DEFINE_STATIC_KEY_FALSE(use_backlog_threads_key); ++ ++static int __init setup_backlog_napi_threads(char *arg) ++{ ++ static_branch_enable(&use_backlog_threads_key); ++ return 0; ++} ++early_param("thread_backlog_napi", setup_backlog_napi_threads); ++ ++static bool use_backlog_threads(void) ++{ ++ return static_branch_unlikely(&use_backlog_threads_key); ++} ++ ++#else ++ ++static bool use_backlog_threads(void) ++{ ++ return true; ++} ++ ++#endif ++ + static inline void rps_lock_irqsave(struct softnet_data *sd, + unsigned long *flags) + { +@@ -4420,6 +4446,7 @@ EXPORT_SYMBOL(__dev_direct_xmit); + /************************************************************************* + * Receiver routines + *************************************************************************/ ++static DEFINE_PER_CPU(struct task_struct *, backlog_napi); + + int netdev_max_backlog __read_mostly = 1000; + EXPORT_SYMBOL(netdev_max_backlog); +@@ -4452,12 +4479,16 @@ static inline void ____napi_schedule(str + */ + thread = READ_ONCE(napi->thread); + if (thread) { ++ if (use_backlog_threads() && thread == raw_cpu_read(backlog_napi)) ++ goto use_local_napi; ++ + set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); + wake_up_process(thread); + return; + } + } + ++use_local_napi: + list_add_tail(&napi->poll_list, &sd->poll_list); + WRITE_ONCE(napi->list_owner, smp_processor_id()); + /* If not called from net_rx_action() +@@ -4703,6 +4734,11 @@ static void napi_schedule_rps(struct sof + + #ifdef CONFIG_RPS + if (sd != mysd) { ++ if (use_backlog_threads()) { ++ __napi_schedule_irqoff(&sd->backlog); ++ return; ++ } ++ + sd->rps_ipi_next = mysd->rps_ipi_list; + mysd->rps_ipi_list = sd; + +@@ -5926,7 +5962,7 @@ static void net_rps_action_and_irq_enabl + #ifdef CONFIG_RPS + struct softnet_data *remsd = sd->rps_ipi_list; + +- if (remsd) { ++ if (!use_backlog_threads() && remsd) { + sd->rps_ipi_list = NULL; + + local_irq_enable(); +@@ -5941,7 +5977,7 @@ static void net_rps_action_and_irq_enabl + static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) + { + #ifdef CONFIG_RPS +- return sd->rps_ipi_list != NULL; ++ return !use_backlog_threads() && sd->rps_ipi_list; + #else + return false; + #endif +@@ -5985,7 +6021,7 @@ static int process_backlog(struct napi_s + * We can use a plain write instead of clear_bit(), + * and we dont need an smp_mb() memory barrier. + */ +- napi->state = 0; ++ napi->state &= NAPIF_STATE_THREADED; + again = false; + } else { + skb_queue_splice_tail_init(&sd->input_pkt_queue, +@@ -6691,43 +6727,48 @@ static void skb_defer_free_flush(struct + } + } + +-static int napi_threaded_poll(void *data) ++static void napi_threaded_poll_loop(struct napi_struct *napi) + { +- struct napi_struct *napi = data; + struct softnet_data *sd; +- void *have; ++ unsigned long last_qs = jiffies; + +- while (!napi_thread_wait(napi)) { +- unsigned long last_qs = jiffies; ++ for (;;) { ++ bool repoll = false; ++ void *have; + +- for (;;) { +- bool repoll = false; ++ local_bh_disable(); ++ sd = this_cpu_ptr(&softnet_data); ++ sd->in_napi_threaded_poll = true; + +- local_bh_disable(); +- sd = this_cpu_ptr(&softnet_data); +- sd->in_napi_threaded_poll = true; +- +- have = netpoll_poll_lock(napi); +- __napi_poll(napi, &repoll); +- netpoll_poll_unlock(have); +- +- sd->in_napi_threaded_poll = false; +- barrier(); +- +- if (sd_has_rps_ipi_waiting(sd)) { +- local_irq_disable(); +- net_rps_action_and_irq_enable(sd); +- } +- skb_defer_free_flush(sd); +- local_bh_enable(); ++ have = netpoll_poll_lock(napi); ++ __napi_poll(napi, &repoll); ++ netpoll_poll_unlock(have); ++ ++ sd->in_napi_threaded_poll = false; ++ barrier(); ++ ++ if (sd_has_rps_ipi_waiting(sd)) { ++ local_irq_disable(); ++ net_rps_action_and_irq_enable(sd); ++ } ++ skb_defer_free_flush(sd); ++ local_bh_enable(); + +- if (!repoll) +- break; ++ if (!repoll) ++ break; + +- rcu_softirq_qs_periodic(last_qs); +- cond_resched(); +- } ++ rcu_softirq_qs_periodic(last_qs); ++ cond_resched(); + } ++} ++ ++static int napi_threaded_poll(void *data) ++{ ++ struct napi_struct *napi = data; ++ ++ while (!napi_thread_wait(napi)) ++ napi_threaded_poll_loop(napi); ++ + return 0; + } + +@@ -11326,7 +11367,7 @@ static int dev_cpu_dead(unsigned int old + + list_del_init(&napi->poll_list); + if (napi->poll == process_backlog) +- napi->state = 0; ++ napi->state &= NAPIF_STATE_THREADED; + else + ____napi_schedule(sd, napi); + } +@@ -11334,12 +11375,14 @@ static int dev_cpu_dead(unsigned int old + raise_softirq_irqoff(NET_TX_SOFTIRQ); + local_irq_enable(); + ++ if (!use_backlog_threads()) { + #ifdef CONFIG_RPS +- remsd = oldsd->rps_ipi_list; +- oldsd->rps_ipi_list = NULL; ++ remsd = oldsd->rps_ipi_list; ++ oldsd->rps_ipi_list = NULL; + #endif +- /* send out pending IPI's on offline CPU */ +- net_rps_send_ipi(remsd); ++ /* send out pending IPI's on offline CPU */ ++ net_rps_send_ipi(remsd); ++ } + + /* Process offline CPU's input_pkt_queue */ + while ((skb = __skb_dequeue(&oldsd->process_queue))) { +@@ -11659,6 +11702,38 @@ static void __init net_dev_struct_check( + * + */ + ++static int backlog_napi_should_run(unsigned int cpu) ++{ ++ struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); ++ struct napi_struct *napi = &sd->backlog; ++ ++ return test_bit(NAPI_STATE_SCHED_THREADED, &napi->state); ++} ++ ++static void run_backlog_napi(unsigned int cpu) ++{ ++ struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); ++ ++ napi_threaded_poll_loop(&sd->backlog); ++} ++ ++static void backlog_napi_setup(unsigned int cpu) ++{ ++ struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); ++ struct napi_struct *napi = &sd->backlog; ++ ++ napi->thread = this_cpu_read(backlog_napi); ++ set_bit(NAPI_STATE_THREADED, &napi->state); ++} ++ ++static struct smp_hotplug_thread backlog_threads = { ++ .store = &backlog_napi, ++ .thread_should_run = backlog_napi_should_run, ++ .thread_fn = run_backlog_napi, ++ .thread_comm = "backlog_napi/%u", ++ .setup = backlog_napi_setup, ++}; ++ + /* + * This is called single threaded during boot, so no need + * to take the rtnl semaphore. +@@ -11711,7 +11786,10 @@ static int __init net_dev_init(void) + init_gro_hash(&sd->backlog); + sd->backlog.poll = process_backlog; + sd->backlog.weight = weight_p; ++ INIT_LIST_HEAD(&sd->backlog.poll_list); + } ++ if (use_backlog_threads()) ++ smpboot_register_percpu_thread(&backlog_threads); + + dev_boot_phase = 0; + diff --git a/debian/patches-rt/0002-perf-Enqueue-SIGTRAP-always-via-task_work.patch b/debian/patches-rt/0002-perf-Enqueue-SIGTRAP-always-via-task_work.patch new file mode 100644 index 0000000000..e6e684ad51 --- /dev/null +++ b/debian/patches-rt/0002-perf-Enqueue-SIGTRAP-always-via-task_work.patch @@ -0,0 +1,160 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Tue, 12 Mar 2024 19:01:50 +0100 +Subject: [PATCH 2/4] perf: Enqueue SIGTRAP always via task_work. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +A signal is delivered by raising irq_work() which works from any context +including NMI. irq_work() can be delayed if the architecture does not +provide an interrupt vector. In order not to lose a signal, the signal +is injected via task_work during event_sched_out(). + +Instead going via irq_work, the signal could be added directly via +task_work. The signal is sent to current and can be enqueued on its +return path to userland instead of triggering irq_work. A dummy IRQ is +required in the NMI case to ensure the task_work is handled before +returning to user land. For this irq_work is used. An alternative would +be just raising an interrupt like arch_send_call_function_single_ipi(). + +During testing with `remove_on_exec' it become visible that the event +can be enqueued via NMI during execve(). The task_work must not be kept +because free_event() will complain later. Also the new task will not +have a sighandler installed. + +Queue signal via task_work. Remove perf_event::pending_sigtrap and +and use perf_event::pending_work instead. Raise irq_work in the NMI case +for a dummy interrupt. Remove the task_work if the event is freed. + +Tested-by: Marco Elver <elver@google.com> +Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Link: https://lore.kernel.org/r/20240312180814.3373778-3-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/perf_event.h | 3 -- + kernel/events/core.c | 57 +++++++++++++++++++++++++-------------------- + 2 files changed, 33 insertions(+), 27 deletions(-) + +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -781,7 +781,6 @@ struct perf_event { + unsigned int pending_wakeup; + unsigned int pending_kill; + unsigned int pending_disable; +- unsigned int pending_sigtrap; + unsigned long pending_addr; /* SIGTRAP */ + struct irq_work pending_irq; + struct callback_head pending_task; +@@ -959,7 +958,7 @@ struct perf_event_context { + struct rcu_head rcu_head; + + /* +- * Sum (event->pending_sigtrap + event->pending_work) ++ * Sum (event->pending_work + event->pending_work) + * + * The SIGTRAP is targeted at ctx->task, as such it won't do changing + * that until the signal is delivered. +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -2283,21 +2283,6 @@ event_sched_out(struct perf_event *event + state = PERF_EVENT_STATE_OFF; + } + +- if (event->pending_sigtrap) { +- bool dec = true; +- +- event->pending_sigtrap = 0; +- if (state != PERF_EVENT_STATE_OFF && +- !event->pending_work) { +- event->pending_work = 1; +- dec = false; +- WARN_ON_ONCE(!atomic_long_inc_not_zero(&event->refcount)); +- task_work_add(current, &event->pending_task, TWA_RESUME); +- } +- if (dec) +- local_dec(&event->ctx->nr_pending); +- } +- + perf_event_set_state(event, state); + + if (!is_software_event(event)) +@@ -6741,11 +6726,6 @@ static void __perf_pending_irq(struct pe + * Yay, we hit home and are in the context of the event. + */ + if (cpu == smp_processor_id()) { +- if (event->pending_sigtrap) { +- event->pending_sigtrap = 0; +- perf_sigtrap(event); +- local_dec(&event->ctx->nr_pending); +- } + if (event->pending_disable) { + event->pending_disable = 0; + perf_event_disable_local(event); +@@ -9592,14 +9572,23 @@ static int __perf_event_overflow(struct + + if (regs) + pending_id = hash32_ptr((void *)instruction_pointer(regs)) ?: 1; +- if (!event->pending_sigtrap) { +- event->pending_sigtrap = pending_id; ++ if (!event->pending_work) { ++ event->pending_work = pending_id; + local_inc(&event->ctx->nr_pending); +- irq_work_queue(&event->pending_irq); ++ WARN_ON_ONCE(!atomic_long_inc_not_zero(&event->refcount)); ++ task_work_add(current, &event->pending_task, TWA_RESUME); ++ /* ++ * The NMI path returns directly to userland. The ++ * irq_work is raised as a dummy interrupt to ensure ++ * regular return path to user is taken and task_work ++ * is processed. ++ */ ++ if (in_nmi()) ++ irq_work_queue(&event->pending_irq); + } else if (event->attr.exclude_kernel && valid_sample) { + /* + * Should not be able to return to user space without +- * consuming pending_sigtrap; with exceptions: ++ * consuming pending_work; with exceptions: + * + * 1. Where !exclude_kernel, events can overflow again + * in the kernel without returning to user space. +@@ -9609,7 +9598,7 @@ static int __perf_event_overflow(struct + * To approximate progress (with false negatives), + * check 32-bit hash of the current IP. + */ +- WARN_ON_ONCE(event->pending_sigtrap != pending_id); ++ WARN_ON_ONCE(event->pending_work != pending_id); + } + + event->pending_addr = 0; +@@ -13049,6 +13038,13 @@ static void sync_child_event(struct perf + &parent_event->child_total_time_running); + } + ++static bool task_work_cb_match(struct callback_head *cb, void *data) ++{ ++ struct perf_event *event = container_of(cb, struct perf_event, pending_task); ++ ++ return event == data; ++} ++ + static void + perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx) + { +@@ -13088,6 +13084,17 @@ perf_event_exit_event(struct perf_event + * Kick perf_poll() for is_event_hup(); + */ + perf_event_wakeup(parent_event); ++ /* ++ * Cancel pending task_work and update counters if it has not ++ * yet been delivered to userland. free_event() expects the ++ * reference counter at 1 and keeping the event around until the ++ * task return to userland will be a unexpected. ++ */ ++ if (event->pending_work && ++ task_work_cancel_match(current, task_work_cb_match, event)) { ++ put_event(event); ++ local_dec(&event->ctx->nr_pending); ++ } + free_event(event); + put_event(parent_event); + return; diff --git a/debian/patches-rt/0002-serial-ar933x-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0002-serial-ar933x-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..f8f97abf10 --- /dev/null +++ b/debian/patches-rt/0002-serial-ar933x-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,68 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:15 +0100 +Subject: [PATCH 02/18] serial: ar933x: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Link: https://lore.kernel.org/r/20240301215246.891055-3-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/ar933x_uart.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/tty/serial/ar933x_uart.c ++++ b/drivers/tty/serial/ar933x_uart.c +@@ -378,7 +378,7 @@ static void ar933x_uart_rx_chars(struct + up->port.icount.rx++; + ch = rdata & AR933X_UART_DATA_TX_RX_MASK; + +- if (uart_handle_sysrq_char(&up->port, ch)) ++ if (uart_prepare_sysrq_char(&up->port, ch)) + continue; + + if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) +@@ -468,7 +468,7 @@ static irqreturn_t ar933x_uart_interrupt + ar933x_uart_tx_chars(up); + } + +- uart_port_unlock(&up->port); ++ uart_unlock_and_check_sysrq(&up->port); + + return IRQ_HANDLED; + } +@@ -627,14 +627,10 @@ static void ar933x_uart_console_write(st + unsigned int int_en; + int locked = 1; + +- local_irq_save(flags); +- +- if (up->port.sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(&up->port); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(&up->port, &flags); + else +- uart_port_lock(&up->port); ++ uart_port_lock_irqsave(&up->port, &flags); + + /* + * First save the IER then disable the interrupts +@@ -654,9 +650,7 @@ static void ar933x_uart_console_write(st + ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS); + + if (locked) +- uart_port_unlock(&up->port); +- +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(&up->port, flags); + } + + static int ar933x_uart_console_setup(struct console *co, char *options) diff --git a/debian/patches-rt/0002-softirq-Add-function-to-preempt-serving-softirqs.patch b/debian/patches-rt/0002-softirq-Add-function-to-preempt-serving-softirqs.patch index 642feb6394..24f73e8d86 100644 --- a/debian/patches-rt/0002-softirq-Add-function-to-preempt-serving-softirqs.patch +++ b/debian/patches-rt/0002-softirq-Add-function-to-preempt-serving-softirqs.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri, 4 Aug 2023 13:30:38 +0200 Subject: [PATCH 2/3] softirq: Add function to preempt serving softirqs. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Add a functionality for the softirq handler to preempt its current work if needed. The softirq core has no particular state. It reads and resets diff --git a/debian/patches-rt/0003-ARM-vfp-Use-vfp_lock-in-vfp_support_entry.patch b/debian/patches-rt/0003-ARM-vfp-Use-vfp_lock-in-vfp_support_entry.patch index 45fd3aca6a..2e2ea53f2a 100644 --- a/debian/patches-rt/0003-ARM-vfp-Use-vfp_lock-in-vfp_support_entry.patch +++ b/debian/patches-rt/0003-ARM-vfp-Use-vfp_lock-in-vfp_support_entry.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed, 28 Jun 2023 09:36:10 +0200 Subject: [PATCH 3/4] ARM: vfp: Use vfp_lock() in vfp_support_entry(). -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz vfp_entry() is invoked from exception handler and is fully preemptible. It uses local_bh_disable() to remain uninterrupted while checking the diff --git a/debian/patches-rt/0003-drm-i915-Use-preempt_disable-enable_rt-where-recomme.patch b/debian/patches-rt/0003-drm-i915-Use-preempt_disable-enable_rt-where-recomme.patch index 4e9d58c0b9..86275329f1 100644 --- a/debian/patches-rt/0003-drm-i915-Use-preempt_disable-enable_rt-where-recomme.patch +++ b/debian/patches-rt/0003-drm-i915-Use-preempt_disable-enable_rt-where-recomme.patch @@ -2,7 +2,7 @@ From: Mike Galbraith <umgwanakikbuti@gmail.com> Date: Sat, 27 Feb 2016 08:09:11 +0100 Subject: [PATCH 03/10] drm/i915: Use preempt_disable/enable_rt() where recommended -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Mario Kleiner suggest in commit ad3543ede630f ("drm/intel: Push get_scanout_position() timestamping into kms driver.") @@ -29,14 +29,45 @@ Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - drivers/gpu/drm/i915/display/intel_vblank.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) + drivers/gpu/drm/i915/display/intel_vblank.c | 38 ++++++++++++++++++++-------- + 1 file changed, 28 insertions(+), 10 deletions(-) --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c -@@ -308,7 +308,8 @@ static bool i915_get_crtc_scanoutpos(str +@@ -275,6 +275,26 @@ int intel_crtc_scanline_to_hw(struct int + * all register accesses to the same cacheline to be serialized, + * otherwise they may hang. + */ ++static void intel_vblank_section_enter_irqsave(struct drm_i915_private *i915, unsigned long *flags) ++ __acquires(i915->uncore.lock) ++{ ++#ifdef I915 ++ spin_lock_irqsave(&i915->uncore.lock, *flags); ++#else ++ *flags = 0; ++#endif ++} ++ ++static void intel_vblank_section_exit_irqrestore(struct drm_i915_private *i915, unsigned long flags) ++ __releases(i915->uncore.lock) ++{ ++#ifdef I915 ++ spin_unlock_irqrestore(&i915->uncore.lock, flags); ++#else ++ if (flags) ++ return; ++#endif ++} + static void intel_vblank_section_enter(struct drm_i915_private *i915) + __acquires(i915->uncore.lock) + { +@@ -332,10 +352,10 @@ static bool i915_get_crtc_scanoutpos(str + * timing critical raw register reads, potentially with + * preemption disabled, so the following code must not block. */ - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); +- local_irq_save(irqflags); +- intel_vblank_section_enter(dev_priv); ++ intel_vblank_section_enter_irqsave(dev_priv, &irqflags); - /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ + if (IS_ENABLED(CONFIG_PREEMPT_RT)) @@ -44,7 +75,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Get optional system timestamp before query. */ if (stime) -@@ -372,7 +373,8 @@ static bool i915_get_crtc_scanoutpos(str +@@ -399,10 +419,10 @@ static bool i915_get_crtc_scanoutpos(str if (etime) *etime = ktime_get(); @@ -52,5 +83,25 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + if (IS_ENABLED(CONFIG_PREEMPT_RT)) + preempt_enable(); - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); +- intel_vblank_section_exit(dev_priv); +- local_irq_restore(irqflags); ++ intel_vblank_section_exit_irqrestore(dev_priv, irqflags); + /* + * While in vblank, position will be negative +@@ -440,13 +460,11 @@ int intel_get_crtc_scanline(struct intel + unsigned long irqflags; + int position; + +- local_irq_save(irqflags); +- intel_vblank_section_enter(dev_priv); ++ intel_vblank_section_enter_irqsave(dev_priv, &irqflags); + + position = __intel_get_crtc_scanline(crtc); + +- intel_vblank_section_exit(dev_priv); +- local_irq_restore(irqflags); ++ intel_vblank_section_exit_irqrestore(dev_priv, irqflags); + + return position; + } diff --git a/debian/patches-rt/0003-net-Use-backlog-NAPI-to-clean-up-the-defer_list.patch b/debian/patches-rt/0003-net-Use-backlog-NAPI-to-clean-up-the-defer_list.patch new file mode 100644 index 0000000000..ae46bdf942 --- /dev/null +++ b/debian/patches-rt/0003-net-Use-backlog-NAPI-to-clean-up-the-defer_list.patch @@ -0,0 +1,121 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Sat, 9 Mar 2024 10:05:11 +0100 +Subject: [PATCH 3/4] net: Use backlog-NAPI to clean up the defer_list. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The defer_list is a per-CPU list which is used to free skbs outside of +the socket lock and on the CPU on which they have been allocated. +The list is processed during NAPI callbacks so ideally the list is +cleaned up. +Should the amount of skbs on the list exceed a certain water mark then +the softirq is triggered remotely on the target CPU by invoking a remote +function call. The raise of the softirqs via a remote function call +leads to waking the ksoftirqd on PREEMPT_RT which is undesired. +The backlog-NAPI threads already provide the infrastructure which can be +utilized to perform the cleanup of the defer_list. + +The NAPI state is updated with the input_pkt_queue.lock acquired. It +order not to break the state, it is needed to also wake the backlog-NAPI +thread with the lock held. This requires to acquire the use the lock in +rps_lock_irq*() if the backlog-NAPI threads are used even with RPS +disabled. + +Move the logic of remotely starting softirqs to clean up the defer_list +into kick_defer_list_purge(). Make sure a lock is held in +rps_lock_irq*() if backlog-NAPI threads are used. Schedule backlog-NAPI +for defer_list cleanup if backlog-NAPI is available. + +Acked-by: Jakub Kicinski <kuba@kernel.org> +Link: https://lore.kernel.org/r/20240309090824.2956805-4-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/netdevice.h | 1 + + net/core/dev.c | 25 +++++++++++++++++++++---- + net/core/skbuff.c | 4 ++-- + 3 files changed, 24 insertions(+), 6 deletions(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -3365,6 +3365,7 @@ static inline void dev_xmit_recursion_de + __this_cpu_dec(softnet_data.xmit.recursion); + } + ++void kick_defer_list_purge(struct softnet_data *sd, unsigned int cpu); + void __netif_schedule(struct Qdisc *q); + void netif_schedule_queue(struct netdev_queue *txq); + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -245,7 +245,7 @@ static bool use_backlog_threads(void) + static inline void rps_lock_irqsave(struct softnet_data *sd, + unsigned long *flags) + { +- if (IS_ENABLED(CONFIG_RPS)) ++ if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_lock_irqsave(&sd->input_pkt_queue.lock, *flags); + else if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_irq_save(*flags); +@@ -253,7 +253,7 @@ static inline void rps_lock_irqsave(stru + + static inline void rps_lock_irq_disable(struct softnet_data *sd) + { +- if (IS_ENABLED(CONFIG_RPS)) ++ if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_lock_irq(&sd->input_pkt_queue.lock); + else if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_irq_disable(); +@@ -262,7 +262,7 @@ static inline void rps_lock_irq_disable( + static inline void rps_unlock_irq_restore(struct softnet_data *sd, + unsigned long *flags) + { +- if (IS_ENABLED(CONFIG_RPS)) ++ if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_unlock_irqrestore(&sd->input_pkt_queue.lock, *flags); + else if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_irq_restore(*flags); +@@ -270,7 +270,7 @@ static inline void rps_unlock_irq_restor + + static inline void rps_unlock_irq_enable(struct softnet_data *sd) + { +- if (IS_ENABLED(CONFIG_RPS)) ++ if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_unlock_irq(&sd->input_pkt_queue.lock); + else if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_irq_enable(); +@@ -4753,6 +4753,23 @@ static void napi_schedule_rps(struct sof + __napi_schedule_irqoff(&mysd->backlog); + } + ++void kick_defer_list_purge(struct softnet_data *sd, unsigned int cpu) ++{ ++ unsigned long flags; ++ ++ if (use_backlog_threads()) { ++ rps_lock_irqsave(sd, &flags); ++ ++ if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state)) ++ __napi_schedule_irqoff(&sd->backlog); ++ ++ rps_unlock_irq_restore(sd, &flags); ++ ++ } else if (!cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) { ++ smp_call_function_single_async(cpu, &sd->defer_csd); ++ } ++} ++ + #ifdef CONFIG_NET_FLOW_LIMIT + int netdev_flow_limit_table_len __read_mostly = (1 << 12); + #endif +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -6929,8 +6929,8 @@ nodefer: __kfree_skb(skb); + /* Make sure to trigger NET_RX_SOFTIRQ on the remote CPU + * if we are unlucky enough (this seems very unlikely). + */ +- if (unlikely(kick) && !cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) +- smp_call_function_single_async(cpu, &sd->defer_csd); ++ if (unlikely(kick)) ++ kick_defer_list_purge(sd, cpu); + } + + static void skb_splice_csum_page(struct sk_buff *skb, struct page *page, diff --git a/debian/patches-rt/0003-perf-Remove-perf_swevent_get_recursion_context-from-.patch b/debian/patches-rt/0003-perf-Remove-perf_swevent_get_recursion_context-from-.patch new file mode 100644 index 0000000000..150b5530d2 --- /dev/null +++ b/debian/patches-rt/0003-perf-Remove-perf_swevent_get_recursion_context-from-.patch @@ -0,0 +1,55 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Tue, 12 Mar 2024 19:01:51 +0100 +Subject: [PATCH 3/4] perf: Remove perf_swevent_get_recursion_context() from + perf_pending_task(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +perf_swevent_get_recursion_context() is supposed to avoid recursion. +This requires to remain on the same CPU in order to decrement/ increment +the same counter. This is done by using preempt_disable(). Having +preemption disabled while sending a signal leads to locking problems on +PREEMPT_RT because sighand, a spinlock_t, becomes a sleeping lock. + +This callback runs in task context and currently delivers only a signal +to "itself". Any kind of recusrion protection in this context is not +required. + +Remove recursion protection in perf_pending_task(). + +Tested-by: Marco Elver <elver@google.com> +Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Link: https://lore.kernel.org/r/20240312180814.3373778-4-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/events/core.c | 12 ------------ + 1 file changed, 12 deletions(-) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -6785,14 +6785,6 @@ static void perf_pending_irq(struct irq_ + static void perf_pending_task(struct callback_head *head) + { + struct perf_event *event = container_of(head, struct perf_event, pending_task); +- int rctx; +- +- /* +- * If we 'fail' here, that's OK, it means recursion is already disabled +- * and we won't recurse 'further'. +- */ +- preempt_disable_notrace(); +- rctx = perf_swevent_get_recursion_context(); + + if (event->pending_work) { + event->pending_work = 0; +@@ -6800,10 +6792,6 @@ static void perf_pending_task(struct cal + local_dec(&event->ctx->nr_pending); + } + +- if (rctx >= 0) +- perf_swevent_put_recursion_context(rctx); +- preempt_enable_notrace(); +- + put_event(event); + } + diff --git a/debian/patches-rt/0013-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch b/debian/patches-rt/0003-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch index 94aab97fe8..d7575e9a50 100644 --- a/debian/patches-rt/0013-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch +++ b/debian/patches-rt/0003-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> -Date: Fri, 20 Oct 2023 09:37:05 +0000 -Subject: [PATCH 13/50] printk: Avoid non-panic CPUs writing to ringbuffer -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Date: Wed, 7 Feb 2024 14:47:01 +0106 +Subject: [PATCH 03/48] printk: Avoid non-panic CPUs writing to ringbuffer +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Commit 13fb0f74d702 ("printk: Avoid livelock with heavy printk during panic") introduced a mechanism to silence non-panic CPUs @@ -11,10 +11,18 @@ intended to avoid losing panic messages. However, if non-panic CPUs are writing to the ringbuffer, then reacting to dropped messages is too late. +Another motivation is that non-finalized messages already might +be skipped in panic(). In other words, random messages from +non-panic CPUs might already get lost. It is better to ignore +all to avoid confusion. + To avoid losing panic CPU messages, silence non-panic CPUs immediately on panic. Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Petr Mladek <pmladek@suse.com> +Link: https://lore.kernel.org/r/20240207134103.1357162-13-john.ogness@linutronix.de +Signed-off-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- kernel/printk/printk.c | 26 ++++++-------------------- diff --git a/debian/patches-rt/0003-serial-bcm63xx-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0003-serial-bcm63xx-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..580b336885 --- /dev/null +++ b/debian/patches-rt/0003-serial-bcm63xx-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,78 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:16 +0100 +Subject: [PATCH 03/18] serial: bcm63xx: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Link: https://lore.kernel.org/r/20240301215246.891055-4-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/bcm63xx_uart.c | 24 ++++++++---------------- + 1 file changed, 8 insertions(+), 16 deletions(-) + +--- a/drivers/tty/serial/bcm63xx_uart.c ++++ b/drivers/tty/serial/bcm63xx_uart.c +@@ -285,10 +285,9 @@ static void bcm_uart_do_rx(struct uart_p + flag = TTY_PARITY; + } + +- if (uart_handle_sysrq_char(port, c)) ++ if (uart_prepare_sysrq_char(port, c)) + continue; + +- + if ((cstat & port->ignore_status_mask) == 0) + tty_insert_flip_char(tty_port, c, flag); + +@@ -353,7 +352,7 @@ static irqreturn_t bcm_uart_interrupt(in + estat & UART_EXTINP_DCD_MASK); + } + +- uart_port_unlock(port); ++ uart_unlock_and_check_sysrq(port); + return IRQ_HANDLED; + } + +@@ -703,20 +702,14 @@ static void bcm_console_write(struct con + { + struct uart_port *port; + unsigned long flags; +- int locked; ++ int locked = 1; + + port = &ports[co->index]; + +- local_irq_save(flags); +- if (port->sysrq) { +- /* bcm_uart_interrupt() already took the lock */ +- locked = 0; +- } else if (oops_in_progress) { +- locked = uart_port_trylock(port); +- } else { +- uart_port_lock(port); +- locked = 1; +- } ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(port, &flags); ++ else ++ uart_port_lock_irqsave(port, &flags); + + /* call helper to deal with \r\n */ + uart_console_write(port, s, count, bcm_console_putchar); +@@ -725,8 +718,7 @@ static void bcm_console_write(struct con + wait_for_xmitr(port); + + if (locked) +- uart_port_unlock(port); +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(port, flags); + } + + /* diff --git a/debian/patches-rt/0003-time-Allow-to-preempt-after-a-callback.patch b/debian/patches-rt/0003-time-Allow-to-preempt-after-a-callback.patch index ac1a234ddf..486b98521f 100644 --- a/debian/patches-rt/0003-time-Allow-to-preempt-after-a-callback.patch +++ b/debian/patches-rt/0003-time-Allow-to-preempt-after-a-callback.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri, 4 Aug 2023 13:30:39 +0200 Subject: [PATCH 3/3] time: Allow to preempt after a callback. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The TIMER_SOFTIRQ handler invokes timer callbacks of the expired timers. Before each invocation the timer_base::lock is dropped. The only lock diff --git a/debian/patches-rt/0004-ARM-vfp-Move-sending-signals-outside-of-vfp_lock-ed-.patch b/debian/patches-rt/0004-ARM-vfp-Move-sending-signals-outside-of-vfp_lock-ed-.patch index 8c9259a872..b5f618d1c5 100644 --- a/debian/patches-rt/0004-ARM-vfp-Move-sending-signals-outside-of-vfp_lock-ed-.patch +++ b/debian/patches-rt/0004-ARM-vfp-Move-sending-signals-outside-of-vfp_lock-ed-.patch @@ -2,7 +2,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed, 28 Jun 2023 09:39:33 +0200 Subject: [PATCH 4/4] ARM: vfp: Move sending signals outside of vfp_lock()ed section. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz VFP_bounce() is invoked from within vfp_support_entry() and may send a signal. Sending a signal uses spinlock_t which becomes a sleeping lock diff --git a/debian/patches-rt/0004-drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch b/debian/patches-rt/0004-drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch index a95775d7fe..3d26b9d6cc 100644 --- a/debian/patches-rt/0004-drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch +++ b/debian/patches-rt/0004-drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch @@ -2,7 +2,7 @@ From: Mike Galbraith <umgwanakikbuti@gmail.com> Date: Sat, 27 Feb 2016 09:01:42 +0100 Subject: [PATCH 04/10] drm/i915: Don't disable interrupts on PREEMPT_RT during atomic updates -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Commit 8d7849db3eab7 ("drm/i915: Make sprite updates atomic") @@ -37,7 +37,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c -@@ -573,7 +573,8 @@ void intel_pipe_update_start(struct inte +@@ -580,7 +580,8 @@ void intel_pipe_update_start(struct inte */ intel_psr_wait_for_idle_locked(new_crtc_state); @@ -47,7 +47,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> crtc->debug.min_vbl = min; crtc->debug.max_vbl = max; -@@ -598,11 +599,13 @@ void intel_pipe_update_start(struct inte +@@ -605,11 +606,13 @@ void intel_pipe_update_start(struct inte break; } @@ -63,7 +63,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } finish_wait(wq, &wait); -@@ -635,7 +638,8 @@ void intel_pipe_update_start(struct inte +@@ -642,7 +645,8 @@ void intel_pipe_update_start(struct inte return; irq_disable: @@ -73,7 +73,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE) -@@ -737,7 +741,8 @@ void intel_pipe_update_end(struct intel_ +@@ -744,7 +748,8 @@ void intel_pipe_update_end(struct intel_ */ intel_vrr_send_push(new_crtc_state); diff --git a/debian/patches-rt/0004-net-Rename-rps_lock-to-backlog_lock.patch b/debian/patches-rt/0004-net-Rename-rps_lock-to-backlog_lock.patch new file mode 100644 index 0000000000..70de5b94e2 --- /dev/null +++ b/debian/patches-rt/0004-net-Rename-rps_lock-to-backlog_lock.patch @@ -0,0 +1,164 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Sat, 9 Mar 2024 10:05:12 +0100 +Subject: [PATCH 4/4] net: Rename rps_lock to backlog_lock. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The rps_lock.*() functions use the inner lock of a sk_buff_head for +locking. This lock is used if RPS is enabled, otherwise the list is +accessed lockless and disabling interrupts is enough for the +synchronisation because it is only accessed CPU local. Not only the list +is protected but also the NAPI state protected. +With the addition of backlog threads, the lock is also needed because of +the cross CPU access even without RPS. The clean up of the defer_list +list is also done via backlog threads (if enabled). + +It has been suggested to rename the locking function since it is no +longer just RPS. + +Rename the rps_lock*() functions to backlog_lock*(). + +Suggested-by: Jakub Kicinski <kuba@kernel.org> +Acked-by: Jakub Kicinski <kuba@kernel.org> +Link: https://lore.kernel.org/r/20240309090824.2956805-5-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + net/core/dev.c | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -242,8 +242,8 @@ static bool use_backlog_threads(void) + + #endif + +-static inline void rps_lock_irqsave(struct softnet_data *sd, +- unsigned long *flags) ++static inline void backlog_lock_irq_save(struct softnet_data *sd, ++ unsigned long *flags) + { + if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_lock_irqsave(&sd->input_pkt_queue.lock, *flags); +@@ -251,7 +251,7 @@ static inline void rps_lock_irqsave(stru + local_irq_save(*flags); + } + +-static inline void rps_lock_irq_disable(struct softnet_data *sd) ++static inline void backlog_lock_irq_disable(struct softnet_data *sd) + { + if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_lock_irq(&sd->input_pkt_queue.lock); +@@ -259,8 +259,8 @@ static inline void rps_lock_irq_disable( + local_irq_disable(); + } + +-static inline void rps_unlock_irq_restore(struct softnet_data *sd, +- unsigned long *flags) ++static inline void backlog_unlock_irq_restore(struct softnet_data *sd, ++ unsigned long *flags) + { + if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_unlock_irqrestore(&sd->input_pkt_queue.lock, *flags); +@@ -268,7 +268,7 @@ static inline void rps_unlock_irq_restor + local_irq_restore(*flags); + } + +-static inline void rps_unlock_irq_enable(struct softnet_data *sd) ++static inline void backlog_unlock_irq_enable(struct softnet_data *sd) + { + if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_unlock_irq(&sd->input_pkt_queue.lock); +@@ -4758,12 +4758,12 @@ void kick_defer_list_purge(struct softne + unsigned long flags; + + if (use_backlog_threads()) { +- rps_lock_irqsave(sd, &flags); ++ backlog_lock_irq_save(sd, &flags); + + if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state)) + __napi_schedule_irqoff(&sd->backlog); + +- rps_unlock_irq_restore(sd, &flags); ++ backlog_unlock_irq_restore(sd, &flags); + + } else if (!cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) { + smp_call_function_single_async(cpu, &sd->defer_csd); +@@ -4825,7 +4825,7 @@ static int enqueue_to_backlog(struct sk_ + reason = SKB_DROP_REASON_NOT_SPECIFIED; + sd = &per_cpu(softnet_data, cpu); + +- rps_lock_irqsave(sd, &flags); ++ backlog_lock_irq_save(sd, &flags); + if (!netif_running(skb->dev)) + goto drop; + qlen = skb_queue_len(&sd->input_pkt_queue); +@@ -4834,7 +4834,7 @@ static int enqueue_to_backlog(struct sk_ + enqueue: + __skb_queue_tail(&sd->input_pkt_queue, skb); + input_queue_tail_incr_save(sd, qtail); +- rps_unlock_irq_restore(sd, &flags); ++ backlog_unlock_irq_restore(sd, &flags); + return NET_RX_SUCCESS; + } + +@@ -4849,7 +4849,7 @@ static int enqueue_to_backlog(struct sk_ + + drop: + sd->dropped++; +- rps_unlock_irq_restore(sd, &flags); ++ backlog_unlock_irq_restore(sd, &flags); + + dev_core_stats_rx_dropped_inc(skb->dev); + kfree_skb_reason(skb, reason); +@@ -5880,7 +5880,7 @@ static void flush_backlog(struct work_st + local_bh_disable(); + sd = this_cpu_ptr(&softnet_data); + +- rps_lock_irq_disable(sd); ++ backlog_lock_irq_disable(sd); + skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { + if (skb->dev->reg_state == NETREG_UNREGISTERING) { + __skb_unlink(skb, &sd->input_pkt_queue); +@@ -5888,7 +5888,7 @@ static void flush_backlog(struct work_st + input_queue_head_incr(sd); + } + } +- rps_unlock_irq_enable(sd); ++ backlog_unlock_irq_enable(sd); + + skb_queue_walk_safe(&sd->process_queue, skb, tmp) { + if (skb->dev->reg_state == NETREG_UNREGISTERING) { +@@ -5906,14 +5906,14 @@ static bool flush_required(int cpu) + struct softnet_data *sd = &per_cpu(softnet_data, cpu); + bool do_flush; + +- rps_lock_irq_disable(sd); ++ backlog_lock_irq_disable(sd); + + /* as insertion into process_queue happens with the rps lock held, + * process_queue access may race only with dequeue + */ + do_flush = !skb_queue_empty(&sd->input_pkt_queue) || + !skb_queue_empty_lockless(&sd->process_queue); +- rps_unlock_irq_enable(sd); ++ backlog_unlock_irq_enable(sd); + + return do_flush; + #endif +@@ -6028,7 +6028,7 @@ static int process_backlog(struct napi_s + + } + +- rps_lock_irq_disable(sd); ++ backlog_lock_irq_disable(sd); + if (skb_queue_empty(&sd->input_pkt_queue)) { + /* + * Inline a custom version of __napi_complete(). +@@ -6044,7 +6044,7 @@ static int process_backlog(struct napi_s + skb_queue_splice_tail_init(&sd->input_pkt_queue, + &sd->process_queue); + } +- rps_unlock_irq_enable(sd); ++ backlog_unlock_irq_enable(sd); + } + + return work; diff --git a/debian/patches-rt/0004-perf-Split-__perf_pending_irq-out-of-perf_pending_ir.patch b/debian/patches-rt/0004-perf-Split-__perf_pending_irq-out-of-perf_pending_ir.patch new file mode 100644 index 0000000000..3f1d2a5e00 --- /dev/null +++ b/debian/patches-rt/0004-perf-Split-__perf_pending_irq-out-of-perf_pending_ir.patch @@ -0,0 +1,134 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Tue, 12 Mar 2024 19:01:52 +0100 +Subject: [PATCH 4/4] perf: Split __perf_pending_irq() out of + perf_pending_irq() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +perf_pending_irq() invokes perf_event_wakeup() and __perf_pending_irq(). +The former is in charge of waking any tasks which wait to be woken up +while the latter disables perf-events. + +The irq_work perf_pending_irq(), while this an irq_work, the callback +is invoked in thread context on PREEMPT_RT. This is needed because all +the waking functions (wake_up_all(), kill_fasync()) acquire sleep locks +which must not be used with disabled interrupts. +Disabling events, as done by __perf_pending_irq(), expects a hardirq +context and disabled interrupts. This requirement is not fulfilled on +PREEMPT_RT. + +Split functionality based on perf_event::pending_disable into irq_work +named `pending_disable_irq' and invoke it in hardirq context on +PREEMPT_RT. Rename the split out callback to perf_pending_disable(). + +Tested-by: Marco Elver <elver@google.com> +Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Link: https://lore.kernel.org/r/20240312180814.3373778-5-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/perf_event.h | 1 + + kernel/events/core.c | 31 +++++++++++++++++++++++-------- + 2 files changed, 24 insertions(+), 8 deletions(-) + +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -783,6 +783,7 @@ struct perf_event { + unsigned int pending_disable; + unsigned long pending_addr; /* SIGTRAP */ + struct irq_work pending_irq; ++ struct irq_work pending_disable_irq; + struct callback_head pending_task; + unsigned int pending_work; + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -2449,7 +2449,7 @@ static void __perf_event_disable(struct + * hold the top-level event's child_mutex, so any descendant that + * goes to exit will block in perf_event_exit_event(). + * +- * When called from perf_pending_irq it's OK because event->ctx ++ * When called from perf_pending_disable it's OK because event->ctx + * is the current context on this CPU and preemption is disabled, + * hence we can't get into perf_event_task_sched_out for this context. + */ +@@ -2489,7 +2489,7 @@ EXPORT_SYMBOL_GPL(perf_event_disable); + void perf_event_disable_inatomic(struct perf_event *event) + { + event->pending_disable = 1; +- irq_work_queue(&event->pending_irq); ++ irq_work_queue(&event->pending_disable_irq); + } + + #define MAX_INTERRUPTS (~0ULL) +@@ -5175,6 +5175,7 @@ static void perf_addr_filters_splice(str + static void _free_event(struct perf_event *event) + { + irq_work_sync(&event->pending_irq); ++ irq_work_sync(&event->pending_disable_irq); + + unaccount_event(event); + +@@ -6711,7 +6712,7 @@ static void perf_sigtrap(struct perf_eve + /* + * Deliver the pending work in-event-context or follow the context. + */ +-static void __perf_pending_irq(struct perf_event *event) ++static void __perf_pending_disable(struct perf_event *event) + { + int cpu = READ_ONCE(event->oncpu); + +@@ -6749,11 +6750,26 @@ static void __perf_pending_irq(struct pe + * irq_work_queue(); // FAILS + * + * irq_work_run() +- * perf_pending_irq() ++ * perf_pending_disable() + * + * But the event runs on CPU-B and wants disabling there. + */ +- irq_work_queue_on(&event->pending_irq, cpu); ++ irq_work_queue_on(&event->pending_disable_irq, cpu); ++} ++ ++static void perf_pending_disable(struct irq_work *entry) ++{ ++ struct perf_event *event = container_of(entry, struct perf_event, pending_disable_irq); ++ int rctx; ++ ++ /* ++ * If we 'fail' here, that's OK, it means recursion is already disabled ++ * and we won't recurse 'further'. ++ */ ++ rctx = perf_swevent_get_recursion_context(); ++ __perf_pending_disable(event); ++ if (rctx >= 0) ++ perf_swevent_put_recursion_context(rctx); + } + + static void perf_pending_irq(struct irq_work *entry) +@@ -6776,8 +6792,6 @@ static void perf_pending_irq(struct irq_ + perf_event_wakeup(event); + } + +- __perf_pending_irq(event); +- + if (rctx >= 0) + perf_swevent_put_recursion_context(rctx); + } +@@ -9572,7 +9586,7 @@ static int __perf_event_overflow(struct + * is processed. + */ + if (in_nmi()) +- irq_work_queue(&event->pending_irq); ++ irq_work_queue(&event->pending_disable_irq); + } else if (event->attr.exclude_kernel && valid_sample) { + /* + * Should not be able to return to user space without +@@ -11912,6 +11926,7 @@ perf_event_alloc(struct perf_event_attr + + init_waitqueue_head(&event->waitq); + init_irq_work(&event->pending_irq, perf_pending_irq); ++ event->pending_disable_irq = IRQ_WORK_INIT_HARD(perf_pending_disable); + init_task_work(&event->pending_task, perf_pending_task); + + mutex_init(&event->mmap_mutex); diff --git a/debian/patches-rt/0004-serial-meson-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0004-serial-meson-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..d85b4e4333 --- /dev/null +++ b/debian/patches-rt/0004-serial-meson-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,77 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:17 +0100 +Subject: [PATCH 04/18] serial: meson: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Cc: Kevin Hilman <khilman@baylibre.com> +Cc: Jerome Brunet <jbrunet@baylibre.com> +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-amlogic@lists.infradead.org +Link: https://lore.kernel.org/r/20240301215246.891055-5-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/meson_uart.c | 22 ++++++++-------------- + 1 file changed, 8 insertions(+), 14 deletions(-) + +--- a/drivers/tty/serial/meson_uart.c ++++ b/drivers/tty/serial/meson_uart.c +@@ -220,7 +220,7 @@ static void meson_receive_chars(struct u + continue; + } + +- if (uart_handle_sysrq_char(port, ch)) ++ if (uart_prepare_sysrq_char(port, ch)) + continue; + + if ((status & port->ignore_status_mask) == 0) +@@ -248,7 +248,7 @@ static irqreturn_t meson_uart_interrupt( + meson_uart_start_tx(port); + } + +- uart_port_unlock(port); ++ uart_unlock_and_check_sysrq(port); + + return IRQ_HANDLED; + } +@@ -556,18 +556,13 @@ static void meson_serial_port_write(stru + u_int count) + { + unsigned long flags; +- int locked; ++ int locked = 1; + u32 val, tmp; + +- local_irq_save(flags); +- if (port->sysrq) { +- locked = 0; +- } else if (oops_in_progress) { +- locked = uart_port_trylock(port); +- } else { +- uart_port_lock(port); +- locked = 1; +- } ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(port, &flags); ++ else ++ uart_port_lock_irqsave(port, &flags); + + val = readl(port->membase + AML_UART_CONTROL); + tmp = val & ~(AML_UART_TX_INT_EN | AML_UART_RX_INT_EN); +@@ -577,8 +572,7 @@ static void meson_serial_port_write(stru + writel(val, port->membase + AML_UART_CONTROL); + + if (locked) +- uart_port_unlock(port); +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(port, flags); + } + + static void meson_serial_console_write(struct console *co, const char *s, diff --git a/debian/patches-rt/0005-drm-i915-Don-t-check-for-atomic-context-on-PREEMPT_R.patch b/debian/patches-rt/0005-drm-i915-Don-t-check-for-atomic-context-on-PREEMPT_R.patch index 9a10c838aa..d61e6d3cda 100644 --- a/debian/patches-rt/0005-drm-i915-Don-t-check-for-atomic-context-on-PREEMPT_R.patch +++ b/debian/patches-rt/0005-drm-i915-Don-t-check-for-atomic-context-on-PREEMPT_R.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Mon, 25 Oct 2021 15:05:18 +0200 Subject: [PATCH 05/10] drm/i915: Don't check for atomic context on PREEMPT_RT -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The !in_atomic() check in _wait_for_atomic() triggers on PREEMPT_RT because the uncore::lock is a spinlock_t and does not disable diff --git a/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..75c822db47 --- /dev/null +++ b/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,116 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:18 +0100 +Subject: [PATCH 05/18] serial: msm: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Cc: Bjorn Andersson <andersson@kernel.org> +Cc: Konrad Dybcio <konrad.dybcio@linaro.org> +Cc: linux-arm-msm@vger.kernel.org +Link: https://lore.kernel.org/r/20240301215246.891055-6-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/msm_serial.c | 33 ++++++++++----------------------- + 1 file changed, 10 insertions(+), 23 deletions(-) + +--- a/drivers/tty/serial/msm_serial.c ++++ b/drivers/tty/serial/msm_serial.c +@@ -588,16 +588,14 @@ static void msm_complete_rx_dma(void *ar + if (!(port->read_status_mask & MSM_UART_SR_RX_BREAK)) + flag = TTY_NORMAL; + +- uart_port_unlock_irqrestore(port, flags); +- sysrq = uart_handle_sysrq_char(port, dma->virt[i]); +- uart_port_lock_irqsave(port, &flags); ++ sysrq = uart_prepare_sysrq_char(port, dma->virt[i]); + if (!sysrq) + tty_insert_flip_char(tport, dma->virt[i], flag); + } + + msm_start_rx_dma(msm_port); + done: +- uart_port_unlock_irqrestore(port, flags); ++ uart_unlock_and_check_sysrq_irqrestore(port, flags); + + if (count) + tty_flip_buffer_push(tport); +@@ -763,9 +761,7 @@ static void msm_handle_rx_dm(struct uart + if (!(port->read_status_mask & MSM_UART_SR_RX_BREAK)) + flag = TTY_NORMAL; + +- uart_port_unlock(port); +- sysrq = uart_handle_sysrq_char(port, buf[i]); +- uart_port_lock(port); ++ sysrq = uart_prepare_sysrq_char(port, buf[i]); + if (!sysrq) + tty_insert_flip_char(tport, buf[i], flag); + } +@@ -825,9 +821,7 @@ static void msm_handle_rx(struct uart_po + else if (sr & MSM_UART_SR_PAR_FRAME_ERR) + flag = TTY_FRAME; + +- uart_port_unlock(port); +- sysrq = uart_handle_sysrq_char(port, c); +- uart_port_lock(port); ++ sysrq = uart_prepare_sysrq_char(port, c); + if (!sysrq) + tty_insert_flip_char(tport, c, flag); + } +@@ -948,11 +942,10 @@ static irqreturn_t msm_uart_irq(int irq, + struct uart_port *port = dev_id; + struct msm_port *msm_port = to_msm_port(port); + struct msm_dma *dma = &msm_port->rx_dma; +- unsigned long flags; + unsigned int misr; + u32 val; + +- uart_port_lock_irqsave(port, &flags); ++ uart_port_lock(port); + misr = msm_read(port, MSM_UART_MISR); + msm_write(port, 0, MSM_UART_IMR); /* disable interrupt */ + +@@ -984,7 +977,7 @@ static irqreturn_t msm_uart_irq(int irq, + msm_handle_delta_cts(port); + + msm_write(port, msm_port->imr, MSM_UART_IMR); /* restore interrupt */ +- uart_port_unlock_irqrestore(port, flags); ++ uart_unlock_and_check_sysrq(port); + + return IRQ_HANDLED; + } +@@ -1621,14 +1614,10 @@ static void __msm_console_write(struct u + num_newlines++; + count += num_newlines; + +- local_irq_save(flags); +- +- if (port->sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(port); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(port, &flags); + else +- uart_port_lock(port); ++ uart_port_lock_irqsave(port, &flags); + + if (is_uartdm) + msm_reset_dm_count(port, count); +@@ -1667,9 +1656,7 @@ static void __msm_console_write(struct u + } + + if (locked) +- uart_port_unlock(port); +- +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(port, flags); + } + + static void msm_console_write(struct console *co, const char *s, diff --git a/debian/patches-rt/0006-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch b/debian/patches-rt/0006-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch index 5951d04c0c..39bda39263 100644 --- a/debian/patches-rt/0006-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch +++ b/debian/patches-rt/0006-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Thu, 6 Dec 2018 09:52:20 +0100 Subject: [PATCH 06/10] drm/i915: Disable tracing points on PREEMPT_RT -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Luca Abeni reported this: | BUG: scheduling while atomic: kworker/u8:2/15203/0x00000003 diff --git a/debian/patches-rt/0016-printk-Add-sparse-notation-to-console_srcu-locking.patch b/debian/patches-rt/0006-printk-Add-notation-to-console_srcu-locking.patch index 02fb6c51e1..077a2d2a1a 100644 --- a/debian/patches-rt/0016-printk-Add-sparse-notation-to-console_srcu-locking.patch +++ b/debian/patches-rt/0006-printk-Add-notation-to-console_srcu-locking.patch @@ -1,14 +1,13 @@ From: John Ogness <john.ogness@linutronix.de> Date: Mon, 9 Oct 2023 13:55:19 +0000 -Subject: [PATCH 16/50] printk: Add sparse notation to console_srcu locking -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 06/48] printk: Add notation to console_srcu locking +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz kernel/printk/printk.c:284:5: sparse: sparse: context imbalance in 'console_srcu_read_lock' - wrong count at exit include/linux/srcu.h:301:9: sparse: sparse: context imbalance in 'console_srcu_read_unlock' - unexpected unlock -Reported-by: kernel test robot <lkp@intel.com> Fixes: 6c4afa79147e ("printk: Prepare for SRCU console list protection") Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> diff --git a/debian/patches-rt/0006-printk-For-suppress_panic_printk-check-for-other-CPU.patch b/debian/patches-rt/0006-printk-For-suppress_panic_printk-check-for-other-CPU.patch deleted file mode 100644 index 9906aca51f..0000000000 --- a/debian/patches-rt/0006-printk-For-suppress_panic_printk-check-for-other-CPU.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Fri, 13 Oct 2023 20:13:02 +0000 -Subject: [PATCH 06/50] printk: For @suppress_panic_printk check for other CPU - in panic -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Currently @suppress_panic_printk is checked along with -non-matching @panic_cpu and current CPU. This works -because @suppress_panic_printk is only set when -panic_in_progress() is true. - -Rather than relying on the @suppress_panic_printk semantics, -use the concise helper function other_cpu_in_progress(). The -helper function exists to avoid open coding such tests. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Reviewed-by: Petr Mladek <pmladek@suse.com> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/printk/printk.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -2270,8 +2270,7 @@ asmlinkage int vprintk_emit(int facility - if (unlikely(suppress_printk)) - return 0; - -- if (unlikely(suppress_panic_printk) && -- atomic_read(&panic_cpu) != raw_smp_processor_id()) -+ if (unlikely(suppress_panic_printk) && other_cpu_in_panic()) - return 0; - - if (level == LOGLEVEL_SCHED) { diff --git a/debian/patches-rt/0006-serial-omap-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0006-serial-omap-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..58fe8b1323 --- /dev/null +++ b/debian/patches-rt/0006-serial-omap-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,66 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:19 +0100 +Subject: [PATCH 06/18] serial: omap: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Link: https://lore.kernel.org/r/20240301215246.891055-7-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/omap-serial.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +--- a/drivers/tty/serial/omap-serial.c ++++ b/drivers/tty/serial/omap-serial.c +@@ -508,7 +508,7 @@ static void serial_omap_rdi(struct uart_ + + up->port.icount.rx++; + +- if (uart_handle_sysrq_char(&up->port, ch)) ++ if (uart_prepare_sysrq_char(&up->port, ch)) + return; + + uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, TTY_NORMAL); +@@ -563,7 +563,7 @@ static irqreturn_t serial_omap_irq(int i + } + } while (max_count--); + +- uart_port_unlock(&up->port); ++ uart_unlock_and_check_sysrq(&up->port); + + tty_flip_buffer_push(&up->port.state->port); + +@@ -1212,13 +1212,10 @@ serial_omap_console_write(struct console + unsigned int ier; + int locked = 1; + +- local_irq_save(flags); +- if (up->port.sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(&up->port); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(&up->port, &flags); + else +- uart_port_lock(&up->port); ++ uart_port_lock_irqsave(&up->port, &flags); + + /* + * First save the IER then disable the interrupts +@@ -1245,8 +1242,7 @@ serial_omap_console_write(struct console + check_modem_status(up); + + if (locked) +- uart_port_unlock(&up->port); +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(&up->port, flags); + } + + static int __init diff --git a/debian/patches-rt/0007-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch b/debian/patches-rt/0007-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch index c2b03ffbb3..2d5f24fde2 100644 --- a/debian/patches-rt/0007-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch +++ b/debian/patches-rt/0007-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch @@ -2,7 +2,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed, 19 Dec 2018 10:47:02 +0100 Subject: [PATCH 07/10] drm/i915: skip DRM_I915_LOW_LEVEL_TRACEPOINTS with NOTRACE -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The order of the header files is important. If this header file is included after tracepoint.h was included then the NOTRACE here becomes a diff --git a/debian/patches-rt/0007-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch b/debian/patches-rt/0007-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch new file mode 100644 index 0000000000..cc54d0652e --- /dev/null +++ b/debian/patches-rt/0007-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch @@ -0,0 +1,116 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Wed, 22 Nov 2023 11:23:43 +0000 +Subject: [PATCH 07/48] printk: Properly deal with nbcon consoles on seq init +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +If a non-boot console is registering and boot consoles exist, the +consoles are flushed before being unregistered. This allows the +non-boot console to continue where the boot console left off. + +If for whatever reason flushing fails, the lowest seq found from +any of the enabled boot consoles is used. Until now con->seq was +checked. However, if it is an nbcon boot console, the function +nbcon_seq_read() must be used to read seq because con->seq is +not updated for nbcon consoles. + +Check if it is an nbcon boot console and if so call +nbcon_seq_read() to read seq. + +Also setup the nbcon sequence number and reset the legacy +sequence number from register_console() (rather than in +nbcon_init() and nbcon_seq_force()). This removes all legacy +sequence handling from nbcon.c so the code is easier to follow +and maintain. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/printk/nbcon.c | 7 +------ + kernel/printk/printk.c | 29 ++++++++++++++++++++++++----- + 2 files changed, 25 insertions(+), 11 deletions(-) + +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -172,9 +172,6 @@ void nbcon_seq_force(struct console *con + u64 valid_seq = max_t(u64, seq, prb_first_valid_seq(prb)); + + atomic_long_set(&ACCESS_PRIVATE(con, nbcon_seq), __u64seq_to_ulseq(valid_seq)); +- +- /* Clear con->seq since nbcon consoles use con->nbcon_seq instead. */ +- con->seq = 0; + } + + /** +@@ -964,8 +961,6 @@ bool nbcon_alloc(struct console *con) + * + * nbcon_alloc() *must* be called and succeed before this function + * is called. +- * +- * This function expects that the legacy @con->seq has been set. + */ + void nbcon_init(struct console *con) + { +@@ -974,7 +969,7 @@ void nbcon_init(struct console *con) + /* nbcon_alloc() must have been called and successful! */ + BUG_ON(!con->pbufs); + +- nbcon_seq_force(con, con->seq); ++ nbcon_seq_force(con, 0); + nbcon_state_set(con, &state); + } + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -3353,6 +3353,7 @@ static void try_enable_default_console(s + newcon->flags |= CON_CONSDEV; + } + ++/* Set @newcon->seq to the first record this console should print. */ + static void console_init_seq(struct console *newcon, bool bootcon_registered) + { + struct console *con; +@@ -3401,11 +3402,20 @@ static void console_init_seq(struct cons + + newcon->seq = prb_next_seq(prb); + for_each_console(con) { +- if ((con->flags & CON_BOOT) && +- (con->flags & CON_ENABLED) && +- con->seq < newcon->seq) { +- newcon->seq = con->seq; ++ u64 seq; ++ ++ if (!((con->flags & CON_BOOT) && ++ (con->flags & CON_ENABLED))) { ++ continue; + } ++ ++ if (con->flags & CON_NBCON) ++ seq = nbcon_seq_read(con); ++ else ++ seq = con->seq; ++ ++ if (seq < newcon->seq) ++ newcon->seq = seq; + } + } + +@@ -3522,9 +3532,18 @@ void register_console(struct console *ne + newcon->dropped = 0; + console_init_seq(newcon, bootcon_registered); + +- if (newcon->flags & CON_NBCON) ++ if (newcon->flags & CON_NBCON) { + nbcon_init(newcon); + ++ /* ++ * nbcon consoles have their own sequence counter. The legacy ++ * sequence counter is reset so that it is clear it is not ++ * being used. ++ */ ++ nbcon_seq_force(newcon, newcon->seq); ++ newcon->seq = 0; ++ } ++ + /* + * Put this console in the list - keep the + * preferred driver at the head of the list. diff --git a/debian/patches-rt/0007-serial-pxa-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0007-serial-pxa-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..ae76e25872 --- /dev/null +++ b/debian/patches-rt/0007-serial-pxa-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,68 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:20 +0100 +Subject: [PATCH 07/18] serial: pxa: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Link: https://lore.kernel.org/r/20240301215246.891055-8-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/pxa.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +--- a/drivers/tty/serial/pxa.c ++++ b/drivers/tty/serial/pxa.c +@@ -151,7 +151,7 @@ static inline void receive_chars(struct + flag = TTY_FRAME; + } + +- if (uart_handle_sysrq_char(&up->port, ch)) ++ if (uart_prepare_sysrq_char(&up->port, ch)) + goto ignore_char; + + uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); +@@ -232,7 +232,7 @@ static inline irqreturn_t serial_pxa_irq + check_modem_status(up); + if (lsr & UART_LSR_THRE) + transmit_chars(up); +- uart_port_unlock(&up->port); ++ uart_unlock_and_check_sysrq(&up->port); + return IRQ_HANDLED; + } + +@@ -604,13 +604,10 @@ serial_pxa_console_write(struct console + int locked = 1; + + clk_enable(up->clk); +- local_irq_save(flags); +- if (up->port.sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(&up->port); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(&up->port, &flags); + else +- uart_port_lock(&up->port); ++ uart_port_lock_irqsave(&up->port, &flags); + + /* + * First save the IER then disable the interrupts +@@ -628,10 +625,8 @@ serial_pxa_console_write(struct console + serial_out(up, UART_IER, ier); + + if (locked) +- uart_port_unlock(&up->port); +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(&up->port, flags); + clk_disable(up->clk); +- + } + + #ifdef CONFIG_CONSOLE_POLL diff --git a/debian/patches-rt/0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch b/debian/patches-rt/0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch index 5610950db5..c7681ff217 100644 --- a/debian/patches-rt/0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch +++ b/debian/patches-rt/0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed, 8 Sep 2021 17:18:00 +0200 Subject: [PATCH 08/10] drm/i915/gt: Queue and wait for the irq_work item. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Disabling interrupts and invoking the irq_work function directly breaks on PREEMPT_RT. @@ -27,7 +27,7 @@ Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c -@@ -312,10 +312,9 @@ void __intel_breadcrumbs_park(struct int +@@ -317,10 +317,9 @@ void __intel_breadcrumbs_park(struct int /* Kick the work once more to drain the signalers, and disarm the irq */ irq_work_sync(&b->irq_work); while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) { diff --git a/debian/patches-rt/0008-printk-nbcon-Remove-return-value-for-write_atomic.patch b/debian/patches-rt/0008-printk-nbcon-Remove-return-value-for-write_atomic.patch new file mode 100644 index 0000000000..73b0fe77fd --- /dev/null +++ b/debian/patches-rt/0008-printk-nbcon-Remove-return-value-for-write_atomic.patch @@ -0,0 +1,68 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Fri, 20 Oct 2023 09:52:59 +0000 +Subject: [PATCH 08/48] printk: nbcon: Remove return value for write_atomic() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The return value of write_atomic() does not provide any useful +information. On the contrary, it makes things more complicated +for the caller to appropriately deal with the information. + +Change write_atomic() to not have a return value. If the +message did not get printed due to loss of ownership, the +caller will notice this on its own. If ownership was not lost, +it will be assumed that the driver successfully printed the +message and the sequence number for that console will be +incremented. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/console.h | 2 +- + kernel/printk/nbcon.c | 15 +++++++-------- + 2 files changed, 8 insertions(+), 9 deletions(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -327,7 +327,7 @@ struct console { + struct hlist_node node; + + /* nbcon console specific members */ +- bool (*write_atomic)(struct console *con, ++ void (*write_atomic)(struct console *con, + struct nbcon_write_context *wctxt); + atomic_t __private nbcon_state; + atomic_long_t __private nbcon_seq; +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -849,7 +849,6 @@ static bool nbcon_emit_next_record(struc + unsigned long con_dropped; + struct nbcon_state cur; + unsigned long dropped; +- bool done; + + /* + * The printk buffers are filled within an unsafe section. This +@@ -889,16 +888,16 @@ static bool nbcon_emit_next_record(struc + wctxt->unsafe_takeover = cur.unsafe_takeover; + + if (con->write_atomic) { +- done = con->write_atomic(con, wctxt); ++ con->write_atomic(con, wctxt); + } else { +- nbcon_context_release(ctxt); ++ /* ++ * This function should never be called for legacy consoles. ++ * Handle it as if ownership was lost and try to continue. ++ */ + WARN_ON_ONCE(1); +- done = false; +- } +- +- /* If not done, the emit was aborted. */ +- if (!done) ++ nbcon_context_release(ctxt); + return false; ++ } + + /* + * Since any dropped message was successfully output, reset the diff --git a/debian/patches-rt/0008-serial-sunplus-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0008-serial-sunplus-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..fc7a5b7254 --- /dev/null +++ b/debian/patches-rt/0008-serial-sunplus-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,67 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:21 +0100 +Subject: [PATCH 08/18] serial: sunplus: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Cc: Hammer Hsieh <hammerh0314@gmail.com> +Link: https://lore.kernel.org/r/20240301215246.891055-9-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/sunplus-uart.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/tty/serial/sunplus-uart.c ++++ b/drivers/tty/serial/sunplus-uart.c +@@ -260,7 +260,7 @@ static void receive_chars(struct uart_po + if (port->ignore_status_mask & SUP_DUMMY_READ) + goto ignore_char; + +- if (uart_handle_sysrq_char(port, ch)) ++ if (uart_prepare_sysrq_char(port, ch)) + goto ignore_char; + + uart_insert_char(port, lsr, SUP_UART_LSR_OE, ch, flag); +@@ -287,7 +287,7 @@ static irqreturn_t sunplus_uart_irq(int + if (isc & SUP_UART_ISC_TX) + transmit_chars(port); + +- uart_port_unlock(port); ++ uart_unlock_and_check_sysrq(port); + + return IRQ_HANDLED; + } +@@ -512,22 +512,16 @@ static void sunplus_console_write(struct + unsigned long flags; + int locked = 1; + +- local_irq_save(flags); +- +- if (sunplus_console_ports[co->index]->port.sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(&sunplus_console_ports[co->index]->port); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(&sunplus_console_ports[co->index]->port, &flags); + else +- uart_port_lock(&sunplus_console_ports[co->index]->port); ++ uart_port_lock_irqsave(&sunplus_console_ports[co->index]->port, &flags); + + uart_console_write(&sunplus_console_ports[co->index]->port, s, count, + sunplus_uart_console_putchar); + + if (locked) +- uart_port_unlock(&sunplus_console_ports[co->index]->port); +- +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(&sunplus_console_ports[co->index]->port, flags); + } + + static int __init sunplus_console_setup(struct console *co, char *options) diff --git a/debian/patches-rt/0009-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch b/debian/patches-rt/0009-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch index 6aa006db93..b5712afb62 100644 --- a/debian/patches-rt/0009-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch +++ b/debian/patches-rt/0009-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch @@ -2,7 +2,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed, 8 Sep 2021 19:03:41 +0200 Subject: [PATCH 09/10] drm/i915/gt: Use spin_lock_irq() instead of local_irq_disable() + spin_lock() -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz execlists_dequeue() is invoked from a function which uses local_irq_disable() to disable interrupts so the spin_lock() behaves diff --git a/debian/patches-rt/0018-printk-Check-printk_deferred_enter-_exit-usage.patch b/debian/patches-rt/0009-printk-Check-printk_deferred_enter-_exit-usage.patch index 55ecab4cd5..b706ad35e4 100644 --- a/debian/patches-rt/0018-printk-Check-printk_deferred_enter-_exit-usage.patch +++ b/debian/patches-rt/0009-printk-Check-printk_deferred_enter-_exit-usage.patch @@ -1,25 +1,29 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri, 22 Sep 2023 14:58:18 +0000 -Subject: [PATCH 18/50] printk: Check printk_deferred_enter()/_exit() usage -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 09/48] printk: Check printk_deferred_enter()/_exit() usage +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Add validation that printk_deferred_enter()/_exit() are called in non-migration contexts. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - include/linux/printk.h | 7 +++++-- + include/linux/printk.h | 9 +++++---- + kernel/printk/internal.h | 3 +++ kernel/printk/printk_safe.c | 12 ++++++++++++ - 2 files changed, 17 insertions(+), 2 deletions(-) + 3 files changed, 20 insertions(+), 4 deletions(-) --- a/include/linux/printk.h +++ b/include/linux/printk.h -@@ -159,13 +159,16 @@ int _printk(const char *fmt, ...); +@@ -157,15 +157,16 @@ int _printk(const char *fmt, ...); + */ + __printf(1, 2) __cold int _printk_deferred(const char *fmt, ...); - extern void __printk_safe_enter(void); - extern void __printk_safe_exit(void); +-extern void __printk_safe_enter(void); +-extern void __printk_safe_exit(void); +extern void __printk_deferred_enter(void); +extern void __printk_deferred_exit(void); + @@ -35,6 +39,18 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Please don't use printk_ratelimit(), because it shares ratelimiting state +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -53,6 +53,9 @@ int vprintk_store(int facility, int leve + __printf(1, 0) int vprintk_default(const char *fmt, va_list args); + __printf(1, 0) int vprintk_deferred(const char *fmt, va_list args); + ++void __printk_safe_enter(void); ++void __printk_safe_exit(void); ++ + bool printk_percpu_data_ready(void); + + #define printk_safe_enter_irqsave(flags) \ --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -26,6 +26,18 @@ void __printk_safe_exit(void) @@ -44,13 +60,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +void __printk_deferred_enter(void) +{ + cant_migrate(); -+ this_cpu_inc(printk_context); ++ __printk_safe_enter(); +} + +void __printk_deferred_exit(void) +{ + cant_migrate(); -+ this_cpu_dec(printk_context); ++ __printk_safe_exit(); +} + asmlinkage int vprintk(const char *fmt, va_list args) diff --git a/debian/patches-rt/0009-serial-lpc32xx_hs-Use-uart_prepare_sysrq_char-to-han.patch b/debian/patches-rt/0009-serial-lpc32xx_hs-Use-uart_prepare_sysrq_char-to-han.patch new file mode 100644 index 0000000000..e099cf8e60 --- /dev/null +++ b/debian/patches-rt/0009-serial-lpc32xx_hs-Use-uart_prepare_sysrq_char-to-han.patch @@ -0,0 +1,68 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:22 +0100 +Subject: [PATCH 09/18] serial: lpc32xx_hs: Use uart_prepare_sysrq_char() to + handle sysrq. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Handle sysrq requests sysrq once the port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Cc: Vladimir Zapolskiy <vz@mleia.com> +Cc: linux-arm-kernel@lists.infradead.org +Link: https://lore.kernel.org/r/20240301215246.891055-10-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/lpc32xx_hs.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +--- a/drivers/tty/serial/lpc32xx_hs.c ++++ b/drivers/tty/serial/lpc32xx_hs.c +@@ -136,20 +136,16 @@ static void lpc32xx_hsuart_console_write + int locked = 1; + + touch_nmi_watchdog(); +- local_irq_save(flags); +- if (up->port.sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(&up->port); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(&up->port, &flags); + else +- uart_port_lock(&up->port); ++ uart_port_lock_irqsave(&up->port, &flags); + + uart_console_write(&up->port, s, count, lpc32xx_hsuart_console_putchar); + wait_for_xmit_empty(&up->port); + + if (locked) +- uart_port_unlock(&up->port); +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(&up->port, flags); + } + + static int __init lpc32xx_hsuart_console_setup(struct console *co, +@@ -268,7 +264,8 @@ static void __serial_lpc32xx_rx(struct u + tty_insert_flip_char(tport, 0, TTY_FRAME); + } + +- tty_insert_flip_char(tport, (tmp & 0xFF), flag); ++ if (!uart_prepare_sysrq_char(port, tmp & 0xff)) ++ tty_insert_flip_char(tport, (tmp & 0xFF), flag); + + tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); + } +@@ -333,7 +330,7 @@ static irqreturn_t serial_lpc32xx_interr + __serial_lpc32xx_tx(port); + } + +- uart_port_unlock(port); ++ uart_unlock_and_check_sysrq(port); + + return IRQ_HANDLED; + } diff --git a/debian/patches-rt/0010-drm-i915-Drop-the-irqs_disabled-check.patch b/debian/patches-rt/0010-drm-i915-Drop-the-irqs_disabled-check.patch index a76d765926..1cf736b273 100644 --- a/debian/patches-rt/0010-drm-i915-Drop-the-irqs_disabled-check.patch +++ b/debian/patches-rt/0010-drm-i915-Drop-the-irqs_disabled-check.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri, 1 Oct 2021 20:01:03 +0200 Subject: [PATCH 10/10] drm/i915: Drop the irqs_disabled() check -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The !irqs_disabled() check triggers on PREEMPT_RT even with i915_sched_engine::lock acquired. The reason is the lock is transformed diff --git a/debian/patches-rt/0010-printk-nbcon-Add-detailed-doc-for-write_atomic.patch b/debian/patches-rt/0010-printk-nbcon-Add-detailed-doc-for-write_atomic.patch new file mode 100644 index 0000000000..354e027bdb --- /dev/null +++ b/debian/patches-rt/0010-printk-nbcon-Add-detailed-doc-for-write_atomic.patch @@ -0,0 +1,71 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Wed, 7 Feb 2024 18:38:14 +0000 +Subject: [PATCH 10/48] printk: nbcon: Add detailed doc for write_atomic() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The write_atomic() callback has special requirements and is +allowed to use special helper functions. Provide detailed +documentation of the callback so that a developer has a +chance of implementing it correctly. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Petr Mladek <pmladek@suse.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/console.h | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -285,7 +285,7 @@ struct nbcon_write_context { + /** + * struct console - The console descriptor structure + * @name: The name of the console driver +- * @write: Write callback to output messages (Optional) ++ * @write: Legacy write callback to output messages (Optional) + * @read: Read callback for console input (Optional) + * @device: The underlying TTY device driver (Optional) + * @unblank: Callback to unblank the console (Optional) +@@ -302,7 +302,6 @@ struct nbcon_write_context { + * @data: Driver private data + * @node: hlist node for the console list + * +- * @write_atomic: Write callback for atomic context + * @nbcon_state: State for nbcon consoles + * @nbcon_seq: Sequence number of the next record for nbcon to print + * @pbufs: Pointer to nbcon private buffer +@@ -327,8 +326,32 @@ struct console { + struct hlist_node node; + + /* nbcon console specific members */ +- void (*write_atomic)(struct console *con, +- struct nbcon_write_context *wctxt); ++ ++ /** ++ * @write_atomic: ++ * ++ * NBCON callback to write out text in any context. ++ * ++ * This callback is called with the console already acquired. The ++ * callback can use nbcon_can_proceed() at any time to verify that ++ * it is still the owner of the console. In the case that it has ++ * lost ownership, it is no longer allowed to go forward. In this ++ * case it must back out immediately and carefully. The buffer ++ * content is also no longer trusted since it no longer belongs to ++ * the context. ++ * ++ * If the callback needs to perform actions where ownership is not ++ * allowed to be taken over, nbcon_enter_unsafe() and ++ * nbcon_exit_unsafe() can be used to mark such sections. These ++ * functions are also points of possible ownership transfer. If ++ * either function returns false, ownership has been lost. ++ * ++ * This callback can be called from any context (including NMI). ++ * Therefore it must avoid usage of any locking and instead rely ++ * on the console ownership for synchronization. ++ */ ++ void (*write_atomic)(struct console *con, struct nbcon_write_context *wctxt); ++ + atomic_t __private nbcon_state; + atomic_long_t __private nbcon_seq; + struct printk_buffers *pbufs; diff --git a/debian/patches-rt/0010-serial-owl-Use-uart_prepare_sysrq_char-to-handle-sys.patch b/debian/patches-rt/0010-serial-owl-Use-uart_prepare_sysrq_char-to-handle-sys.patch new file mode 100644 index 0000000000..bec90c28e6 --- /dev/null +++ b/debian/patches-rt/0010-serial-owl-Use-uart_prepare_sysrq_char-to-handle-sys.patch @@ -0,0 +1,104 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:23 +0100 +Subject: [PATCH 10/18] serial: owl: Use uart_prepare_sysrq_char() to handle + sysrq. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Handle sysrq requests sysrq once the port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Cc: Andreas Färber <afaerber@suse.de> +Cc: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-actions@lists.infradead.org +Link: https://lore.kernel.org/r/20240301215246.891055-11-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/owl-uart.c | 30 ++++++++++++------------------ + 1 file changed, 12 insertions(+), 18 deletions(-) + +--- a/drivers/tty/serial/owl-uart.c ++++ b/drivers/tty/serial/owl-uart.c +@@ -199,6 +199,7 @@ static void owl_uart_receive_chars(struc + stat = owl_uart_read(port, OWL_UART_STAT); + while (!(stat & OWL_UART_STAT_RFEM)) { + char flag = TTY_NORMAL; ++ bool sysrq; + + if (stat & OWL_UART_STAT_RXER) + port->icount.overrun++; +@@ -217,7 +218,9 @@ static void owl_uart_receive_chars(struc + val = owl_uart_read(port, OWL_UART_RXDAT); + val &= 0xff; + +- if ((stat & port->ignore_status_mask) == 0) ++ sysrq = uart_prepare_sysrq_char(port, val); ++ ++ if (!sysrq && (stat & port->ignore_status_mask) == 0) + tty_insert_flip_char(&port->state->port, val, flag); + + stat = owl_uart_read(port, OWL_UART_STAT); +@@ -229,10 +232,9 @@ static void owl_uart_receive_chars(struc + static irqreturn_t owl_uart_irq(int irq, void *dev_id) + { + struct uart_port *port = dev_id; +- unsigned long flags; + u32 stat; + +- uart_port_lock_irqsave(port, &flags); ++ uart_port_lock(port); + + stat = owl_uart_read(port, OWL_UART_STAT); + +@@ -246,7 +248,7 @@ static irqreturn_t owl_uart_irq(int irq, + stat |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP; + owl_uart_write(port, stat, OWL_UART_STAT); + +- uart_port_unlock_irqrestore(port, flags); ++ uart_unlock_and_check_sysrq(port); + + return IRQ_HANDLED; + } +@@ -508,18 +510,12 @@ static void owl_uart_port_write(struct u + { + u32 old_ctl, val; + unsigned long flags; +- int locked; ++ int locked = 1; + +- local_irq_save(flags); +- +- if (port->sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(port); +- else { +- uart_port_lock(port); +- locked = 1; +- } ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(port, &flags); ++ else ++ uart_port_lock_irqsave(port, &flags); + + old_ctl = owl_uart_read(port, OWL_UART_CTL); + val = old_ctl | OWL_UART_CTL_TRFS_TX; +@@ -541,9 +537,7 @@ static void owl_uart_port_write(struct u + owl_uart_write(port, old_ctl, OWL_UART_CTL); + + if (locked) +- uart_port_unlock(port); +- +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(port, flags); + } + + static void owl_uart_console_write(struct console *co, const char *s, diff --git a/debian/patches-rt/0011-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch b/debian/patches-rt/0011-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch new file mode 100644 index 0000000000..d6239d704b --- /dev/null +++ b/debian/patches-rt/0011-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch @@ -0,0 +1,72 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Mon, 18 Mar 2024 10:11:56 +0000 +Subject: [PATCH 11/48] printk: nbcon: Add callbacks to synchronize with driver +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Console drivers typically must deal with access to the hardware +via user input/output (such as an interactive login shell) and +output of kernel messages via printk() calls. + +Follow-up commits require that the printk subsystem is able to +synchronize with the driver. Require nbcon consoles to implement +two new callbacks (device_lock(), device_unlock()) that will +use whatever synchronization mechanism the driver is using for +itself (for example, the port lock for uart serial consoles). + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/console.h | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -352,6 +352,48 @@ struct console { + */ + void (*write_atomic)(struct console *con, struct nbcon_write_context *wctxt); + ++ /** ++ * @device_lock: ++ * ++ * NBCON callback to begin synchronization with driver code. ++ * ++ * Console drivers typically must deal with access to the hardware ++ * via user input/output (such as an interactive login shell) and ++ * output of kernel messages via printk() calls. This callback is ++ * called by the printk-subsystem whenever it needs to synchronize ++ * with hardware access by the driver. It should be implemented to ++ * use whatever synchronization mechanism the driver is using for ++ * itself (for example, the port lock for uart serial consoles). ++ * ++ * This callback is always called from task context. It may use any ++ * synchronization method required by the driver. BUT this callback ++ * MUST also disable migration. The console driver may be using a ++ * synchronization mechanism that already takes care of this (such as ++ * spinlocks). Otherwise this function must explicitly call ++ * migrate_disable(). ++ * ++ * The flags argument is provided as a convenience to the driver. It ++ * will be passed again to device_unlock(). It can be ignored if the ++ * driver does not need it. ++ */ ++ void (*device_lock)(struct console *con, unsigned long *flags); ++ ++ /** ++ * @device_unlock: ++ * ++ * NBCON callback to finish synchronization with driver code. ++ * ++ * It is the counterpart to device_lock(). ++ * ++ * This callback is always called from task context. It must ++ * appropriately re-enable migration (depending on how device_lock() ++ * disabled migration). ++ * ++ * The flags argument is the value of the same variable that was ++ * passed to device_lock(). ++ */ ++ void (*device_unlock)(struct console *con, unsigned long flags); ++ + atomic_t __private nbcon_state; + atomic_long_t __private nbcon_seq; + struct printk_buffers *pbufs; diff --git a/debian/patches-rt/0011-printk-ringbuffer-Consider-committed-as-finalized-in.patch b/debian/patches-rt/0011-printk-ringbuffer-Consider-committed-as-finalized-in.patch deleted file mode 100644 index 405969873c..0000000000 --- a/debian/patches-rt/0011-printk-ringbuffer-Consider-committed-as-finalized-in.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Mon, 20 Nov 2023 12:46:35 +0100 -Subject: [PATCH 11/50] printk: ringbuffer: Consider committed as finalized in - panic -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -A descriptor in the committed state means the record does not yet -exist for the reader. However, for the panic CPU, committed -records should be handled as finalized records since they contain -message data in a consistent state and may contain additional -hints as to the cause of the panic. - -Add an exception for records in the commit state to not be -considered non-existing when reading from the panic CPU. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/printk/printk_ringbuffer.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - ---- a/kernel/printk/printk_ringbuffer.c -+++ b/kernel/printk/printk_ringbuffer.c -@@ -1857,6 +1857,8 @@ static bool copy_data(struct prb_data_ri - * descriptor. However, it also verifies that the record is finalized and has - * the sequence number @seq. On success, 0 is returned. - * -+ * For the panic CPU, committed descriptors are also considered finalized. -+ * - * Error return values: - * -EINVAL: A finalized record with sequence number @seq does not exist. - * -ENOENT: A finalized record with sequence number @seq exists, but its data -@@ -1875,17 +1877,26 @@ static int desc_read_finalized_seq(struc - - /* - * An unexpected @id (desc_miss) or @seq mismatch means the record -- * does not exist. A descriptor in the reserved or committed state -- * means the record does not yet exist for the reader. -+ * does not exist. A descriptor in the reserved state means the -+ * record does not yet exist for the reader. - */ - if (d_state == desc_miss || - d_state == desc_reserved || -- d_state == desc_committed || - s != seq) { - return -EINVAL; - } - - /* -+ * A descriptor in the committed state means the record does not yet -+ * exist for the reader. However, for the panic CPU, committed -+ * records are also handled as finalized records since they contain -+ * message data in a consistent state and may contain additional -+ * hints as to the cause of the panic. -+ */ -+ if (d_state == desc_committed && !this_cpu_in_panic()) -+ return -EINVAL; -+ -+ /* - * A descriptor in the reusable state may no longer have its data - * available; report it as existing but with lost data. Or the record - * may actually be a record with lost data. diff --git a/debian/patches-rt/0011-serial-rda-Use-uart_prepare_sysrq_char-to-handle-sys.patch b/debian/patches-rt/0011-serial-rda-Use-uart_prepare_sysrq_char-to-handle-sys.patch new file mode 100644 index 0000000000..35d33ed2f9 --- /dev/null +++ b/debian/patches-rt/0011-serial-rda-Use-uart_prepare_sysrq_char-to-handle-sys.patch @@ -0,0 +1,91 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:24 +0100 +Subject: [PATCH 11/18] serial: rda: Use uart_prepare_sysrq_char() to handle + sysrq. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Handle sysrq requests sysrq once the port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Cc: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-unisoc@lists.infradead.org +Link: https://lore.kernel.org/r/20240301215246.891055-12-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/rda-uart.c | 28 ++++++++++------------------ + 1 file changed, 10 insertions(+), 18 deletions(-) + +--- a/drivers/tty/serial/rda-uart.c ++++ b/drivers/tty/serial/rda-uart.c +@@ -394,7 +394,8 @@ static void rda_uart_receive_chars(struc + val &= 0xff; + + port->icount.rx++; +- tty_insert_flip_char(&port->state->port, val, flag); ++ if (!uart_prepare_sysrq_char(port, val)) ++ tty_insert_flip_char(&port->state->port, val, flag); + + status = rda_uart_read(port, RDA_UART_STATUS); + } +@@ -405,10 +406,9 @@ static void rda_uart_receive_chars(struc + static irqreturn_t rda_interrupt(int irq, void *dev_id) + { + struct uart_port *port = dev_id; +- unsigned long flags; + u32 val, irq_mask; + +- uart_port_lock_irqsave(port, &flags); ++ uart_port_lock(port); + + /* Clear IRQ cause */ + val = rda_uart_read(port, RDA_UART_IRQ_CAUSE); +@@ -425,7 +425,7 @@ static irqreturn_t rda_interrupt(int irq + rda_uart_send_chars(port); + } + +- uart_port_unlock_irqrestore(port, flags); ++ uart_unlock_and_check_sysrq(port); + + return IRQ_HANDLED; + } +@@ -590,18 +590,12 @@ static void rda_uart_port_write(struct u + { + u32 old_irq_mask; + unsigned long flags; +- int locked; ++ int locked = 1; + +- local_irq_save(flags); +- +- if (port->sysrq) { +- locked = 0; +- } else if (oops_in_progress) { +- locked = uart_port_trylock(port); +- } else { +- uart_port_lock(port); +- locked = 1; +- } ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(port, &flags); ++ else ++ uart_port_lock_irqsave(port, &flags); + + old_irq_mask = rda_uart_read(port, RDA_UART_IRQ_MASK); + rda_uart_write(port, 0, RDA_UART_IRQ_MASK); +@@ -615,9 +609,7 @@ static void rda_uart_port_write(struct u + rda_uart_write(port, old_irq_mask, RDA_UART_IRQ_MASK); + + if (locked) +- uart_port_unlock(port); +- +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(port, flags); + } + + static void rda_uart_console_write(struct console *co, const char *s, diff --git a/debian/patches-rt/0012-printk-nbcon-Use-driver-synchronization-while-regist.patch b/debian/patches-rt/0012-printk-nbcon-Use-driver-synchronization-while-regist.patch new file mode 100644 index 0000000000..71afdf6e29 --- /dev/null +++ b/debian/patches-rt/0012-printk-nbcon-Use-driver-synchronization-while-regist.patch @@ -0,0 +1,68 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Fri, 15 Mar 2024 15:38:22 +0000 +Subject: [PATCH 12/48] printk: nbcon: Use driver synchronization while + registering +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Depending on if an nbcon console is registered, a driver may +handle its internal locking differently. If a driver is holding +its internal lock while the nbcon console is registered, there +may be a risk that two different contexts access the hardware +simultaneously without synchronization. (For example, if the +printk subsystem invokes atomic printing while another driver +context acquired the internal lock without considering the +atomic console.) + +Use the driver synchronization while a registering nbcon console +transitions to being registered. This guarantees that if the +driver acquires its internal lock when the nbcon console was not +registered, it will remain unregistered until that context +releases the lock. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/printk/printk.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -3453,6 +3453,7 @@ void register_console(struct console *ne + struct console *con; + bool bootcon_registered = false; + bool realcon_registered = false; ++ unsigned long flags; + int err; + + console_list_lock(); +@@ -3545,6 +3546,19 @@ void register_console(struct console *ne + } + + /* ++ * If another context is actively using the hardware of this new ++ * console, it will not be aware of the nbcon synchronization. This ++ * is a risk that two contexts could access the hardware ++ * simultaneously if this new console is used for atomic printing ++ * and the other context is still using the hardware. ++ * ++ * Use the driver synchronization to ensure that the hardware is not ++ * in use while this new console transitions to being registered. ++ */ ++ if ((newcon->flags & CON_NBCON) && newcon->write_atomic) ++ newcon->device_lock(newcon, &flags); ++ ++ /* + * Put this console in the list - keep the + * preferred driver at the head of the list. + */ +@@ -3568,6 +3582,10 @@ void register_console(struct console *ne + * register_console() completes. + */ + ++ /* This new console is now registered. */ ++ if ((newcon->flags & CON_NBCON) && newcon->write_atomic) ++ newcon->device_unlock(newcon, flags); ++ + console_sysfs_notify(); + + /* diff --git a/debian/patches-rt/0012-serial-sifive-Use-uart_prepare_sysrq_char-to-handle-.patch b/debian/patches-rt/0012-serial-sifive-Use-uart_prepare_sysrq_char-to-handle-.patch new file mode 100644 index 0000000000..5b82468e40 --- /dev/null +++ b/debian/patches-rt/0012-serial-sifive-Use-uart_prepare_sysrq_char-to-handle-.patch @@ -0,0 +1,71 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:25 +0100 +Subject: [PATCH 12/18] serial: sifive: Use uart_prepare_sysrq_char() to handle + sysrq. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Handle sysrq requests sysrq once the port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Cc: Palmer Dabbelt <palmer@dabbelt.com> +Cc: Paul Walmsley <paul.walmsley@sifive.com> +Cc: linux-riscv@lists.infradead.org +Link: https://lore.kernel.org/r/20240301215246.891055-13-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/sifive.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +--- a/drivers/tty/serial/sifive.c ++++ b/drivers/tty/serial/sifive.c +@@ -412,7 +412,8 @@ static void __ssp_receive_chars(struct s + break; + + ssp->port.icount.rx++; +- uart_insert_char(&ssp->port, 0, 0, ch, TTY_NORMAL); ++ if (!uart_prepare_sysrq_char(&ssp->port, ch)) ++ uart_insert_char(&ssp->port, 0, 0, ch, TTY_NORMAL); + } + + tty_flip_buffer_push(&ssp->port.state->port); +@@ -534,7 +535,7 @@ static irqreturn_t sifive_serial_irq(int + if (ip & SIFIVE_SERIAL_IP_TXWM_MASK) + __ssp_transmit_chars(ssp); + +- uart_port_unlock(&ssp->port); ++ uart_unlock_and_check_sysrq(&ssp->port); + + return IRQ_HANDLED; + } +@@ -791,13 +792,10 @@ static void sifive_serial_console_write( + if (!ssp) + return; + +- local_irq_save(flags); +- if (ssp->port.sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = uart_port_trylock(&ssp->port); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(&ssp->port, &flags); + else +- uart_port_lock(&ssp->port); ++ uart_port_lock_irqsave(&ssp->port, &flags); + + ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS); + __ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp); +@@ -807,8 +805,7 @@ static void sifive_serial_console_write( + __ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp); + + if (locked) +- uart_port_unlock(&ssp->port); +- local_irq_restore(flags); ++ uart_port_unlock_irqrestore(&ssp->port, flags); + } + + static int sifive_serial_console_setup(struct console *co, char *options) diff --git a/debian/patches-rt/0013-serial-core-Provide-low-level-functions-to-lock-port.patch b/debian/patches-rt/0013-serial-core-Provide-low-level-functions-to-lock-port.patch new file mode 100644 index 0000000000..c441b46257 --- /dev/null +++ b/debian/patches-rt/0013-serial-core-Provide-low-level-functions-to-lock-port.patch @@ -0,0 +1,48 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Mon, 11 Dec 2023 09:19:18 +0000 +Subject: [PATCH 13/48] serial: core: Provide low-level functions to lock port +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +It will be necessary at times for the uart nbcon console +drivers to acquire the port lock directly (without the +additional nbcon functionality of the port lock wrappers). +These are special cases such as the implementation of the +device_lock()/device_unlock() callbacks or for internal +port lock wrapper synchronization. + +Provide low-level variants __uart_port_lock_irqsave() and +__uart_port_unlock_irqrestore() for this purpose. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/serial_core.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -588,6 +588,24 @@ struct uart_port { + void *private_data; /* generic platform data pointer */ + }; + ++/* ++ * Only for console->device_lock()/_unlock() callbacks and internal ++ * port lock wrapper synchronization. ++ */ ++static inline void __uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) ++{ ++ spin_lock_irqsave(&up->lock, *flags); ++} ++ ++/* ++ * Only for console->device_lock()/_unlock() callbacks and internal ++ * port lock wrapper synchronization. ++ */ ++static inline void __uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) ++{ ++ spin_unlock_irqrestore(&up->lock, flags); ++} ++ + /** + * uart_port_lock - Lock the UART port + * @up: Pointer to UART port structure diff --git a/debian/patches-rt/0013-serial-pch-Invoke-handle_rx_to-directly.patch b/debian/patches-rt/0013-serial-pch-Invoke-handle_rx_to-directly.patch new file mode 100644 index 0000000000..436fb4e55c --- /dev/null +++ b/debian/patches-rt/0013-serial-pch-Invoke-handle_rx_to-directly.patch @@ -0,0 +1,39 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:26 +0100 +Subject: [PATCH 13/18] serial: pch: Invoke handle_rx_to() directly. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +handle_rx() is only a wrapper around handle_rx_to() without any +additional functionality. + +Invoke handle_rx_to() directly and remove handle_rx(). + +Link: https://lore.kernel.org/r/20240301215246.891055-14-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/pch_uart.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -778,11 +778,6 @@ static int handle_rx_to(struct eg20t_por + return PCH_UART_HANDLED_RX_INT; + } + +-static int handle_rx(struct eg20t_port *priv) +-{ +- return handle_rx_to(priv); +-} +- + static int dma_handle_rx(struct eg20t_port *priv) + { + struct uart_port *port = &priv->port; +@@ -1051,7 +1046,7 @@ static irqreturn_t pch_uart_interrupt(in + PCH_UART_HAL_RX_INT | + PCH_UART_HAL_RX_ERR_INT); + } else { +- ret = handle_rx(priv); ++ ret = handle_rx_to(priv); + } + break; + case PCH_UART_IID_RDR_TO: /* Received Data Ready diff --git a/debian/patches-rt/0014-panic-Flush-kernel-log-buffer-at-the-end.patch b/debian/patches-rt/0014-panic-Flush-kernel-log-buffer-at-the-end.patch deleted file mode 100644 index 09f528156f..0000000000 --- a/debian/patches-rt/0014-panic-Flush-kernel-log-buffer-at-the-end.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Thu, 14 Dec 2023 20:48:23 +0000 -Subject: [PATCH 14/50] panic: Flush kernel log buffer at the end -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -If the kernel crashes in a context where printk() calls always -defer printing (such as in NMI or inside a printk_safe section) -then the final panic messages will be deferred to irq_work. But -if irq_work is not available, the messages will not get printed -unless explicitly flushed. The result is that the final -"end Kernel panic" banner does not get printed. - -Add one final flush after the last printk() call to make sure -the final panic messages make it out as well. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/panic.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/kernel/panic.c -+++ b/kernel/panic.c -@@ -446,6 +446,14 @@ void panic(const char *fmt, ...) - - /* Do not scroll important messages printed above */ - suppress_printk = 1; -+ -+ /* -+ * The final messages may not have been printed if in a context that -+ * defers printing (such as NMI) and irq_work is not available. -+ * Explicitly flush the kernel log buffer one last time. -+ */ -+ console_flush_on_panic(CONSOLE_FLUSH_PENDING); -+ - local_irq_enable(); - for (i = 0; ; i += PANIC_TIMER_STEP) { - touch_softlockup_watchdog(); diff --git a/debian/patches-rt/0014-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch b/debian/patches-rt/0014-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch new file mode 100644 index 0000000000..edf62ea414 --- /dev/null +++ b/debian/patches-rt/0014-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch @@ -0,0 +1,478 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Wed, 13 Sep 2023 08:35:23 +0000 +Subject: [PATCH 14/48] printk: nbcon: Implement processing in port->lock + wrapper +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Currently the port->lock wrappers uart_port_lock(), +uart_port_unlock() (and their variants) only lock/unlock +the spin_lock. + +If the port is an nbcon console, the wrappers must also +acquire/release the console and mark the region as unsafe. This +allows general port->lock synchronization to be synchronized +with the nbcon console ownership. + +Introduce a new struct nbcon_drvdata within struct console that +provides the necessary components for the port lock wrappers to +acquire the nbcon console and track its ownership. + +Also introduce uart_port_set_cons() as a wrapper to set @cons +of a uart_port. The wrapper sets @cons under the port lock in +order to prevent @cons from disappearing while another context +owns the port lock via the port lock wrappers. + +Also cleanup the description of the console_srcu_read_flags() +function. It is used by the port lock wrappers to ensure a +console cannot be fully unregistered while another context +owns the port lock via the port lock wrappers. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/8250/8250_core.c | 6 +- + drivers/tty/serial/amba-pl011.c | 2 + drivers/tty/serial/serial_core.c | 16 ++--- + include/linux/console.h | 57 ++++++++++++++++---- + include/linux/printk.h | 13 ++++ + include/linux/serial_core.h | 98 +++++++++++++++++++++++++++++++++++- + kernel/printk/nbcon.c | 52 +++++++++++++++++++ + 7 files changed, 219 insertions(+), 25 deletions(-) + +--- a/drivers/tty/serial/8250/8250_core.c ++++ b/drivers/tty/serial/8250/8250_core.c +@@ -627,11 +627,11 @@ static int univ8250_console_setup(struct + + port = &serial8250_ports[co->index].port; + /* link port to console */ +- port->cons = co; ++ uart_port_set_cons(port, co); + + retval = serial8250_console_setup(port, options, false); + if (retval != 0) +- port->cons = NULL; ++ uart_port_set_cons(port, NULL); + return retval; + } + +@@ -689,7 +689,7 @@ static int univ8250_console_match(struct + continue; + + co->index = i; +- port->cons = co; ++ uart_port_set_cons(port, co); + return serial8250_console_setup(port, options, true); + } + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -2488,7 +2488,7 @@ static int pl011_console_match(struct co + continue; + + co->index = i; +- port->cons = co; ++ uart_port_set_cons(port, co); + return pl011_console_setup(co, options); + } + +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -3145,8 +3145,15 @@ static int serial_core_add_one_port(stru + state->uart_port = uport; + uport->state = state; + ++ /* ++ * If this port is in use as a console then the spinlock is already ++ * initialised. ++ */ ++ if (!uart_console_registered(uport)) ++ uart_port_spin_lock_init(uport); ++ + state->pm_state = UART_PM_STATE_UNDEFINED; +- uport->cons = drv->cons; ++ uart_port_set_cons(uport, drv->cons); + uport->minor = drv->tty_driver->minor_start + uport->line; + uport->name = kasprintf(GFP_KERNEL, "%s%d", drv->dev_name, + drv->tty_driver->name_base + uport->line); +@@ -3155,13 +3162,6 @@ static int serial_core_add_one_port(stru + goto out; + } + +- /* +- * If this port is in use as a console then the spinlock is already +- * initialised. +- */ +- if (!uart_console_registered(uport)) +- uart_port_spin_lock_init(uport); +- + if (uport->cons && uport->dev) + of_console_check(uport->dev->of_node, uport->cons->name, uport->line); + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -283,6 +283,25 @@ struct nbcon_write_context { + }; + + /** ++ * struct nbcon_drvdata - Data to allow nbcon acquire in non-print context ++ * @ctxt: The core console context ++ * @srcu_cookie: Storage for a console_srcu_lock cookie, if needed ++ * @owner_index: Storage for the owning console index, if needed ++ * @locked: Storage for the locked state, if needed ++ * ++ * All fields (except for @ctxt) are available exclusively to the driver to ++ * use as needed. They are not used by the printk subsystem. ++ */ ++struct nbcon_drvdata { ++ struct nbcon_context __private ctxt; ++ ++ /* reserved for driver use */ ++ int srcu_cookie; ++ short owner_index; ++ bool locked; ++}; ++ ++/** + * struct console - The console descriptor structure + * @name: The name of the console driver + * @write: Legacy write callback to output messages (Optional) +@@ -396,6 +415,21 @@ struct console { + + atomic_t __private nbcon_state; + atomic_long_t __private nbcon_seq; ++ ++ /** ++ * @nbcon_drvdata: ++ * ++ * Data for nbcon ownership tracking to allow acquiring nbcon consoles ++ * in non-printing contexts. ++ * ++ * Drivers may need to acquire nbcon consoles in non-printing ++ * contexts. This is achieved by providing a struct nbcon_drvdata. ++ * Then the driver can call nbcon_driver_acquire() and ++ * nbcon_driver_release(). The struct does not require any special ++ * initialization. ++ */ ++ struct nbcon_drvdata *nbcon_drvdata; ++ + struct printk_buffers *pbufs; + }; + +@@ -425,28 +459,29 @@ extern void console_list_unlock(void) __ + extern struct hlist_head console_list; + + /** +- * console_srcu_read_flags - Locklessly read the console flags ++ * console_srcu_read_flags - Locklessly read flags of a possibly registered ++ * console + * @con: struct console pointer of console to read flags from + * +- * This function provides the necessary READ_ONCE() and data_race() +- * notation for locklessly reading the console flags. The READ_ONCE() +- * in this function matches the WRITE_ONCE() when @flags are modified +- * for registered consoles with console_srcu_write_flags(). ++ * Locklessly reading @con->flags provides a consistent read value because ++ * there is at most one CPU modifying @con->flags and that CPU is using only ++ * read-modify-write operations to do so. + * +- * Only use this function to read console flags when locklessly +- * iterating the console list via srcu. ++ * Requires console_srcu_read_lock to be held, which implies that @con might ++ * be a registered console. If the caller is holding the console_list_lock or ++ * it is certain that the console is not registered, the caller may read ++ * @con->flags directly instead. + * + * Context: Any context. ++ * Return: The current value of the @con->flags field. + */ + static inline short console_srcu_read_flags(const struct console *con) + { + WARN_ON_ONCE(!console_srcu_read_lock_is_held()); + + /* +- * Locklessly reading console->flags provides a consistent +- * read value because there is at most one CPU modifying +- * console->flags and that CPU is using only read-modify-write +- * operations to do so. ++ * The READ_ONCE() matches the WRITE_ONCE() when @flags are modified ++ * for registered consoles with console_srcu_write_flags(). + */ + return data_race(READ_ONCE(con->flags)); + } +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -9,6 +9,8 @@ + #include <linux/ratelimit_types.h> + #include <linux/once_lite.h> + ++struct console; ++ + extern const char linux_banner[]; + extern const char linux_proc_banner[]; + +@@ -193,6 +195,8 @@ void show_regs_print_info(const char *lo + extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; + extern asmlinkage void dump_stack(void) __cold; + void printk_trigger_flush(void); ++extern void nbcon_driver_acquire(struct console *con); ++extern void nbcon_driver_release(struct console *con); + #else + static inline __printf(1, 0) + int vprintk(const char *s, va_list args) +@@ -272,6 +276,15 @@ static inline void dump_stack(void) + static inline void printk_trigger_flush(void) + { + } ++ ++static inline void nbcon_driver_acquire(struct console *con) ++{ ++} ++ ++static inline void nbcon_driver_release(struct console *con) ++{ ++} ++ + #endif + + bool this_cpu_in_panic(void); +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -8,10 +8,13 @@ + #define LINUX_SERIAL_CORE_H + + #include <linux/bitops.h> ++#include <linux/bug.h> + #include <linux/compiler.h> + #include <linux/console.h> + #include <linux/interrupt.h> + #include <linux/circ_buf.h> ++#include <linux/lockdep.h> ++#include <linux/printk.h> + #include <linux/spinlock.h> + #include <linux/sched.h> + #include <linux/tty.h> +@@ -607,12 +610,90 @@ static inline void __uart_port_unlock_ir + } + + /** ++ * uart_port_set_cons - Safely set the @cons field for a uart ++ * @up: The uart port to set ++ * @con: The new console to set to ++ * ++ * This function must be used to set @up->cons. It uses the port lock to ++ * synchronize with the port lock wrappers in order to ensure that the console ++ * cannot change or disappear while another context is holding the port lock. ++ */ ++static inline void uart_port_set_cons(struct uart_port *up, struct console *con) ++{ ++ unsigned long flags; ++ ++ __uart_port_lock_irqsave(up, &flags); ++ up->cons = con; ++ __uart_port_unlock_irqrestore(up, flags); ++} ++ ++/* Only for internal port lock wrapper usage. */ ++static inline void __uart_port_nbcon_acquire(struct uart_port *up) ++{ ++ lockdep_assert_held_once(&up->lock); ++ ++ if (likely(!uart_console(up))) ++ return; ++ ++ if (up->cons->nbcon_drvdata) { ++ /* ++ * If @up->cons is registered, prevent it from fully ++ * unregistering until this context releases the nbcon. ++ */ ++ int cookie = console_srcu_read_lock(); ++ ++ /* Ensure console is registered and is an nbcon console. */ ++ if (!hlist_unhashed_lockless(&up->cons->node) && ++ (console_srcu_read_flags(up->cons) & CON_NBCON)) { ++ WARN_ON_ONCE(up->cons->nbcon_drvdata->locked); ++ ++ nbcon_driver_acquire(up->cons); ++ ++ /* ++ * Record @up->line to be used during release because ++ * @up->cons->index can change while the port and ++ * nbcon are locked. ++ */ ++ up->cons->nbcon_drvdata->owner_index = up->line; ++ up->cons->nbcon_drvdata->srcu_cookie = cookie; ++ up->cons->nbcon_drvdata->locked = true; ++ } else { ++ console_srcu_read_unlock(cookie); ++ } ++ } ++} ++ ++/* Only for internal port lock wrapper usage. */ ++static inline void __uart_port_nbcon_release(struct uart_port *up) ++{ ++ lockdep_assert_held_once(&up->lock); ++ ++ /* ++ * uart_console() cannot be used here because @up->cons->index might ++ * have changed. Check against @up->cons->nbcon_drvdata->owner_index ++ * instead. ++ */ ++ ++ if (unlikely(up->cons && ++ up->cons->nbcon_drvdata && ++ up->cons->nbcon_drvdata->locked && ++ up->cons->nbcon_drvdata->owner_index == up->line)) { ++ WARN_ON_ONCE(!up->cons->nbcon_drvdata->locked); ++ ++ up->cons->nbcon_drvdata->locked = false; ++ nbcon_driver_release(up->cons); ++ console_srcu_read_unlock(up->cons->nbcon_drvdata->srcu_cookie); ++ } ++} ++ ++/** + * uart_port_lock - Lock the UART port + * @up: Pointer to UART port structure + */ + static inline void uart_port_lock(struct uart_port *up) + { + spin_lock(&up->lock); ++ __uart_port_nbcon_acquire(up); + } + + /** +@@ -622,6 +703,7 @@ static inline void uart_port_lock(struct + static inline void uart_port_lock_irq(struct uart_port *up) + { + spin_lock_irq(&up->lock); ++ __uart_port_nbcon_acquire(up); + } + + /** +@@ -632,6 +714,7 @@ static inline void uart_port_lock_irq(st + static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) + { + spin_lock_irqsave(&up->lock, *flags); ++ __uart_port_nbcon_acquire(up); + } + + /** +@@ -642,7 +725,11 @@ static inline void uart_port_lock_irqsav + */ + static inline bool uart_port_trylock(struct uart_port *up) + { +- return spin_trylock(&up->lock); ++ if (!spin_trylock(&up->lock)) ++ return false; ++ ++ __uart_port_nbcon_acquire(up); ++ return true; + } + + /** +@@ -654,7 +741,11 @@ static inline bool uart_port_trylock(str + */ + static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags) + { +- return spin_trylock_irqsave(&up->lock, *flags); ++ if (!spin_trylock_irqsave(&up->lock, *flags)) ++ return false; ++ ++ __uart_port_nbcon_acquire(up); ++ return true; + } + + /** +@@ -663,6 +754,7 @@ static inline bool uart_port_trylock_irq + */ + static inline void uart_port_unlock(struct uart_port *up) + { ++ __uart_port_nbcon_release(up); + spin_unlock(&up->lock); + } + +@@ -672,6 +764,7 @@ static inline void uart_port_unlock(stru + */ + static inline void uart_port_unlock_irq(struct uart_port *up) + { ++ __uart_port_nbcon_release(up); + spin_unlock_irq(&up->lock); + } + +@@ -682,6 +775,7 @@ static inline void uart_port_unlock_irq( + */ + static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) + { ++ __uart_port_nbcon_release(up); + spin_unlock_irqrestore(&up->lock, flags); + } + +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -3,9 +3,12 @@ + // Copyright (C) 2022 Intel, Thomas Gleixner + + #include <linux/kernel.h> ++#include <linux/bug.h> + #include <linux/console.h> + #include <linux/delay.h> ++#include <linux/export.h> + #include <linux/slab.h> ++#include <linux/string.h> + #include "internal.h" + /* + * Printk console printing implementation for consoles which does not depend +@@ -988,3 +991,52 @@ void nbcon_free(struct console *con) + + con->pbufs = NULL; + } ++ ++/** ++ * nbcon_driver_acquire - Acquire nbcon console and enter unsafe section ++ * @con: The nbcon console to acquire ++ * ++ * Context: Any context which could not be migrated to another CPU. ++ * ++ * Console drivers will usually use their own internal synchronization ++ * mechasism to synchronize between console printing and non-printing ++ * activities (such as setting baud rates). However, nbcon console drivers ++ * supporting atomic consoles may also want to mark unsafe sections when ++ * performing non-printing activities. ++ * ++ * This function acquires the nbcon console using priority NBCON_PRIO_NORMAL ++ * and marks it unsafe for handover/takeover. ++ * ++ * Console drivers using this function must have provided @nbcon_drvdata in ++ * their struct console, which is used to track ownership and state ++ * information. ++ */ ++void nbcon_driver_acquire(struct console *con) ++{ ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(con->nbcon_drvdata, ctxt); ++ ++ cant_migrate(); ++ ++ do { ++ do { ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ctxt->console = con; ++ ctxt->prio = NBCON_PRIO_NORMAL; ++ } while (!nbcon_context_try_acquire(ctxt)); ++ ++ } while (!nbcon_context_enter_unsafe(ctxt)); ++} ++EXPORT_SYMBOL_GPL(nbcon_driver_acquire); ++ ++/** ++ * nbcon_driver_release - Exit unsafe section and release the nbcon console ++ * @con: The nbcon console acquired in nbcon_driver_acquire() ++ */ ++void nbcon_driver_release(struct console *con) ++{ ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(con->nbcon_drvdata, ctxt); ++ ++ if (nbcon_context_exit_unsafe(ctxt)) ++ nbcon_context_release(ctxt); ++} ++EXPORT_SYMBOL_GPL(nbcon_driver_release); diff --git a/debian/patches-rt/0014-serial-pch-Make-push_rx-return-void.patch b/debian/patches-rt/0014-serial-pch-Make-push_rx-return-void.patch new file mode 100644 index 0000000000..9ed4ea5abc --- /dev/null +++ b/debian/patches-rt/0014-serial-pch-Make-push_rx-return-void.patch @@ -0,0 +1,56 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:27 +0100 +Subject: [PATCH 14/18] serial: pch: Make push_rx() return void. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +push_rx() returns always 0. + +Make push_rx() return void. + +Link: https://lore.kernel.org/r/20240301215246.891055-15-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/pch_uart.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -599,16 +599,14 @@ static void pch_uart_hal_set_break(struc + iowrite8(lcr, priv->membase + UART_LCR); + } + +-static int push_rx(struct eg20t_port *priv, const unsigned char *buf, +- int size) ++static void push_rx(struct eg20t_port *priv, const unsigned char *buf, ++ int size) + { + struct uart_port *port = &priv->port; + struct tty_port *tport = &port->state->port; + + tty_insert_flip_string(tport, buf, size); + tty_flip_buffer_push(tport); +- +- return 0; + } + + static int dma_push_rx(struct eg20t_port *priv, int size) +@@ -761,7 +759,7 @@ static int handle_rx_to(struct eg20t_por + { + struct pch_uart_buffer *buf; + int rx_size; +- int ret; ++ + if (!priv->start_rx) { + pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT | + PCH_UART_HAL_RX_ERR_INT); +@@ -770,9 +768,7 @@ static int handle_rx_to(struct eg20t_por + buf = &priv->rxbuf; + do { + rx_size = pch_uart_hal_read(priv, buf->buf, buf->size); +- ret = push_rx(priv, buf->buf, rx_size); +- if (ret) +- return 0; ++ push_rx(priv, buf->buf, rx_size); + } while (rx_size == buf->size); + + return PCH_UART_HANDLED_RX_INT; diff --git a/debian/patches-rt/0015-printk-Consider-nbcon-boot-consoles-on-seq-init.patch b/debian/patches-rt/0015-printk-Consider-nbcon-boot-consoles-on-seq-init.patch deleted file mode 100644 index 0f0519c5e3..0000000000 --- a/debian/patches-rt/0015-printk-Consider-nbcon-boot-consoles-on-seq-init.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Wed, 22 Nov 2023 11:23:43 +0000 -Subject: [PATCH 15/50] printk: Consider nbcon boot consoles on seq init -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -If a non-boot console is registering and boot consoles exist, the -consoles are flushed before being unregistered. This allows the -non-boot console to continue where the boot console left off. - -If for whatever reason flushing fails, the lowest seq found from -any of the enabled boot consoles is used. Until now con->seq was -checked. However, if it is an nbcon boot console, the function -nbcon_seq_read() must be used to read seq because con->seq is -always 0. - -Check if it is an nbcon boot console and if so call -nbcon_seq_read() to read seq. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/printk/printk.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -3399,11 +3399,20 @@ static void console_init_seq(struct cons - - newcon->seq = prb_next_seq(prb); - for_each_console(con) { -- if ((con->flags & CON_BOOT) && -- (con->flags & CON_ENABLED) && -- con->seq < newcon->seq) { -- newcon->seq = con->seq; -+ u64 seq; -+ -+ if (!((con->flags & CON_BOOT) && -+ (con->flags & CON_ENABLED))) { -+ continue; - } -+ -+ if (con->flags & CON_NBCON) -+ seq = nbcon_seq_read(con); -+ else -+ seq = con->seq; -+ -+ if (seq < newcon->seq) -+ newcon->seq = seq; - } - } - diff --git a/debian/patches-rt/0015-printk-nbcon-Do-not-rely-on-proxy-headers.patch b/debian/patches-rt/0015-printk-nbcon-Do-not-rely-on-proxy-headers.patch new file mode 100644 index 0000000000..3ea3dd3d77 --- /dev/null +++ b/debian/patches-rt/0015-printk-nbcon-Do-not-rely-on-proxy-headers.patch @@ -0,0 +1,87 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Mon, 19 Feb 2024 17:35:49 +0000 +Subject: [PATCH 15/48] printk: nbcon: Do not rely on proxy headers +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The headers kernel.h, serial_core.h, and console.h allow for the +definitions of many types and functions from other headers. +Rather than relying on these as proxy headers, explicitly +include all headers providing needed definitions. Also sort the +list alphabetically to be able to easily detect duplicates. + +Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/printk/internal.h | 8 ++++++-- + kernel/printk/nbcon.c | 12 +++++++++++- + kernel/printk/printk_ringbuffer.h | 2 ++ + 3 files changed, 19 insertions(+), 3 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -2,11 +2,12 @@ + /* + * internal.h - printk internal definitions + */ +-#include <linux/percpu.h> + #include <linux/console.h> +-#include "printk_ringbuffer.h" ++#include <linux/percpu.h> ++#include <linux/types.h> + + #if defined(CONFIG_PRINTK) && defined(CONFIG_SYSCTL) ++struct ctl_table; + void __init printk_sysctl_init(void); + int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos); +@@ -43,6 +44,9 @@ enum printk_info_flags { + LOG_CONT = 8, /* text is a fragment of a continuation line */ + }; + ++struct printk_ringbuffer; ++struct dev_printk_info; ++ + extern struct printk_ringbuffer *prb; + + __printf(4, 0) +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -2,14 +2,24 @@ + // Copyright (C) 2022 Linutronix GmbH, John Ogness + // Copyright (C) 2022 Intel, Thomas Gleixner + +-#include <linux/kernel.h> ++#include <linux/atomic.h> + #include <linux/bug.h> + #include <linux/console.h> + #include <linux/delay.h> ++#include <linux/errno.h> + #include <linux/export.h> ++#include <linux/init.h> ++#include <linux/irqflags.h> ++#include <linux/minmax.h> ++#include <linux/percpu.h> ++#include <linux/preempt.h> + #include <linux/slab.h> ++#include <linux/smp.h> ++#include <linux/stddef.h> + #include <linux/string.h> ++#include <linux/types.h> + #include "internal.h" ++#include "printk_ringbuffer.h" + /* + * Printk console printing implementation for consoles which does not depend + * on the legacy style console_lock mechanism. +--- a/kernel/printk/printk_ringbuffer.h ++++ b/kernel/printk/printk_ringbuffer.h +@@ -5,6 +5,8 @@ + + #include <linux/atomic.h> + #include <linux/dev_printk.h> ++#include <linux/stddef.h> ++#include <linux/types.h> + + /* + * Meta information about each stored message. diff --git a/debian/patches-rt/0015-serial-pch-Don-t-disable-interrupts-while-acquiring-.patch b/debian/patches-rt/0015-serial-pch-Don-t-disable-interrupts-while-acquiring-.patch new file mode 100644 index 0000000000..aad340f32c --- /dev/null +++ b/debian/patches-rt/0015-serial-pch-Don-t-disable-interrupts-while-acquiring-.patch @@ -0,0 +1,42 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:28 +0100 +Subject: [PATCH 15/18] serial: pch: Don't disable interrupts while acquiring + lock in ISR. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The interrupt service routine is always invoked with disabled +interrupts. + +Remove the _irqsave() from the locking functions in the interrupts +service routine/ pch_uart_interrupt(). + +Link: https://lore.kernel.org/r/20240301215246.891055-16-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/pch_uart.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -1010,11 +1010,10 @@ static irqreturn_t pch_uart_interrupt(in + u8 lsr; + int ret = 0; + unsigned char iid; +- unsigned long flags; + int next = 1; + u8 msr; + +- spin_lock_irqsave(&priv->lock, flags); ++ spin_lock(&priv->lock); + handled = 0; + while (next) { + iid = pch_uart_hal_get_iid(priv); +@@ -1074,7 +1073,7 @@ static irqreturn_t pch_uart_interrupt(in + handled |= (unsigned int)ret; + } + +- spin_unlock_irqrestore(&priv->lock, flags); ++ spin_unlock(&priv->lock); + return IRQ_RETVAL(handled); + } + diff --git a/debian/patches-rt/0016-printk-nbcon-Fix-kerneldoc-for-enums.patch b/debian/patches-rt/0016-printk-nbcon-Fix-kerneldoc-for-enums.patch new file mode 100644 index 0000000000..246deca24d --- /dev/null +++ b/debian/patches-rt/0016-printk-nbcon-Fix-kerneldoc-for-enums.patch @@ -0,0 +1,36 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Fri, 9 Feb 2024 10:46:58 +0000 +Subject: [PATCH 16/48] printk: nbcon: Fix kerneldoc for enums +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Kerneldoc requires enums to be specified as such. Otherwise it is +interpreted as function documentation. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Randy Dunlap <rdunlap@infradead.org> +Reviewed-by: Petr Mladek <pmladek@suse.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/console.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -137,7 +137,7 @@ static inline int con_debug_leave(void) + */ + + /** +- * cons_flags - General console flags ++ * enum cons_flags - General console flags + * @CON_PRINTBUFFER: Used by newly registered consoles to avoid duplicate + * output of messages that were already shown by boot + * consoles or read by userspace via syslog() syscall. +@@ -218,7 +218,7 @@ struct nbcon_state { + static_assert(sizeof(struct nbcon_state) <= sizeof(int)); + + /** +- * nbcon_prio - console owner priority for nbcon consoles ++ * enum nbcon_prio - console owner priority for nbcon consoles + * @NBCON_PRIO_NONE: Unused + * @NBCON_PRIO_NORMAL: Normal (non-emergency) usage + * @NBCON_PRIO_EMERGENCY: Emergency output (WARN/OOPS...) diff --git a/debian/patches-rt/0016-serial-pch-Don-t-initialize-uart_port-s-spin_lock.patch b/debian/patches-rt/0016-serial-pch-Don-t-initialize-uart_port-s-spin_lock.patch new file mode 100644 index 0000000000..4acdbb831f --- /dev/null +++ b/debian/patches-rt/0016-serial-pch-Don-t-initialize-uart_port-s-spin_lock.patch @@ -0,0 +1,28 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:29 +0100 +Subject: [PATCH 16/18] serial: pch: Don't initialize uart_port's spin_lock. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +There is no need to directly initialize the spinlock_t in struct +uart_port. The structure is later passed to uart_add_one_port() which +initialize the complete struct including the lock member. + +Remove spin_lock_init() on uart_port's internal lock. + +Link: https://lore.kernel.org/r/20240301215246.891055-17-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/pch_uart.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -1725,8 +1725,6 @@ static struct eg20t_port *pch_uart_init_ + KBUILD_MODNAME ":" PCH_UART_DRIVER_DEVICE "%d", + priv->port.line); + +- spin_lock_init(&priv->port.lock); +- + pci_set_drvdata(pdev, priv); + priv->trigger_level = 1; + priv->fcr = 0; diff --git a/debian/patches-rt/0021-printk-Make-console_is_usable-available-to-nbcon.patch b/debian/patches-rt/0017-printk-Make-console_is_usable-available-to-nbcon.patch index c3fecf4e31..8334063ed5 100644 --- a/debian/patches-rt/0021-printk-Make-console_is_usable-available-to-nbcon.patch +++ b/debian/patches-rt/0017-printk-Make-console_is_usable-available-to-nbcon.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 12 Sep 2023 13:25:41 +0000 -Subject: [PATCH 21/50] printk: Make console_is_usable() available to nbcon -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 17/48] printk: Make console_is_usable() available to nbcon +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Move console_is_usable() as-is into internal.h so that it can be used by nbcon printing functions as well. @@ -16,7 +16,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -78,6 +78,36 @@ bool nbcon_alloc(struct console *con); +@@ -85,6 +85,36 @@ bool nbcon_alloc(struct console *con); void nbcon_init(struct console *con); void nbcon_free(struct console *con); @@ -53,7 +53,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #else #define PRINTK_PREFIX_MAX 0 -@@ -99,6 +129,8 @@ static inline bool nbcon_alloc(struct co +@@ -106,6 +136,8 @@ static inline bool nbcon_alloc(struct co static inline void nbcon_init(struct console *con) { } static inline void nbcon_free(struct console *con) { } diff --git a/debian/patches-rt/0017-printk-nbcon-Ensure-ownership-release-on-failed-emit.patch b/debian/patches-rt/0017-printk-nbcon-Ensure-ownership-release-on-failed-emit.patch deleted file mode 100644 index 65553848f5..0000000000 --- a/debian/patches-rt/0017-printk-nbcon-Ensure-ownership-release-on-failed-emit.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Fri, 20 Oct 2023 09:52:59 +0000 -Subject: [PATCH 17/50] printk: nbcon: Ensure ownership release on failed emit -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Until now it was assumed that ownership has been lost when the -write_atomic() callback fails. nbcon_emit_next_record() only -returns false when ownership has been lost. - -Ensure ownership has been lost before reporting failure by -explicitly attempting a release. If the current context is not -the owner, the release has no effect. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/printk/nbcon.c | 19 ++++++++++--------- - 1 file changed, 10 insertions(+), 9 deletions(-) - ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -852,7 +852,7 @@ static bool nbcon_emit_next_record(struc - unsigned long con_dropped; - struct nbcon_state cur; - unsigned long dropped; -- bool done; -+ bool done = false; - - /* - * The printk buffers are filled within an unsafe section. This -@@ -891,17 +891,18 @@ static bool nbcon_emit_next_record(struc - nbcon_state_read(con, &cur); - wctxt->unsafe_takeover = cur.unsafe_takeover; - -- if (con->write_atomic) { -+ if (con->write_atomic) - done = con->write_atomic(con, wctxt); -- } else { -- nbcon_context_release(ctxt); -- WARN_ON_ONCE(1); -- done = false; -- } - -- /* If not done, the emit was aborted. */ -- if (!done) -+ if (!done) { -+ /* -+ * The emit was aborted, probably due to a loss of ownership. -+ * Ensure ownership was lost or released before reporting the -+ * loss. -+ */ -+ nbcon_context_release(ctxt); - return false; -+ } - - /* - * Since any dropped message was successfully output, reset the diff --git a/debian/patches-rt/0017-serial-pch-Remove-eg20t_port-lock.patch b/debian/patches-rt/0017-serial-pch-Remove-eg20t_port-lock.patch new file mode 100644 index 0000000000..9ca34a1034 --- /dev/null +++ b/debian/patches-rt/0017-serial-pch-Remove-eg20t_port-lock.patch @@ -0,0 +1,128 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:30 +0100 +Subject: [PATCH 17/18] serial: pch: Remove eg20t_port::lock. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The struct eg20t_port has a spinlock_t which is used for locking while +access I/O of the device. Then there is the uart_portlock which is +sometimes and nests within eg20t_port's lock. + +The uart_port lock is not used while using the struct in +pch_uart_hal_read() which might be okay. Then both locks are used in +pch_console_write() which looks odd especially the double try_lock part. + +All in all it looks like the uart_port's lock could replace eg20t_port's +lock and simplify the code. + +Remove eg20t_port::lock and use uart_port's lock for the lock scope. + +Link: https://lore.kernel.org/r/20240301215246.891055-18-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/pch_uart.c | 26 ++++++-------------------- + 1 file changed, 6 insertions(+), 20 deletions(-) + +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -237,9 +237,6 @@ struct eg20t_port { + + #define IRQ_NAME_SIZE 17 + char irq_name[IRQ_NAME_SIZE]; +- +- /* protect the eg20t_port private structure and io access to membase */ +- spinlock_t lock; + }; + + /** +@@ -1013,7 +1010,7 @@ static irqreturn_t pch_uart_interrupt(in + int next = 1; + u8 msr; + +- spin_lock(&priv->lock); ++ uart_port_lock(&priv->port); + handled = 0; + while (next) { + iid = pch_uart_hal_get_iid(priv); +@@ -1073,7 +1070,7 @@ static irqreturn_t pch_uart_interrupt(in + handled |= (unsigned int)ret; + } + +- spin_unlock(&priv->lock); ++ uart_port_unlock(&priv->port); + return IRQ_RETVAL(handled); + } + +@@ -1184,9 +1181,9 @@ static void pch_uart_break_ctl(struct ua + unsigned long flags; + + priv = container_of(port, struct eg20t_port, port); +- spin_lock_irqsave(&priv->lock, flags); ++ uart_port_lock_irqsave(&priv->port, &flags); + pch_uart_hal_set_break(priv, ctl); +- spin_unlock_irqrestore(&priv->lock, flags); ++ uart_port_unlock_irqrestore(&priv->port, flags); + } + + /* Grab any interrupt resources and initialise any low level driver state. */ +@@ -1336,8 +1333,7 @@ static void pch_uart_set_termios(struct + + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); + +- spin_lock_irqsave(&priv->lock, flags); +- uart_port_lock(port); ++ uart_port_lock_irqsave(port, &flags); + + uart_update_timeout(port, termios->c_cflag, baud); + rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb); +@@ -1350,8 +1346,7 @@ static void pch_uart_set_termios(struct + tty_termios_encode_baud_rate(termios, baud, baud); + + out: +- uart_port_unlock(port); +- spin_unlock_irqrestore(&priv->lock, flags); ++ uart_port_unlock_irqrestore(port, flags); + } + + static const char *pch_uart_type(struct uart_port *port) +@@ -1555,7 +1550,6 @@ pch_console_write(struct console *co, co + { + struct eg20t_port *priv; + unsigned long flags; +- int priv_locked = 1; + int port_locked = 1; + u8 ier; + +@@ -1565,15 +1559,11 @@ pch_console_write(struct console *co, co + + local_irq_save(flags); + if (priv->port.sysrq) { +- /* call to uart_handle_sysrq_char already took the priv lock */ +- priv_locked = 0; + /* serial8250_handle_port() already took the port lock */ + port_locked = 0; + } else if (oops_in_progress) { +- priv_locked = spin_trylock(&priv->lock); + port_locked = uart_port_trylock(&priv->port); + } else { +- spin_lock(&priv->lock); + uart_port_lock(&priv->port); + } + +@@ -1595,8 +1585,6 @@ pch_console_write(struct console *co, co + + if (port_locked) + uart_port_unlock(&priv->port); +- if (priv_locked) +- spin_unlock(&priv->lock); + local_irq_restore(flags); + } + +@@ -1694,8 +1682,6 @@ static struct eg20t_port *pch_uart_init_ + pci_enable_msi(pdev); + pci_set_master(pdev); + +- spin_lock_init(&priv->lock); +- + iobase = pci_resource_start(pdev, 0); + mapbase = pci_resource_start(pdev, 1); + priv->mapbase = mapbase; diff --git a/debian/patches-rt/0022-printk-Let-console_is_usable-handle-nbcon.patch b/debian/patches-rt/0018-printk-Let-console_is_usable-handle-nbcon.patch index 3d7364fe69..6d995e7020 100644 --- a/debian/patches-rt/0022-printk-Let-console_is_usable-handle-nbcon.patch +++ b/debian/patches-rt/0018-printk-Let-console_is_usable-handle-nbcon.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 12 Sep 2023 13:53:21 +0000 -Subject: [PATCH 22/50] printk: Let console_is_usable() handle nbcon -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 18/48] printk: Let console_is_usable() handle nbcon +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The nbcon consoles use a different printing callback. For nbcon consoles, check for the write_atomic() callback instead of @@ -16,7 +16,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -80,6 +80,8 @@ void nbcon_free(struct console *con); +@@ -87,6 +87,8 @@ void nbcon_free(struct console *con); /* * Check if the given console is currently capable and allowed to print @@ -25,7 +25,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * records. * * Requires the console_srcu_read_lock. -@@ -94,8 +96,13 @@ static inline bool console_is_usable(str +@@ -101,8 +103,13 @@ static inline bool console_is_usable(str if ((flags & CON_SUSPENDED)) return false; diff --git a/debian/patches-rt/0018-serial-pch-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0018-serial-pch-Use-uart_prepare_sysrq_char.patch new file mode 100644 index 0000000000..55e6615c9e --- /dev/null +++ b/debian/patches-rt/0018-serial-pch-Use-uart_prepare_sysrq_char.patch @@ -0,0 +1,79 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 1 Mar 2024 22:45:31 +0100 +Subject: [PATCH 18/18] serial: pch: Use uart_prepare_sysrq_char(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT. +The driver splits the locking function into two parts: local_irq_save() and +uart_port_lock() and this breaks PREEMPT_RT. + +Delay handling sysrq until port lock is dropped. +Remove the special case in the console write routine an always use the +complete locking function. + +Link: https://lore.kernel.org/r/20240301215246.891055-19-bigeasy@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/tty/serial/pch_uart.c | 24 +++++++++--------------- + 1 file changed, 9 insertions(+), 15 deletions(-) + +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -564,7 +564,7 @@ static int pch_uart_hal_read(struct eg20 + if (uart_handle_break(port)) + continue; + } +- if (uart_handle_sysrq_char(port, rbr)) ++ if (uart_prepare_sysrq_char(port, rbr)) + continue; + + buf[i++] = rbr; +@@ -1070,7 +1070,7 @@ static irqreturn_t pch_uart_interrupt(in + handled |= (unsigned int)ret; + } + +- uart_port_unlock(&priv->port); ++ uart_unlock_and_check_sysrq(&priv->port); + return IRQ_RETVAL(handled); + } + +@@ -1550,22 +1550,17 @@ pch_console_write(struct console *co, co + { + struct eg20t_port *priv; + unsigned long flags; +- int port_locked = 1; ++ int locked = 1; + u8 ier; + + priv = pch_uart_ports[co->index]; + + touch_nmi_watchdog(); + +- local_irq_save(flags); +- if (priv->port.sysrq) { +- /* serial8250_handle_port() already took the port lock */ +- port_locked = 0; +- } else if (oops_in_progress) { +- port_locked = uart_port_trylock(&priv->port); +- } else { +- uart_port_lock(&priv->port); +- } ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(&priv->port, &flags); ++ else ++ uart_port_lock_irqsave(&priv->port, &flags); + + /* + * First save the IER then disable the interrupts +@@ -1583,9 +1578,8 @@ pch_console_write(struct console *co, co + wait_for_xmitr(priv, UART_LSR_BOTH_EMPTY); + iowrite8(ier, priv->membase + UART_IER); + +- if (port_locked) +- uart_port_unlock(&priv->port); +- local_irq_restore(flags); ++ if (locked) ++ uart_port_unlock_irqrestore(&priv->port, flags); + } + + static int __init pch_console_setup(struct console *co, char *options) diff --git a/debian/patches-rt/0023-printk-Add-flags-argument-for-console_is_usable.patch b/debian/patches-rt/0019-printk-Add-flags-argument-for-console_is_usable.patch index 12fff9afb9..ed902938c0 100644 --- a/debian/patches-rt/0023-printk-Add-flags-argument-for-console_is_usable.patch +++ b/debian/patches-rt/0019-printk-Add-flags-argument-for-console_is_usable.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 12 Sep 2023 13:45:33 +0000 -Subject: [PATCH 23/50] printk: Add @flags argument for console_is_usable() -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 19/48] printk: Add @flags argument for console_is_usable() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The caller of console_is_usable() usually needs @console->flags for its own checks. Rather than having console_is_usable() read @@ -18,7 +18,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -83,13 +83,9 @@ void nbcon_free(struct console *con); +@@ -90,13 +90,9 @@ void nbcon_free(struct console *con); * records. Note that this function does not consider the current context, * which can also play a role in deciding if @con can be used to print * records. @@ -33,7 +33,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!(flags & CON_ENABLED)) return false; -@@ -136,7 +132,7 @@ static inline bool nbcon_alloc(struct co +@@ -143,7 +139,7 @@ static inline bool nbcon_alloc(struct co static inline void nbcon_init(struct console *con) { } static inline void nbcon_free(struct console *con) { } @@ -56,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> continue; any_usable = true; -@@ -3791,7 +3792,7 @@ static bool __pr_flush(struct console *c +@@ -3819,7 +3820,7 @@ static bool __pr_flush(struct console *c * that they make forward progress, so only increment * @diff for usable consoles. */ diff --git a/debian/patches-rt/0019-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch b/debian/patches-rt/0019-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch deleted file mode 100644 index f20a359c21..0000000000 --- a/debian/patches-rt/0019-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch +++ /dev/null @@ -1,244 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Wed, 13 Sep 2023 08:35:23 +0000 -Subject: [PATCH 19/50] printk: nbcon: Implement processing in port->lock - wrapper -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Currently the port->lock wrappers uart_port_lock(), -uart_port_unlock() (and their variants) only lock/unlock -the spin_lock. - -If the port is an nbcon console, the wrappers must also -acquire/release the console and mark the region as unsafe. This -allows general port->lock synchronization to be synchronized -with the nbcon console ownership. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/console.h | 2 + - include/linux/printk.h | 13 +++++++ - include/linux/serial_core.h | 18 +++++++++- - kernel/printk/nbcon.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 108 insertions(+), 2 deletions(-) - ---- a/include/linux/console.h -+++ b/include/linux/console.h -@@ -306,6 +306,7 @@ struct nbcon_write_context { - * @nbcon_state: State for nbcon consoles - * @nbcon_seq: Sequence number of the next record for nbcon to print - * @pbufs: Pointer to nbcon private buffer -+ * @locked_port: True, if the port lock is locked by nbcon - */ - struct console { - char name[16]; -@@ -332,6 +333,7 @@ struct console { - atomic_t __private nbcon_state; - atomic_long_t __private nbcon_seq; - struct printk_buffers *pbufs; -+ bool locked_port; - }; - - #ifdef CONFIG_LOCKDEP ---- a/include/linux/printk.h -+++ b/include/linux/printk.h -@@ -9,6 +9,8 @@ - #include <linux/ratelimit_types.h> - #include <linux/once_lite.h> - -+struct uart_port; -+ - extern const char linux_banner[]; - extern const char linux_proc_banner[]; - -@@ -195,6 +197,8 @@ void show_regs_print_info(const char *lo - extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; - extern asmlinkage void dump_stack(void) __cold; - void printk_trigger_flush(void); -+extern void nbcon_acquire(struct uart_port *up); -+extern void nbcon_release(struct uart_port *up); - #else - static inline __printf(1, 0) - int vprintk(const char *s, va_list args) -@@ -274,6 +278,15 @@ static inline void dump_stack(void) - static inline void printk_trigger_flush(void) - { - } -+ -+static inline void nbcon_acquire(struct uart_port *up) -+{ -+} -+ -+static inline void nbcon_release(struct uart_port *up) -+{ -+} -+ - #endif - - #ifdef CONFIG_SMP ---- a/include/linux/serial_core.h -+++ b/include/linux/serial_core.h -@@ -595,6 +595,7 @@ struct uart_port { - static inline void uart_port_lock(struct uart_port *up) - { - spin_lock(&up->lock); -+ nbcon_acquire(up); - } - - /** -@@ -604,6 +605,7 @@ static inline void uart_port_lock(struct - static inline void uart_port_lock_irq(struct uart_port *up) - { - spin_lock_irq(&up->lock); -+ nbcon_acquire(up); - } - - /** -@@ -614,6 +616,7 @@ static inline void uart_port_lock_irq(st - static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) - { - spin_lock_irqsave(&up->lock, *flags); -+ nbcon_acquire(up); - } - - /** -@@ -624,7 +627,11 @@ static inline void uart_port_lock_irqsav - */ - static inline bool uart_port_trylock(struct uart_port *up) - { -- return spin_trylock(&up->lock); -+ if (!spin_trylock(&up->lock)) -+ return false; -+ -+ nbcon_acquire(up); -+ return true; - } - - /** -@@ -636,7 +643,11 @@ static inline bool uart_port_trylock(str - */ - static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags) - { -- return spin_trylock_irqsave(&up->lock, *flags); -+ if (!spin_trylock_irqsave(&up->lock, *flags)) -+ return false; -+ -+ nbcon_acquire(up); -+ return true; - } - - /** -@@ -645,6 +656,7 @@ static inline bool uart_port_trylock_irq - */ - static inline void uart_port_unlock(struct uart_port *up) - { -+ nbcon_release(up); - spin_unlock(&up->lock); - } - -@@ -654,6 +666,7 @@ static inline void uart_port_unlock(stru - */ - static inline void uart_port_unlock_irq(struct uart_port *up) - { -+ nbcon_release(up); - spin_unlock_irq(&up->lock); - } - -@@ -664,6 +677,7 @@ static inline void uart_port_unlock_irq( - */ - static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) - { -+ nbcon_release(up); - spin_unlock_irqrestore(&up->lock, flags); - } - ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -6,6 +6,7 @@ - #include <linux/console.h> - #include <linux/delay.h> - #include <linux/slab.h> -+#include <linux/serial_core.h> - #include "internal.h" - /* - * Printk console printing implementation for consoles which does not depend -@@ -995,3 +996,79 @@ void nbcon_free(struct console *con) - - con->pbufs = NULL; - } -+ -+static inline bool uart_is_nbcon(struct uart_port *up) -+{ -+ int cookie; -+ bool ret; -+ -+ if (!uart_console(up)) -+ return false; -+ -+ cookie = console_srcu_read_lock(); -+ ret = (console_srcu_read_flags(up->cons) & CON_NBCON); -+ console_srcu_read_unlock(cookie); -+ return ret; -+} -+ -+/** -+ * nbcon_acquire - The second half of the port locking wrapper -+ * @up: The uart port whose @lock was locked -+ * -+ * The uart_port_lock() wrappers will first lock the spin_lock @up->lock. -+ * Then this function is called to implement nbcon-specific processing. -+ * -+ * If @up is an nbcon console, this console will be acquired and marked as -+ * unsafe. Otherwise this function does nothing. -+ */ -+void nbcon_acquire(struct uart_port *up) -+{ -+ struct console *con = up->cons; -+ struct nbcon_context ctxt; -+ -+ if (!uart_is_nbcon(up)) -+ return; -+ -+ WARN_ON_ONCE(con->locked_port); -+ -+ do { -+ do { -+ memset(&ctxt, 0, sizeof(ctxt)); -+ ctxt.console = con; -+ ctxt.prio = NBCON_PRIO_NORMAL; -+ } while (!nbcon_context_try_acquire(&ctxt)); -+ -+ } while (!nbcon_context_enter_unsafe(&ctxt)); -+ -+ con->locked_port = true; -+} -+EXPORT_SYMBOL_GPL(nbcon_acquire); -+ -+/** -+ * nbcon_release - The first half of the port unlocking wrapper -+ * @up: The uart port whose @lock is about to be unlocked -+ * -+ * The uart_port_unlock() wrappers will first call this function to implement -+ * nbcon-specific processing. Then afterwards the uart_port_unlock() wrappers -+ * will unlock the spin_lock @up->lock. -+ * -+ * If @up is an nbcon console, the console will be marked as safe and -+ * released. Otherwise this function does nothing. -+ */ -+void nbcon_release(struct uart_port *up) -+{ -+ struct console *con = up->cons; -+ struct nbcon_context ctxt = { -+ .console = con, -+ .prio = NBCON_PRIO_NORMAL, -+ }; -+ -+ if (!con->locked_port) -+ return; -+ -+ if (nbcon_context_exit_unsafe(&ctxt)) -+ nbcon_context_release(&ctxt); -+ -+ con->locked_port = false; -+} -+EXPORT_SYMBOL_GPL(nbcon_release); diff --git a/debian/patches-rt/0020-printk-nbcon-Add-driver_enter-driver_exit-console-ca.patch b/debian/patches-rt/0020-printk-nbcon-Add-driver_enter-driver_exit-console-ca.patch deleted file mode 100644 index 04dcbc620a..0000000000 --- a/debian/patches-rt/0020-printk-nbcon-Add-driver_enter-driver_exit-console-ca.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Fri, 8 Dec 2023 15:54:27 +0000 -Subject: [PATCH 20/50] printk: nbcon: Add driver_enter/driver_exit console - callbacks -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Console drivers need some mechanism to synchronize between "normal -driver activity" and console printing. For uart serial drivers it -is the port lock. Other types of console drivers (network, -graphics, USB) will need something as well. - -Provide 2 new mandatory nbcon console callbacks (driver_enter and -driver_exit) to allow the consoles drivers to implement the -appropriate synchronization. The callbacks are also expected to -disable/enable migration. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/console.h | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/include/linux/console.h -+++ b/include/linux/console.h -@@ -303,6 +303,8 @@ struct nbcon_write_context { - * @node: hlist node for the console list - * - * @write_atomic: Write callback for atomic context -+ * @driver_enter: Callback to begin synchronization with driver code -+ * @driver_exit: Callback to finish synchronization with driver code - * @nbcon_state: State for nbcon consoles - * @nbcon_seq: Sequence number of the next record for nbcon to print - * @pbufs: Pointer to nbcon private buffer -@@ -330,6 +332,8 @@ struct console { - /* nbcon console specific members */ - bool (*write_atomic)(struct console *con, - struct nbcon_write_context *wctxt); -+ void (*driver_enter)(struct console *con, unsigned long *flags); -+ void (*driver_exit)(struct console *con, unsigned long flags); - atomic_t __private nbcon_state; - atomic_long_t __private nbcon_seq; - struct printk_buffers *pbufs; diff --git a/debian/patches-rt/0024-printk-nbcon-Provide-function-to-flush-using-write_a.patch b/debian/patches-rt/0020-printk-nbcon-Provide-function-to-flush-using-write_a.patch index 9f8a3e3765..26c68ed229 100644 --- a/debian/patches-rt/0024-printk-nbcon-Provide-function-to-flush-using-write_a.patch +++ b/debian/patches-rt/0020-printk-nbcon-Provide-function-to-flush-using-write_a.patch @@ -1,26 +1,29 @@ From: Thomas Gleixner <tglx@linutronix.de> Date: Tue, 12 Sep 2023 12:00:08 +0000 -Subject: [PATCH 24/50] printk: nbcon: Provide function to flush using +Subject: [PATCH 20/48] printk: nbcon: Provide function to flush using write_atomic() -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz -Provide nbcon_atomic_flush_all() to perform flushing of all +Provide nbcon_atomic_flush_pending() to perform flushing of all registered nbcon consoles using their write_atomic() callback. -Like with legacy consoles, the nbcon consoles are flushed one -record per console. This allows all nbcon consoles to print -lines pseudo-simultaneously, rather than one console waiting -for the full ringbuffer to dump to another console before -printing anything. -Unlike console_flush_all(), nbcon_atomic_flush_all() will only -flush up through the newest record at the time of the call. -This prevents a CPU from printing unbounded when other CPUs are -adding records. +Unlike console_flush_all(), nbcon_atomic_flush_pending() will +only flush up through the newest record at the time of the +call. This prevents a CPU from printing unbounded when other +CPUs are adding records. -Perform nbcon console atomic flushing in -console_flush_on_panic(). This function is not only used in -panic() but also other locations where there may be stored -messages that need to be flushed. +Also unlike console_flush_all(), nbcon_atomic_flush_pending() +will fully flush one console before flushing the next. This +helps to guarantee that a block of pending records (such as +a stack trace in an emergency situation) can be printed +atomically at once before releasing console ownership. + +nbcon_atomic_flush_pending() is safe in any context because it +uses write_atomic() and acquires with unsafe_takeover disabled. + +Use it in console_flush_on_panic() before flushing legacy +consoles. The legacy write() callbacks are not fully safe when +oops_in_progress is set. Co-developed-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: John Ogness <john.ogness@linutronix.de> @@ -28,31 +31,31 @@ Signed-off-by: Thomas Gleixner (Intel) <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- kernel/printk/internal.h | 2 - kernel/printk/nbcon.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++- + kernel/printk/nbcon.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++- kernel/printk/printk.c | 2 - 3 files changed, 102 insertions(+), 2 deletions(-) + 3 files changed, 106 insertions(+), 2 deletions(-) --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -77,6 +77,7 @@ void nbcon_seq_force(struct console *con +@@ -84,6 +84,7 @@ void nbcon_seq_force(struct console *con bool nbcon_alloc(struct console *con); void nbcon_init(struct console *con); void nbcon_free(struct console *con); -+void nbcon_atomic_flush_all(void); ++void nbcon_atomic_flush_pending(void); /* * Check if the given console is currently capable and allowed to print -@@ -131,6 +132,7 @@ static inline void nbcon_seq_force(struc +@@ -138,6 +139,7 @@ static inline void nbcon_seq_force(struc static inline bool nbcon_alloc(struct console *con) { return false; } static inline void nbcon_init(struct console *con) { } static inline void nbcon_free(struct console *con) { } -+static inline void nbcon_atomic_flush_all(void) { } ++static inline void nbcon_atomic_flush_pending(void) { } static inline bool console_is_usable(struct console *con, short flags) { return false; } --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -539,7 +539,6 @@ static struct printk_buffers panic_nbcon +@@ -548,7 +548,6 @@ static struct printk_buffers panic_nbcon * in an unsafe state. Otherwise, on success the caller may assume * the console is not in an unsafe state. */ @@ -60,7 +63,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static bool nbcon_context_try_acquire(struct nbcon_context *ctxt) { unsigned int cpu = smp_processor_id(); -@@ -841,7 +840,6 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); +@@ -850,7 +849,6 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); * When true is returned, @wctxt->ctxt.backlog indicates whether there are * still records pending in the ringbuffer, */ @@ -68,56 +71,65 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt) { struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); -@@ -931,6 +929,104 @@ static bool nbcon_emit_next_record(struc +@@ -938,6 +936,108 @@ static bool nbcon_emit_next_record(struc } /** -+ * nbcon_atomic_emit_one - Print one record for an nbcon console using the -+ * write_atomic() callback -+ * @wctxt: An initialized write context struct to use -+ * for this context ++ * __nbcon_atomic_flush_pending_con - Flush specified nbcon console using its ++ * write_atomic() callback ++ * @con: The nbcon console to flush ++ * @stop_seq: Flush up until this record + * -+ * Return: False if the given console could not print a record or there -+ * are no more records to print, otherwise true. ++ * Return: True if taken over while printing. Otherwise false. + * -+ * This is an internal helper to handle the locking of the console before -+ * calling nbcon_emit_next_record(). ++ * If flushing up to @stop_seq was not successful, it only makes sense for the ++ * caller to try again when true was returned. When false is returned, either ++ * there are no more records available to read or this context is not allowed ++ * to acquire the console. + */ -+static bool nbcon_atomic_emit_one(struct nbcon_write_context *wctxt) ++static bool __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) +{ -+ struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); ++ struct nbcon_write_context wctxt = { }; ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); ++ ++ ctxt->console = con; ++ ctxt->spinwait_max_us = 2000; ++ ctxt->prio = NBCON_PRIO_NORMAL; + + if (!nbcon_context_try_acquire(ctxt)) + return false; + -+ /* -+ * nbcon_emit_next_record() returns false when the console was -+ * handed over or taken over. In both cases the context is no -+ * longer valid. -+ */ -+ if (!nbcon_emit_next_record(wctxt)) -+ return false; ++ while (nbcon_seq_read(con) < stop_seq) { ++ /* ++ * nbcon_emit_next_record() returns false when the console was ++ * handed over or taken over. In both cases the context is no ++ * longer valid. ++ */ ++ if (!nbcon_emit_next_record(&wctxt)) ++ return true; ++ ++ if (!ctxt->backlog) ++ break; ++ } + + nbcon_context_release(ctxt); + -+ return ctxt->backlog; ++ return false; +} + +/** -+ * __nbcon_atomic_flush_all - Flush all nbcon consoles using their ++ * __nbcon_atomic_flush_pending - Flush all nbcon consoles using their + * write_atomic() callback + * @stop_seq: Flush up until this record + */ -+static void __nbcon_atomic_flush_all(u64 stop_seq) ++static void __nbcon_atomic_flush_pending(u64 stop_seq) +{ -+ struct nbcon_write_context wctxt = { }; -+ struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); + struct console *con; -+ bool any_progress; ++ bool should_retry; + int cookie; + + do { -+ any_progress = false; ++ should_retry = false; + + cookie = console_srcu_read_lock(); + for_each_console_srcu(con) { @@ -133,40 +145,35 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + if (nbcon_seq_read(con) >= stop_seq) + continue; + -+ memset(ctxt, 0, sizeof(*ctxt)); -+ ctxt->console = con; -+ ctxt->spinwait_max_us = 2000; -+ ctxt->prio = NBCON_PRIO_NORMAL; -+ + /* + * Atomic flushing does not use console driver + * synchronization (i.e. it does not hold the port + * lock for uart consoles). Therefore IRQs must be + * disabled to avoid being interrupted and then + * calling into a driver that will deadlock trying -+ * acquire console ownership. ++ * to acquire console ownership. + */ + local_irq_save(irq_flags); + -+ any_progress |= nbcon_atomic_emit_one(&wctxt); ++ should_retry |= __nbcon_atomic_flush_pending_con(con, stop_seq); + + local_irq_restore(irq_flags); + } + console_srcu_read_unlock(cookie); -+ } while (any_progress); ++ } while (should_retry); +} + +/** -+ * nbcon_atomic_flush_all - Flush all nbcon consoles using their ++ * nbcon_atomic_flush_pending - Flush all nbcon consoles using their + * write_atomic() callback + * + * Flush the backlog up through the currently newest record. Any new + * records added while flushing will not be flushed. This is to avoid + * one CPU printing unbounded because other CPUs continue to add records. + */ -+void nbcon_atomic_flush_all(void) ++void nbcon_atomic_flush_pending(void) +{ -+ __nbcon_atomic_flush_all(prb_next_reserve_seq(prb)); ++ __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb)); +} + +/** @@ -179,7 +186,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> console_srcu_read_unlock(cookie); } -+ nbcon_atomic_flush_all(); ++ nbcon_atomic_flush_pending(); + console_flush_all(false, &next_seq, &handover); } diff --git a/debian/patches-rt/0025-printk-Track-registered-boot-consoles.patch b/debian/patches-rt/0021-printk-Track-registered-boot-consoles.patch index 5c35ea115c..64ee0c4dbb 100644 --- a/debian/patches-rt/0025-printk-Track-registered-boot-consoles.patch +++ b/debian/patches-rt/0021-printk-Track-registered-boot-consoles.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 24 Oct 2023 14:13:14 +0000 -Subject: [PATCH 25/50] printk: Track registered boot consoles -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 21/48] printk: Track registered boot consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Unfortunately it is not known if a boot console and a regular (legacy or nbcon) console use the same hardware. For this reason @@ -17,6 +17,7 @@ to ensure that boot consoles and nbcon consoles cannot print simultaneously. Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- kernel/printk/printk.c | 24 ++++++++++++++++++++++++ @@ -34,22 +35,22 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + * the console lock. This is because boot consoles and nbcon consoles may + * have mapped the same hardware. + */ -+bool have_boot_console; ++static bool have_boot_console; + #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); /* All 3 protected by @syslog_lock. */ -@@ -3507,6 +3515,9 @@ void register_console(struct console *ne - if (newcon->flags & CON_NBCON) - nbcon_init(newcon); +@@ -3518,6 +3526,9 @@ void register_console(struct console *ne + newcon->seq = 0; + } + if (newcon->flags & CON_BOOT) + have_boot_console = true; + /* - * Put this console in the list - keep the - * preferred driver at the head of the list. -@@ -3559,6 +3570,8 @@ EXPORT_SYMBOL(register_console); + * If another context is actively using the hardware of this new + * console, it will not be aware of the nbcon synchronization. This +@@ -3587,6 +3598,8 @@ EXPORT_SYMBOL(register_console); /* Must be called under console_list_lock(). */ static int unregister_console_locked(struct console *console) { @@ -58,7 +59,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> int res; lockdep_assert_console_list_lock_held(); -@@ -3606,6 +3619,17 @@ static int unregister_console_locked(str +@@ -3634,6 +3647,17 @@ static int unregister_console_locked(str if (console->exit) res = console->exit(console); @@ -71,7 +72,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + found_boot_con = true; + } + if (!found_boot_con) -+ have_boot_console = false; ++ have_boot_console = found_boot_con; + return res; } diff --git a/debian/patches-rt/0026-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch b/debian/patches-rt/0022-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch index 512310071b..02c868a001 100644 --- a/debian/patches-rt/0026-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch +++ b/debian/patches-rt/0022-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch @@ -1,14 +1,15 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 19 Sep 2023 14:33:27 +0000 -Subject: [PATCH 26/50] printk: nbcon: Use nbcon consoles in +Subject: [PATCH 22/48] printk: nbcon: Use nbcon consoles in console_flush_all() -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz -Allow nbcon consoles to print messages in the printk() caller -context by integrating them into console_flush_all(). The -write_atomic() callback is used for printing. +Allow nbcon consoles to print messages in the legacy printk() +caller context (printing via unlock) by integrating them into +console_flush_all(). The write_atomic() callback is used for +printing. -Provide nbcon_console_emit_next_record(), which acts as the +Provide nbcon_legacy_emit_next_record(), which acts as the nbcon variant of console_emit_next_record(). Call this variant within console_flush_all() for nbcon consoles. Since nbcon consoles use their own @nbcon_seq variable to track the next @@ -17,14 +18,14 @@ record to print, this also must be appropriately handled. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/printk/internal.h | 5 ++++ - kernel/printk/nbcon.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ - kernel/printk/printk.c | 19 +++++++++++++---- - 3 files changed, 69 insertions(+), 5 deletions(-) + kernel/printk/internal.h | 6 +++ + kernel/printk/nbcon.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ + kernel/printk/printk.c | 17 +++++++--- + 3 files changed, 95 insertions(+), 5 deletions(-) --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -71,6 +71,8 @@ void defer_console_output(void); +@@ -78,6 +78,8 @@ void defer_console_output(void); u16 printk_parse_prefix(const char *text, int *level, enum printk_info_flags *flags); @@ -33,26 +34,27 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> u64 nbcon_seq_read(struct console *con); void nbcon_seq_force(struct console *con, u64 seq); -@@ -78,6 +80,7 @@ bool nbcon_alloc(struct console *con); +@@ -85,6 +87,8 @@ bool nbcon_alloc(struct console *con); void nbcon_init(struct console *con); void nbcon_free(struct console *con); - void nbcon_atomic_flush_all(void); -+bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, int cookie); + void nbcon_atomic_flush_pending(void); ++bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, ++ int cookie); /* * Check if the given console is currently capable and allowed to print -@@ -133,6 +136,8 @@ static inline bool nbcon_alloc(struct co +@@ -140,6 +144,8 @@ static inline bool nbcon_alloc(struct co static inline void nbcon_init(struct console *con) { } static inline void nbcon_free(struct console *con) { } - static inline void nbcon_atomic_flush_all(void) { } -+static inline bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, + static inline void nbcon_atomic_flush_pending(void) { } ++static inline bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, + int cookie) { return false; } static inline bool console_is_usable(struct console *con, short flags) { return false; } --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -532,6 +532,7 @@ static struct printk_buffers panic_nbcon +@@ -541,6 +541,7 @@ static struct printk_buffers panic_nbcon * nbcon_context_try_acquire - Try to acquire nbcon console * @ctxt: The context of the caller * @@ -60,12 +62,43 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Return: True if the console was acquired. False otherwise. * * If the caller allowed an unsafe hostile takeover, on success the -@@ -961,6 +962,55 @@ static bool nbcon_atomic_emit_one(struct +@@ -936,6 +937,82 @@ static bool nbcon_emit_next_record(struc } /** -+ * nbcon_atomic_emit_next_record - Print one record for an nbcon console -+ * using the write_atomic() callback ++ * nbcon_atomic_emit_one - Print one record for an nbcon console using the ++ * write_atomic() callback ++ * @wctxt: An initialized write context struct to use for this context ++ * ++ * Return: False if it is known there are no more records to print, ++ * otherwise true. ++ * ++ * This is an internal helper to handle the locking of the console before ++ * calling nbcon_emit_next_record(). ++ */ ++static bool nbcon_atomic_emit_one(struct nbcon_write_context *wctxt) ++{ ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); ++ ++ if (!nbcon_context_try_acquire(ctxt)) ++ return true; ++ ++ /* ++ * nbcon_emit_next_record() returns false when the console was ++ * handed over or taken over. In both cases the context is no ++ * longer valid. ++ */ ++ if (!nbcon_emit_next_record(wctxt)) ++ return true; ++ ++ nbcon_context_release(ctxt); ++ ++ return ctxt->backlog; ++} ++ ++/** ++ * nbcon_legacy_emit_next_record - Print one record for an nbcon console ++ * in legacy contexts + * @con: The console to print on + * @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 @@ -73,38 +106,34 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + * is set to false. + * @cookie: The cookie from the SRCU read lock. + * -+ * Context: Any context which could not be migrated to another CPU. -+ * Return: True if a record could be printed, otherwise false. ++ * Context: Any context except NMI. ++ * Return: False if the given console has no next record to print, ++ * otherwise true. + * + * This function is meant to be called by console_flush_all() to print records -+ * on nbcon consoles using the write_atomic() callback. Essentially it is the -+ * nbcon version of console_emit_next_record(). ++ * on nbcon consoles from legacy context (printing via console unlocking). ++ * Essentially it is the nbcon version of console_emit_next_record(). + */ -+bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, int cookie) ++bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, ++ int cookie) +{ + struct nbcon_write_context wctxt = { }; + struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); -+ unsigned long driver_flags; -+ bool progress = false; + unsigned long flags; ++ bool progress; + + *handover = false; + -+ /* Use the same locking order as console_emit_next_record(). */ ++ /* Use the same procedure as console_emit_next_record(). */ + printk_safe_enter_irqsave(flags); + console_lock_spinning_enable(); + stop_critical_timings(); + -+ con->driver_enter(con, &driver_flags); -+ cant_migrate(); -+ + ctxt->console = con; + ctxt->prio = NBCON_PRIO_NORMAL; + + progress = nbcon_atomic_emit_one(&wctxt); + -+ con->driver_exit(con, driver_flags); -+ + start_critical_timings(); + *handover = console_lock_spinning_disable_and_check(cookie); + printk_safe_exit_irqrestore(flags); @@ -113,9 +142,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +} + +/** - * __nbcon_atomic_flush_all - Flush all nbcon consoles using their + * __nbcon_atomic_flush_pending_con - Flush specified nbcon console using its * write_atomic() callback - * @stop_seq: Flush up until this record + * @con: The nbcon console to flush --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1871,7 +1871,7 @@ static bool console_waiter; @@ -136,7 +165,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { int waiter; -@@ -2956,13 +2956,22 @@ static bool console_flush_all(bool do_co +@@ -2956,13 +2956,20 @@ static bool console_flush_all(bool do_co cookie = console_srcu_read_lock(); for_each_console_srcu(con) { short flags = console_srcu_read_flags(con); @@ -149,18 +178,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> - progress = console_emit_next_record(con, handover, cookie); + if (flags & CON_NBCON) { -+ progress = nbcon_atomic_emit_next_record(con, handover, cookie); -+ ++ progress = nbcon_legacy_emit_next_record(con, handover, cookie); + printk_seq = nbcon_seq_read(con); + } else { + progress = console_emit_next_record(con, handover, cookie); -+ + printk_seq = con->seq; + } /* * If a handover has occurred, the SRCU read lock -@@ -2972,8 +2981,8 @@ static bool console_flush_all(bool do_co +@@ -2972,8 +2979,8 @@ static bool console_flush_all(bool do_co return false; /* Track the next of the highest seq flushed. */ diff --git a/debian/patches-rt/0023-printk-nbcon-Assign-priority-based-on-CPU-state.patch b/debian/patches-rt/0023-printk-nbcon-Assign-priority-based-on-CPU-state.patch new file mode 100644 index 0000000000..ff275e2ab9 --- /dev/null +++ b/debian/patches-rt/0023-printk-nbcon-Assign-priority-based-on-CPU-state.patch @@ -0,0 +1,84 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Thu, 14 Dec 2023 14:38:42 +0000 +Subject: [PATCH 23/48] printk: nbcon: Assign priority based on CPU state +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Use the current state of the CPU to determine which priority to +assign to the printing context. + +The EMERGENCY priority handling is added in a follow-up commit. +It will use a per-CPU variable. + +Note: nbcon_driver_acquire(), which is used by console drivers + to acquire the nbcon console for non-printing activities, + will always use NORMAL priority. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Reviewed-by: Petr Mladek <pmladek@suse.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/printk/internal.h | 2 ++ + kernel/printk/nbcon.c | 20 ++++++++++++++++++-- + 2 files changed, 20 insertions(+), 2 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -86,6 +86,7 @@ void nbcon_seq_force(struct console *con + bool nbcon_alloc(struct console *con); + void nbcon_init(struct console *con); + void nbcon_free(struct console *con); ++enum nbcon_prio nbcon_get_default_prio(void); + void nbcon_atomic_flush_pending(void); + bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, + int cookie); +@@ -143,6 +144,7 @@ static inline void nbcon_seq_force(struc + static inline bool nbcon_alloc(struct console *con) { return false; } + static inline void nbcon_init(struct console *con) { } + static inline void nbcon_free(struct console *con) { } ++static inline enum nbcon_prio nbcon_get_default_prio(void) { return NBCON_PRIO_NONE; } + static inline void nbcon_atomic_flush_pending(void) { } + static inline bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, + int cookie) { return false; } +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -968,6 +968,22 @@ static bool nbcon_atomic_emit_one(struct + } + + /** ++ * nbcon_get_default_prio - The appropriate nbcon priority to use for nbcon ++ * printing on the current CPU ++ * ++ * Context: Any context which could not be migrated to another CPU. ++ * Return: The nbcon_prio to use for acquiring an nbcon console in this ++ * context for printing. ++ */ ++enum nbcon_prio nbcon_get_default_prio(void) ++{ ++ if (this_cpu_in_panic()) ++ return NBCON_PRIO_PANIC; ++ ++ return NBCON_PRIO_NORMAL; ++} ++ ++/** + * nbcon_legacy_emit_next_record - Print one record for an nbcon console + * in legacy contexts + * @con: The console to print on +@@ -1001,7 +1017,7 @@ bool nbcon_legacy_emit_next_record(struc + stop_critical_timings(); + + ctxt->console = con; +- ctxt->prio = NBCON_PRIO_NORMAL; ++ ctxt->prio = nbcon_get_default_prio(); + + progress = nbcon_atomic_emit_one(&wctxt); + +@@ -1032,7 +1048,7 @@ static bool __nbcon_atomic_flush_pending + + ctxt->console = con; + ctxt->spinwait_max_us = 2000; +- ctxt->prio = NBCON_PRIO_NORMAL; ++ ctxt->prio = nbcon_get_default_prio(); + + if (!nbcon_context_try_acquire(ctxt)) + return false; diff --git a/debian/patches-rt/0024-printk-nbcon-Add-unsafe-flushing-on-panic.patch b/debian/patches-rt/0024-printk-nbcon-Add-unsafe-flushing-on-panic.patch new file mode 100644 index 0000000000..a63a8ac515 --- /dev/null +++ b/debian/patches-rt/0024-printk-nbcon-Add-unsafe-flushing-on-panic.patch @@ -0,0 +1,125 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Fri, 20 Oct 2023 10:03:42 +0000 +Subject: [PATCH 24/48] printk: nbcon: Add unsafe flushing on panic +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Add nbcon_atomic_flush_unsafe() to flush all nbcon consoles +using the write_atomic() callback and allowing unsafe hostile +takeovers. Call this at the end of panic() as a final attempt +to flush any pending messages. + +Note that legacy consoles use unsafe methods for flushing +from the beginning of panic (see bust_spinlocks()). Therefore, +systems using both legacy and nbcon consoles may still fail to +see panic messages due to unsafe legacy console usage. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/printk.h | 5 +++++ + kernel/panic.c | 1 + + kernel/printk/nbcon.c | 26 +++++++++++++++++++++----- + 3 files changed, 27 insertions(+), 5 deletions(-) + +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -197,6 +197,7 @@ extern asmlinkage void dump_stack(void) + void printk_trigger_flush(void); + extern void nbcon_driver_acquire(struct console *con); + extern void nbcon_driver_release(struct console *con); ++void nbcon_atomic_flush_unsafe(void); + #else + static inline __printf(1, 0) + int vprintk(const char *s, va_list args) +@@ -285,6 +286,10 @@ static inline void nbcon_driver_release( + { + } + ++static inline void nbcon_atomic_flush_unsafe(void) ++{ ++} ++ + #endif + + bool this_cpu_in_panic(void); +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -453,6 +453,7 @@ void panic(const char *fmt, ...) + * Explicitly flush the kernel log buffer one last time. + */ + console_flush_on_panic(CONSOLE_FLUSH_PENDING); ++ nbcon_atomic_flush_unsafe(); + + local_irq_enable(); + for (i = 0; ; i += PANIC_TIMER_STEP) { +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -1033,6 +1033,7 @@ bool nbcon_legacy_emit_next_record(struc + * write_atomic() callback + * @con: The nbcon console to flush + * @stop_seq: Flush up until this record ++ * @allow_unsafe_takeover: True, to allow unsafe hostile takeovers + * + * Return: True if taken over while printing. Otherwise false. + * +@@ -1041,7 +1042,8 @@ bool nbcon_legacy_emit_next_record(struc + * there are no more records available to read or this context is not allowed + * to acquire the console. + */ +-static bool __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) ++static bool __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq, ++ bool allow_unsafe_takeover) + { + struct nbcon_write_context wctxt = { }; + struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); +@@ -1049,6 +1051,7 @@ static bool __nbcon_atomic_flush_pending + ctxt->console = con; + ctxt->spinwait_max_us = 2000; + ctxt->prio = nbcon_get_default_prio(); ++ ctxt->allow_unsafe_takeover = allow_unsafe_takeover; + + if (!nbcon_context_try_acquire(ctxt)) + return false; +@@ -1075,8 +1078,9 @@ static bool __nbcon_atomic_flush_pending + * __nbcon_atomic_flush_pending - Flush all nbcon consoles using their + * write_atomic() callback + * @stop_seq: Flush up until this record ++ * @allow_unsafe_takeover: True, to allow unsafe hostile takeovers + */ +-static void __nbcon_atomic_flush_pending(u64 stop_seq) ++static void __nbcon_atomic_flush_pending(u64 stop_seq, bool allow_unsafe_takeover) + { + struct console *con; + bool should_retry; +@@ -1109,8 +1113,8 @@ static void __nbcon_atomic_flush_pending + */ + local_irq_save(irq_flags); + +- should_retry |= __nbcon_atomic_flush_pending_con(con, stop_seq); +- ++ should_retry |= __nbcon_atomic_flush_pending_con(con, stop_seq, ++ allow_unsafe_takeover); + local_irq_restore(irq_flags); + } + console_srcu_read_unlock(cookie); +@@ -1127,7 +1131,19 @@ static void __nbcon_atomic_flush_pending + */ + void nbcon_atomic_flush_pending(void) + { +- __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb)); ++ __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), false); ++} ++ ++/** ++ * nbcon_atomic_flush_unsafe - Flush all nbcon consoles using their ++ * write_atomic() callback and allowing unsafe hostile takeovers ++ * ++ * Flush the backlog up through the currently newest record. Unsafe hostile ++ * takeovers will be performed, if necessary. ++ */ ++void nbcon_atomic_flush_unsafe(void) ++{ ++ __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), true); + } + + /** diff --git a/debian/patches-rt/0029-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch b/debian/patches-rt/0025-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch index a0be40fe7b..8156ae1d14 100644 --- a/debian/patches-rt/0029-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch +++ b/debian/patches-rt/0025-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch @@ -1,18 +1,14 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 26 Sep 2023 12:44:07 +0000 -Subject: [PATCH 29/50] printk: Avoid console_lock dance if no legacy or boot +Subject: [PATCH 25/48] printk: Avoid console_lock dance if no legacy or boot consoles -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Currently the console lock is used to attempt legacy-type printing even if there are no legacy or boot consoles registered. If no such consoles are registered, the console lock does not need to be taken. -Also, if boot consoles are registered, nbcon consoles must -perform their atomic printing under the console lock in order -to be synchronized with boot consoles. - Add tracking of legacy console registration and use it with boot console tracking to avoid unnecessary code paths, i.e. do not use the console lock if there are no boot consoles @@ -21,38 +17,9 @@ and no legacy consoles. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/printk/internal.h | 12 +++++++++ - kernel/printk/printk.c | 59 +++++++++++++++++++++++++++++++++++------------ - 2 files changed, 56 insertions(+), 15 deletions(-) + kernel/printk/printk.c | 79 +++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 64 insertions(+), 15 deletions(-) ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -44,6 +44,16 @@ enum printk_info_flags { - }; - - extern struct printk_ringbuffer *prb; -+extern bool have_legacy_console; -+extern bool have_boot_console; -+ -+/* -+ * Specifies if the console lock/unlock dance is needed for console -+ * printing. If @have_boot_console is true, the nbcon consoles will -+ * be printed serially along with the legacy consoles because nbcon -+ * consoles cannot print simultaneously with boot consoles. -+ */ -+#define printing_via_unlock (have_legacy_console || have_boot_console) - - __printf(4, 0) - int vprintk_store(int facility, int level, -@@ -122,6 +132,8 @@ static inline bool console_is_usable(str - #define PRINTK_MESSAGE_MAX 0 - #define PRINTKRB_RECORD_MAX 0 - -+#define printing_via_unlock (false) -+ - /* - * In !PRINTK builds we still export console_sem - * semaphore and some of console functions (console_unlock()/etc.), so --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -464,6 +464,13 @@ static int console_msg_format = MSG_FORM @@ -60,16 +27,31 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* + * Specifies if a legacy console is registered. If legacy consoles are -+ * present, it is necessary to perform the console_lock/console_unlock dance ++ * present, it is necessary to perform the console lock/unlock dance + * whenever console flushing should occur. + */ -+bool have_legacy_console; ++static bool have_legacy_console; + +/* * Specifies if a boot console is registered. If boot consoles are present, * nbcon consoles cannot print simultaneously and must be synchronized by * the console lock. This is because boot consoles and nbcon consoles may -@@ -2344,7 +2351,7 @@ asmlinkage int vprintk_emit(int facility +@@ -471,6 +478,14 @@ static DEFINE_MUTEX(syslog_lock); + */ + static bool have_boot_console; + ++/* ++ * Specifies if the console lock/unlock dance is needed for console ++ * printing. If @have_boot_console is true, the nbcon consoles will ++ * be printed serially along with the legacy consoles because nbcon ++ * consoles cannot print simultaneously with boot consoles. ++ */ ++#define printing_via_unlock (have_legacy_console || have_boot_console) ++ + #ifdef CONFIG_PRINTK + DECLARE_WAIT_QUEUE_HEAD(log_wait); + /* All 3 protected by @syslog_lock. */ +@@ -2344,7 +2359,7 @@ asmlinkage int vprintk_emit(int facility printed_len = vprintk_store(facility, level, dev_info, fmt, args); /* If called from the scheduler, we can not call up(). */ @@ -78,7 +60,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * The caller may be holding system-critical or * timing-sensitive locks. Disable preemption during -@@ -2653,7 +2660,7 @@ void resume_console(void) +@@ -2653,7 +2668,7 @@ void resume_console(void) */ static int console_cpu_notify(unsigned int cpu) { @@ -87,9 +69,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* If trylock fails, someone else is doing the printing */ if (console_trylock()) console_unlock(); -@@ -3196,7 +3203,8 @@ void console_flush_on_panic(enum con_flu +@@ -3194,7 +3209,8 @@ void console_flush_on_panic(enum con_flu - nbcon_atomic_flush_all(); + nbcon_atomic_flush_pending(); - console_flush_all(false, &next_seq, &handover); + if (printing_via_unlock) @@ -97,20 +79,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* -@@ -3521,8 +3529,11 @@ void register_console(struct console *ne - newcon->dropped = 0; - console_init_seq(newcon, bootcon_registered); - -- if (newcon->flags & CON_NBCON) -+ if (newcon->flags & CON_NBCON) { - nbcon_init(newcon); +@@ -3531,6 +3547,8 @@ void register_console(struct console *ne + */ + nbcon_seq_force(newcon, newcon->seq); + newcon->seq = 0; + } else { + have_legacy_console = true; -+ } + } if (newcon->flags & CON_BOOT) - have_boot_console = true; -@@ -3579,6 +3590,7 @@ EXPORT_SYMBOL(register_console); +@@ -3605,6 +3623,7 @@ EXPORT_SYMBOL(register_console); /* Must be called under console_list_lock(). */ static int unregister_console_locked(struct console *console) { @@ -118,7 +96,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> bool found_boot_con = false; struct console *c; int res; -@@ -3635,9 +3647,13 @@ static int unregister_console_locked(str +@@ -3661,9 +3680,13 @@ static int unregister_console_locked(str for_each_console(c) { if (c->flags & CON_BOOT) found_boot_con = true; @@ -126,21 +104,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + found_legacy_con = true; } if (!found_boot_con) - have_boot_console = false; + have_boot_console = found_boot_con; + if (!found_legacy_con) -+ have_legacy_console = false; ++ have_legacy_console = found_legacy_con; return res; } -@@ -3789,6 +3805,7 @@ static bool __pr_flush(struct console *c - u64 last_diff = 0; - u64 printk_seq; - short flags; -+ bool locked; - int cookie; - u64 diff; - u64 seq; -@@ -3798,22 +3815,28 @@ static bool __pr_flush(struct console *c +@@ -3824,22 +3847,34 @@ static bool __pr_flush(struct console *c seq = prb_next_reserve_seq(prb); /* Flush the consoles so that records up to @seq are printed. */ @@ -154,18 +124,25 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> for (;;) { unsigned long begin_jiffies; unsigned long slept_jiffies; +- +- diff = 0; ++ bool use_console_lock = printing_via_unlock; -+ locked = false; - diff = 0; - -- /* + /* - * Hold the console_lock to guarantee safe access to - * console->seq. Releasing console_lock flushes more - * records in case @seq is still not printed on all - * usable consoles. -- */ ++ * Ensure the compiler does not optimize @use_console_lock to ++ * be @printing_via_unlock since the latter can change at any ++ * time. + */ - console_lock(); -+ if (printing_via_unlock) { ++ barrier(); ++ ++ diff = 0; ++ ++ if (use_console_lock) { + /* + * Hold the console_lock to guarantee safe access to + * console->seq. Releasing console_lock flushes more @@ -173,39 +150,58 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + * usable consoles. + */ + console_lock(); -+ locked = true; + } cookie = console_srcu_read_lock(); for_each_console_srcu(c) { -@@ -3833,6 +3856,7 @@ static bool __pr_flush(struct console *c +@@ -3859,6 +3894,7 @@ static bool __pr_flush(struct console *c if (flags & CON_NBCON) { printk_seq = nbcon_seq_read(c); } else { -+ WARN_ON_ONCE(!locked); ++ WARN_ON_ONCE(!use_console_lock); printk_seq = c->seq; } -@@ -3844,7 +3868,8 @@ static bool __pr_flush(struct console *c +@@ -3870,7 +3906,8 @@ static bool __pr_flush(struct console *c if (diff != last_diff && reset_on_progress) remaining_jiffies = timeout_jiffies; - console_unlock(); -+ if (locked) ++ if (use_console_lock) + console_unlock(); /* Note: @diff is 0 if there are no usable consoles. */ if (diff == 0 || remaining_jiffies == 0) -@@ -3966,7 +3991,11 @@ void defer_console_output(void) - * New messages may have been added directly to the ringbuffer - * using vprintk_store(), so wake any waiters as well. +@@ -3940,6 +3977,7 @@ static void __wake_up_klogd(int val) + return; + + preempt_disable(); ++ + /* + * Guarantee any new records can be seen by tasks preparing to wait + * before this context checks if the wait queue is empty. +@@ -3951,11 +3989,22 @@ static void __wake_up_klogd(int val) + * + * This pairs with devkmsg_read:A and syslog_print:A. */ -- __wake_up_klogd(PRINTK_PENDING_WAKEUP | PRINTK_PENDING_OUTPUT); -+ int val = PRINTK_PENDING_WAKEUP; +- if (wq_has_sleeper(&log_wait) || /* LMM(__wake_up_klogd:A) */ +- (val & PRINTK_PENDING_OUTPUT)) { ++ if (!wq_has_sleeper(&log_wait)) /* LMM(__wake_up_klogd:A) */ ++ val &= ~PRINTK_PENDING_WAKEUP; + -+ if (printing_via_unlock) -+ val |= PRINTK_PENDING_OUTPUT; -+ __wake_up_klogd(val); ++ /* ++ * Simple read is safe. register_console() would flush a newly ++ * registered legacy console when writing the message about it ++ * being enabled. ++ */ ++ if (!printing_via_unlock) ++ val &= ~PRINTK_PENDING_OUTPUT; ++ ++ if (val) { + this_cpu_or(printk_pending, val); + irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); + } ++ + preempt_enable(); } - void printk_trigger_flush(void) diff --git a/debian/patches-rt/0030-printk-Track-nbcon-consoles.patch b/debian/patches-rt/0026-printk-Track-nbcon-consoles.patch index ec363c95d7..7c54a03775 100644 --- a/debian/patches-rt/0030-printk-Track-nbcon-consoles.patch +++ b/debian/patches-rt/0026-printk-Track-nbcon-consoles.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Mon, 11 Dec 2023 09:36:52 +0000 -Subject: [PATCH 30/50] printk: Track nbcon consoles -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 26/48] printk: Track nbcon consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Add a global flag @have_nbcon_console to identify if any nbcon consoles are registered. This will be used in follow-up commits @@ -10,34 +10,32 @@ to preserve legacy behavior when no nbcon consoles are registered. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/printk/printk.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) + kernel/printk/printk.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -471,6 +471,13 @@ static DEFINE_MUTEX(syslog_lock); - bool have_legacy_console; +@@ -471,6 +471,11 @@ static DEFINE_MUTEX(syslog_lock); + static bool have_legacy_console; /* -+ * Specifies if an nbcon console is registered. If nbcon consoles are present, -+ * synchronous printing of legacy consoles will not occur during panic until -+ * the backtrace has been stored to the ringbuffer. ++ * Specifies if an nbcon console is registered. + */ -+bool have_nbcon_console; ++static bool have_nbcon_console; + +/* * Specifies if a boot console is registered. If boot consoles are present, * nbcon consoles cannot print simultaneously and must be synchronized by * the console lock. This is because boot consoles and nbcon consoles may -@@ -3530,6 +3537,7 @@ void register_console(struct console *ne +@@ -3538,6 +3543,7 @@ void register_console(struct console *ne console_init_seq(newcon, bootcon_registered); if (newcon->flags & CON_NBCON) { + have_nbcon_console = true; nbcon_init(newcon); - } else { - have_legacy_console = true; -@@ -3591,6 +3599,7 @@ EXPORT_SYMBOL(register_console); + + /* +@@ -3624,6 +3630,7 @@ EXPORT_SYMBOL(register_console); static int unregister_console_locked(struct console *console) { bool found_legacy_con = false; @@ -45,7 +43,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> bool found_boot_con = false; struct console *c; int res; -@@ -3647,13 +3656,18 @@ static int unregister_console_locked(str +@@ -3680,13 +3687,18 @@ static int unregister_console_locked(str for_each_console(c) { if (c->flags & CON_BOOT) found_boot_con = true; @@ -57,11 +55,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> found_legacy_con = true; } if (!found_boot_con) - have_boot_console = false; + have_boot_console = found_boot_con; if (!found_legacy_con) - have_legacy_console = false; + have_legacy_console = found_legacy_con; + if (!found_nbcon_con) -+ have_nbcon_console = false; ++ have_nbcon_console = found_nbcon_con; return res; } diff --git a/debian/patches-rt/0031-printk-Coordinate-direct-printing-in-panic.patch b/debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch index 6f26bf7fc6..4893dd463f 100644 --- a/debian/patches-rt/0031-printk-Coordinate-direct-printing-in-panic.patch +++ b/debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Wed, 22 Nov 2023 11:56:58 +0000 -Subject: [PATCH 31/50] printk: Coordinate direct printing in panic -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 27/48] printk: Coordinate direct printing in panic +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Perform printing by nbcon consoles on the panic CPU from the printk() caller context in order to get panic messages printed @@ -20,33 +20,57 @@ from the printk() caller context). Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - include/linux/printk.h | 2 + + include/linux/printk.h | 5 +++ kernel/panic.c | 2 + - kernel/printk/printk.c | 53 ++++++++++++++++++++++++++++++++++++++++++------- - 3 files changed, 50 insertions(+), 7 deletions(-) + kernel/printk/printk.c | 62 ++++++++++++++++++++++++++++++++++++++++++------- + 3 files changed, 61 insertions(+), 8 deletions(-) --- a/include/linux/printk.h +++ b/include/linux/printk.h -@@ -782,3 +782,5 @@ static inline void print_hex_dump_debug( - print_hex_dump_debug(prefix_str, prefix_type, 16, 1, buf, len, true) +@@ -195,6 +195,7 @@ void show_regs_print_info(const char *lo + extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; + extern asmlinkage void dump_stack(void) __cold; + void printk_trigger_flush(void); ++void printk_legacy_allow_panic_sync(void); + extern void nbcon_driver_acquire(struct console *con); + extern void nbcon_driver_release(struct console *con); + void nbcon_atomic_flush_unsafe(void); +@@ -278,6 +279,10 @@ static inline void printk_trigger_flush( + { + } - #endif ++static inline void printk_legacy_allow_panic_sync(void) ++{ ++} + -+void printk_legacy_allow_panic_sync(void); + static inline void nbcon_driver_acquire(struct console *con) + { + } --- a/kernel/panic.c +++ b/kernel/panic.c -@@ -370,6 +370,8 @@ void panic(const char *fmt, ...) - */ - atomic_notifier_call_chain(&panic_notifier_list, 0, buf); +@@ -364,6 +364,8 @@ void panic(const char *fmt, ...) + + panic_other_cpus_shutdown(_crash_kexec_post_notifiers); + printk_legacy_allow_panic_sync(); + - panic_print_sys_info(false); - - kmsg_dump(KMSG_DUMP_PANIC); + /* + * Run any panic handlers, including those that might need to + * add information to the kmsg dump output. --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -2329,12 +2329,23 @@ int vprintk_store(int facility, int leve +@@ -471,7 +471,9 @@ static DEFINE_MUTEX(syslog_lock); + static bool have_legacy_console; + + /* +- * Specifies if an nbcon console is registered. ++ * Specifies if an nbcon console is registered. If nbcon consoles are present, ++ * synchronous printing of legacy consoles will not occur during panic until ++ * the backtrace has been stored to the ringbuffer. + */ + static bool have_nbcon_console; + +@@ -2335,12 +2337,29 @@ int vprintk_store(int facility, int leve return ret; } @@ -54,11 +78,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + +/* + * This acts as a one-way switch to allow legacy consoles to print from -+ * the printk() caller context on a panic CPU. ++ * the printk() caller context on a panic CPU. It also attempts to flush ++ * the legacy consoles in this context. + */ +void printk_legacy_allow_panic_sync(void) +{ + legacy_allow_panic_sync = true; ++ ++ if (printing_via_unlock && !in_nmi()) { ++ if (console_trylock()) ++ console_unlock(); ++ } +} + asmlinkage int vprintk_emit(int facility, int level, @@ -71,7 +101,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Suppress unimportant messages after panic happens */ if (unlikely(suppress_printk)) -@@ -2350,15 +2361,43 @@ asmlinkage int vprintk_emit(int facility +@@ -2356,15 +2375,42 @@ asmlinkage int vprintk_emit(int facility if (level == LOGLEVEL_SCHED) { level = LOGLEVEL_DEFAULT; @@ -86,7 +116,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> - /* If called from the scheduler, we can not call up(). */ - if (!in_sched && printing_via_unlock) { -+ if (!have_boot_console && have_nbcon_console) { ++ if (have_nbcon_console && !have_boot_console) { + bool is_panic_context = this_cpu_in_panic(); + + /* @@ -105,20 +135,19 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + * + * - When this CPU is in panic. + * -+ * Note that if boot consoles are registered, the -+ * console_lock/console_unlock dance must be relied upon -+ * instead because nbcon consoles cannot print simultaneously -+ * with boot consoles. ++ * Note that if boot consoles are registered, the console ++ * lock/unlock dance must be relied upon instead because nbcon ++ * consoles cannot print simultaneously with boot consoles. + */ + if (is_panic_context) -+ nbcon_atomic_flush_all(); ++ nbcon_atomic_flush_pending(); + } + + if (do_trylock_unlock) { /* * The caller may be holding system-critical or * timing-sensitive locks. Disable preemption during -@@ -2378,10 +2417,10 @@ asmlinkage int vprintk_emit(int facility +@@ -2384,10 +2430,10 @@ asmlinkage int vprintk_emit(int facility preempt_enable(); } diff --git a/debian/patches-rt/0027-printk-nbcon-Assign-priority-based-on-CPU-state.patch b/debian/patches-rt/0027-printk-nbcon-Assign-priority-based-on-CPU-state.patch deleted file mode 100644 index 0c7282fce7..0000000000 --- a/debian/patches-rt/0027-printk-nbcon-Assign-priority-based-on-CPU-state.patch +++ /dev/null @@ -1,113 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Thu, 14 Dec 2023 14:38:42 +0000 -Subject: [PATCH 27/50] printk: nbcon: Assign priority based on CPU state -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Use the current state of the CPU to determine which priority to -assign to the printing context. - -Note: The uart_port wrapper, which is responsible for non-console- - printing activities, will always use NORMAL priority. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/printk/internal.h | 2 ++ - kernel/printk/nbcon.c | 30 ++++++++++++++++++++++++++++-- - 2 files changed, 30 insertions(+), 2 deletions(-) - ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -79,6 +79,7 @@ void nbcon_seq_force(struct console *con - bool nbcon_alloc(struct console *con); - void nbcon_init(struct console *con); - void nbcon_free(struct console *con); -+enum nbcon_prio nbcon_get_default_prio(void); - void nbcon_atomic_flush_all(void); - bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, int cookie); - -@@ -135,6 +136,7 @@ static inline void nbcon_seq_force(struc - static inline bool nbcon_alloc(struct console *con) { return false; } - static inline void nbcon_init(struct console *con) { } - static inline void nbcon_free(struct console *con) { } -+static inline enum nbcon_prio nbcon_get_default_prio(void) { return NBCON_PRIO_NONE; } - static inline void nbcon_atomic_flush_all(void) { } - static inline bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, - int cookie) { return false; } ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -962,6 +962,22 @@ static bool nbcon_atomic_emit_one(struct - } - - /** -+ * nbcon_get_default_prio - The appropriate nbcon priority to use for nbcon -+ * printing on the current CPU -+ * -+ * Context: Any context which could not be migrated to another CPU. -+ * Return: The nbcon_prio to use for acquiring an nbcon console in this -+ * context for printing. -+ */ -+enum nbcon_prio nbcon_get_default_prio(void) -+{ -+ if (this_cpu_in_panic()) -+ return NBCON_PRIO_PANIC; -+ -+ return NBCON_PRIO_NORMAL; -+} -+ -+/** - * nbcon_atomic_emit_next_record - Print one record for an nbcon console - * using the write_atomic() callback - * @con: The console to print on -@@ -997,7 +1013,7 @@ bool nbcon_atomic_emit_next_record(struc - cant_migrate(); - - ctxt->console = con; -- ctxt->prio = NBCON_PRIO_NORMAL; -+ ctxt->prio = nbcon_get_default_prio(); - - progress = nbcon_atomic_emit_one(&wctxt); - -@@ -1043,7 +1059,6 @@ static void __nbcon_atomic_flush_all(u64 - memset(ctxt, 0, sizeof(*ctxt)); - ctxt->console = con; - ctxt->spinwait_max_us = 2000; -- ctxt->prio = NBCON_PRIO_NORMAL; - - /* - * Atomic flushing does not use console driver -@@ -1052,9 +1067,14 @@ static void __nbcon_atomic_flush_all(u64 - * disabled to avoid being interrupted and then - * calling into a driver that will deadlock trying - * acquire console ownership. -+ * -+ * This also disables migration in order to get the -+ * current CPU priority. - */ - local_irq_save(irq_flags); - -+ ctxt->prio = nbcon_get_default_prio(); -+ - any_progress |= nbcon_atomic_emit_one(&wctxt); - - local_irq_restore(irq_flags); -@@ -1166,6 +1186,9 @@ static inline bool uart_is_nbcon(struct - * - * If @up is an nbcon console, this console will be acquired and marked as - * unsafe. Otherwise this function does nothing. -+ * -+ * nbcon consoles acquired via the port lock wrapper always use priority -+ * NBCON_PRIO_NORMAL. - */ - void nbcon_acquire(struct uart_port *up) - { -@@ -1200,6 +1223,9 @@ EXPORT_SYMBOL_GPL(nbcon_acquire); - * - * If @up is an nbcon console, the console will be marked as safe and - * released. Otherwise this function does nothing. -+ * -+ * nbcon consoles acquired via the port lock wrapper always use priority -+ * NBCON_PRIO_NORMAL. - */ - void nbcon_release(struct uart_port *up) - { diff --git a/debian/patches-rt/0028-printk-nbcon-Add-unsafe-flushing-on-panic.patch b/debian/patches-rt/0028-printk-nbcon-Add-unsafe-flushing-on-panic.patch deleted file mode 100644 index 2bb67b473b..0000000000 --- a/debian/patches-rt/0028-printk-nbcon-Add-unsafe-flushing-on-panic.patch +++ /dev/null @@ -1,96 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Fri, 20 Oct 2023 10:03:42 +0000 -Subject: [PATCH 28/50] printk: nbcon: Add unsafe flushing on panic -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Add nbcon_atomic_flush_unsafe() to flush all nbcon consoles -using the write_atomic() callback and allowing unsafe hostile -takeovers. Call this at the end of panic() as a final attempt -to flush any pending messages. - -Note that legacy consoles use unsafe methods for flushing -from the beginning of panic (see bust_spinlocks()). Therefore, -systems using both legacy and nbcon consoles may still fail to -see panic messages due to unsafe legacy console usage. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/printk.h | 5 +++++ - kernel/panic.c | 1 + - kernel/printk/nbcon.c | 18 ++++++++++++++++-- - 3 files changed, 22 insertions(+), 2 deletions(-) - ---- a/include/linux/printk.h -+++ b/include/linux/printk.h -@@ -199,6 +199,7 @@ extern asmlinkage void dump_stack(void) - void printk_trigger_flush(void); - extern void nbcon_acquire(struct uart_port *up); - extern void nbcon_release(struct uart_port *up); -+void nbcon_atomic_flush_unsafe(void); - #else - static inline __printf(1, 0) - int vprintk(const char *s, va_list args) -@@ -287,6 +288,10 @@ static inline void nbcon_release(struct - { - } - -+static inline void nbcon_atomic_flush_unsafe(void) -+{ -+} -+ - #endif - - #ifdef CONFIG_SMP ---- a/kernel/panic.c -+++ b/kernel/panic.c -@@ -453,6 +453,7 @@ void panic(const char *fmt, ...) - * Explicitly flush the kernel log buffer one last time. - */ - console_flush_on_panic(CONSOLE_FLUSH_PENDING); -+ nbcon_atomic_flush_unsafe(); - - local_irq_enable(); - for (i = 0; ; i += PANIC_TIMER_STEP) { ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -1030,8 +1030,9 @@ bool nbcon_atomic_emit_next_record(struc - * __nbcon_atomic_flush_all - Flush all nbcon consoles using their - * write_atomic() callback - * @stop_seq: Flush up until this record -+ * @allow_unsafe_takeover: True, to allow unsafe hostile takeovers - */ --static void __nbcon_atomic_flush_all(u64 stop_seq) -+static void __nbcon_atomic_flush_all(u64 stop_seq, bool allow_unsafe_takeover) - { - struct nbcon_write_context wctxt = { }; - struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); -@@ -1059,6 +1060,7 @@ static void __nbcon_atomic_flush_all(u64 - memset(ctxt, 0, sizeof(*ctxt)); - ctxt->console = con; - ctxt->spinwait_max_us = 2000; -+ ctxt->allow_unsafe_takeover = allow_unsafe_takeover; - - /* - * Atomic flushing does not use console driver -@@ -1093,7 +1095,19 @@ static void __nbcon_atomic_flush_all(u64 - */ - void nbcon_atomic_flush_all(void) - { -- __nbcon_atomic_flush_all(prb_next_reserve_seq(prb)); -+ __nbcon_atomic_flush_all(prb_next_reserve_seq(prb), false); -+} -+ -+/** -+ * nbcon_atomic_flush_unsafe - Flush all nbcon consoles using their -+ * write_atomic() callback and allowing unsafe hostile takeovers -+ * -+ * Flush the backlog up through the currently newest record. Unsafe hostile -+ * takeovers will be performed, if necessary. -+ */ -+void nbcon_atomic_flush_unsafe(void) -+{ -+ __nbcon_atomic_flush_all(prb_next_reserve_seq(prb), true); - } - - /** diff --git a/debian/patches-rt/0032-printk-nbcon-Implement-emergency-sections.patch b/debian/patches-rt/0028-printk-nbcon-Implement-emergency-sections.patch index 29f5098811..f3a05868e7 100644 --- a/debian/patches-rt/0032-printk-nbcon-Implement-emergency-sections.patch +++ b/debian/patches-rt/0028-printk-nbcon-Implement-emergency-sections.patch @@ -1,7 +1,7 @@ From: Thomas Gleixner <tglx@linutronix.de> Date: Mon, 11 Sep 2023 15:21:57 +0000 -Subject: [PATCH 32/50] printk: nbcon: Implement emergency sections -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 28/48] printk: nbcon: Implement emergency sections +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz In emergency situations (something has gone wrong but the system continues to operate), usually important information @@ -13,8 +13,8 @@ developers and users. In order to help ensure that the collection of printk messages in an emergency situation are all stored to the ringbuffer as quickly as possible, disable console output for that CPU while -it is in the emergency situation. When exiting the emergency -situation, trigger the consoles to be flushed. +it is in the emergency situation. The consoles need to be +flushed when exiting the emergency situation. Add per-CPU emergency nesting tracking because an emergency can arise while in an emergency situation. @@ -24,7 +24,10 @@ sections where the urgent messages are generated. Do not print if the current CPU is in an emergency state. -Trigger console flushing when exiting all emergency nesting. +When exiting all emergency nesting, flush nbcon consoles +directly using their atomic callback. Legacy consoles are +triggered for flushing via irq_work because it is not known +if the context was safe for a trylock on the console lock. Note that the emergency state is not system-wide. While one CPU is in an emergency state, another CPU may continue to print @@ -36,14 +39,13 @@ Signed-off-by: Thomas Gleixner (Intel) <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- include/linux/console.h | 4 ++ - include/linux/printk.h | 7 ++-- - kernel/printk/nbcon.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ - kernel/printk/printk.c | 25 +++++++++++--- - 4 files changed, 109 insertions(+), 8 deletions(-) + kernel/printk/nbcon.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ + kernel/printk/printk.c | 13 ++++++- + 3 files changed, 98 insertions(+), 2 deletions(-) --- a/include/linux/console.h +++ b/include/linux/console.h -@@ -465,10 +465,14 @@ static inline bool console_is_registered +@@ -559,10 +559,14 @@ static inline bool console_is_registered hlist_for_each_entry(con, &console_list, node) #ifdef CONFIG_PRINTK @@ -58,36 +60,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static inline bool nbcon_can_proceed(struct nbcon_write_context *wctxt) { return false; } static inline bool nbcon_enter_unsafe(struct nbcon_write_context *wctxt) { return false; } static inline bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt) { return false; } ---- a/include/linux/printk.h -+++ b/include/linux/printk.h -@@ -197,6 +197,7 @@ void show_regs_print_info(const char *lo - extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; - extern asmlinkage void dump_stack(void) __cold; - void printk_trigger_flush(void); -+void printk_legacy_allow_panic_sync(void); - extern void nbcon_acquire(struct uart_port *up); - extern void nbcon_release(struct uart_port *up); - void nbcon_atomic_flush_unsafe(void); -@@ -280,6 +281,10 @@ static inline void printk_trigger_flush( - { - } - -+static inline void printk_legacy_allow_panic_sync(void) -+{ -+} -+ - static inline void nbcon_acquire(struct uart_port *up) - { - } -@@ -782,5 +787,3 @@ static inline void print_hex_dump_debug( - print_hex_dump_debug(prefix_str, prefix_type, 16, 1, buf, len, true) - - #endif -- --void printk_legacy_allow_panic_sync(void); --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -929,6 +929,29 @@ static bool nbcon_emit_next_record(struc +@@ -936,6 +936,29 @@ static bool nbcon_emit_next_record(struc return nbcon_context_exit_unsafe(ctxt); } @@ -117,7 +92,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** * nbcon_atomic_emit_one - Print one record for an nbcon console using the * write_atomic() callback -@@ -971,9 +994,15 @@ static bool nbcon_atomic_emit_one(struct +@@ -977,9 +1000,15 @@ static bool nbcon_atomic_emit_one(struct */ enum nbcon_prio nbcon_get_default_prio(void) { @@ -133,7 +108,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return NBCON_PRIO_NORMAL; } -@@ -1111,6 +1140,58 @@ void nbcon_atomic_flush_unsafe(void) +@@ -1147,6 +1176,60 @@ void nbcon_atomic_flush_unsafe(void) } /** @@ -176,8 +151,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + + WARN_ON_ONCE(*cpu_emergency_nesting == 0); + -+ if (*cpu_emergency_nesting == 1) ++ if (*cpu_emergency_nesting == 1) { ++ nbcon_atomic_flush_pending(); + do_trigger_flush = true; ++ } + + /* Undo the nesting count of nbcon_cpu_emergency_enter(). */ + (*cpu_emergency_nesting)--; @@ -194,7 +171,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -2404,16 +2404,29 @@ asmlinkage int vprintk_emit(int facility +@@ -2417,16 +2417,25 @@ asmlinkage int vprintk_emit(int facility * printing of all remaining records to all consoles so that * this context can return as soon as possible. Hopefully * another printk() caller will take over the printing. @@ -204,25 +181,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> preempt_disable(); + /* -- * Try to acquire and then immediately release the console -- * semaphore. The release will print out buffers. With the -- * spinning variant, this context tries to take over the -- * printing from another printing context. -+ * Do not emit for EMERGENCY priority. The console will be + * Try to acquire and then immediately release the console + * semaphore. The release will print out buffers. With the + * spinning variant, this context tries to take over the + * printing from another printing context. ++ * ++ * Skip it in EMERGENCY priority. The console will be + * explicitly flushed when exiting the emergency section. */ - if (console_trylock_spinning()) - console_unlock(); -+ if (nbcon_get_default_prio() == NBCON_PRIO_EMERGENCY) { -+ do_trylock_unlock = false; -+ } else { -+ /* -+ * Try to acquire and then immediately release the -+ * console semaphore. The release will print out -+ * buffers. With the spinning variant, this context -+ * tries to take over the printing from another -+ * printing context. -+ */ ++ if (nbcon_get_default_prio() != NBCON_PRIO_EMERGENCY) { + if (console_trylock_spinning()) + console_unlock(); + } diff --git a/debian/patches-rt/0033-panic-Mark-emergency-section-in-warn.patch b/debian/patches-rt/0029-panic-Mark-emergency-section-in-warn.patch index c3058599cf..35c04773c5 100644 --- a/debian/patches-rt/0033-panic-Mark-emergency-section-in-warn.patch +++ b/debian/patches-rt/0029-panic-Mark-emergency-section-in-warn.patch @@ -1,11 +1,11 @@ From: Thomas Gleixner <tglx@linutronix.de> Date: Mon, 11 Sep 2023 15:53:04 +0000 -Subject: [PATCH 33/50] panic: Mark emergency section in warn -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 29/48] panic: Mark emergency section in warn +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Mark the full contents of __warn() as an emergency section. In this section, the CPU will not perform console output for the -printk() calls. Instead, a flushing of the console output will +printk() calls. Instead, a flushing of the console output is triggered when exiting the emergency section. Co-developed-by: John Ogness <john.ogness@linutronix.de> diff --git a/debian/patches-rt/0034-panic-Mark-emergency-section-in-oops.patch b/debian/patches-rt/0030-panic-Mark-emergency-section-in-oops.patch index d4ca13f249..cd3d80fe60 100644 --- a/debian/patches-rt/0034-panic-Mark-emergency-section-in-oops.patch +++ b/debian/patches-rt/0030-panic-Mark-emergency-section-in-oops.patch @@ -1,12 +1,12 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 19 Sep 2023 17:07:34 +0000 -Subject: [PATCH 34/50] panic: Mark emergency section in oops -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 30/48] panic: Mark emergency section in oops +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Mark an emergency section beginning with oops_enter() until the end of oops_exit(). In this section, the CPU will not perform console output for the printk() calls. Instead, a flushing of the -console output will triggered when exiting the emergency section. +console output is triggered when exiting the emergency section. The very end of oops_exit() performs a kmsg_dump(). This is not included in the emergency section because it is another diff --git a/debian/patches-rt/0031-rcu-Mark-emergency-sections-in-rcu-stalls.patch b/debian/patches-rt/0031-rcu-Mark-emergency-sections-in-rcu-stalls.patch new file mode 100644 index 0000000000..0cca134a21 --- /dev/null +++ b/debian/patches-rt/0031-rcu-Mark-emergency-sections-in-rcu-stalls.patch @@ -0,0 +1,96 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Mon, 11 Sep 2023 15:53:39 +0000 +Subject: [PATCH 31/48] rcu: Mark emergency sections in rcu stalls +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Mark emergency sections wherever multiple lines of +rcu stall information are generated. In an emergency +section the CPU will not perform console output for the +printk() calls. Instead, a flushing of the console +output is triggered when exiting the emergency section. +This allows the full message block to be stored as +quickly as possible in the ringbuffer. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/rcu/tree_exp.h | 7 +++++++ + kernel/rcu/tree_stall.h | 9 +++++++++ + 2 files changed, 16 insertions(+) + +--- a/kernel/rcu/tree_exp.h ++++ b/kernel/rcu/tree_exp.h +@@ -7,6 +7,7 @@ + * Authors: Paul E. McKenney <paulmck@linux.ibm.com> + */ + ++#include <linux/console.h> + #include <linux/lockdep.h> + + static void rcu_exp_handler(void *unused); +@@ -636,6 +637,9 @@ static void synchronize_rcu_expedited_wa + return; + if (rcu_stall_is_suppressed()) + continue; ++ ++ nbcon_cpu_emergency_enter(); ++ + j = jiffies; + rcu_stall_notifier_call_chain(RCU_STALL_NOTIFY_EXP, (void *)(j - jiffies_start)); + trace_rcu_stall_warning(rcu_state.name, TPS("ExpeditedStall")); +@@ -689,6 +693,9 @@ static void synchronize_rcu_expedited_wa + rcu_exp_print_detail_task_stall_rnp(rnp); + } + jiffies_stall = 3 * rcu_exp_jiffies_till_stall_check() + 3; ++ ++ nbcon_cpu_emergency_exit(); ++ + panic_on_rcu_stall(); + } + } +--- a/kernel/rcu/tree_stall.h ++++ b/kernel/rcu/tree_stall.h +@@ -7,6 +7,7 @@ + * Author: Paul E. McKenney <paulmck@linux.ibm.com> + */ + ++#include <linux/console.h> + #include <linux/kvm_para.h> + #include <linux/rcu_notifier.h> + +@@ -604,6 +605,8 @@ static void print_other_cpu_stall(unsign + if (rcu_stall_is_suppressed()) + return; + ++ nbcon_cpu_emergency_enter(); ++ + /* + * OK, time to rat on our buddy... + * See Documentation/RCU/stallwarn.rst for info on how to debug +@@ -655,6 +658,8 @@ static void print_other_cpu_stall(unsign + rcu_check_gp_kthread_expired_fqs_timer(); + rcu_check_gp_kthread_starvation(); + ++ nbcon_cpu_emergency_exit(); ++ + panic_on_rcu_stall(); + + rcu_force_quiescent_state(); /* Kick them all. */ +@@ -675,6 +680,8 @@ static void print_cpu_stall(unsigned lon + if (rcu_stall_is_suppressed()) + return; + ++ nbcon_cpu_emergency_enter(); ++ + /* + * OK, time to rat on ourselves... + * See Documentation/RCU/stallwarn.rst for info on how to debug +@@ -703,6 +710,8 @@ static void print_cpu_stall(unsigned lon + jiffies + 3 * rcu_jiffies_till_stall_check() + 3); + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); + ++ nbcon_cpu_emergency_exit(); ++ + panic_on_rcu_stall(); + + /* diff --git a/debian/patches-rt/0032-lockdep-Mark-emergency-sections-in-lockdep-splats.patch b/debian/patches-rt/0032-lockdep-Mark-emergency-sections-in-lockdep-splats.patch new file mode 100644 index 0000000000..64cf39b672 --- /dev/null +++ b/debian/patches-rt/0032-lockdep-Mark-emergency-sections-in-lockdep-splats.patch @@ -0,0 +1,487 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Mon, 18 Sep 2023 20:27:41 +0000 +Subject: [PATCH 32/48] lockdep: Mark emergency sections in lockdep splats +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Mark emergency sections wherever multiple lines of +lock debugging output are generated. In an emergency +section the CPU will not perform console output for the +printk() calls. Instead, a flushing of the console +output is triggered when exiting the emergency section. +This allows the full message block to be stored as +quickly as possible in the ringbuffer. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/locking/lockdep.c | 91 +++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 88 insertions(+), 3 deletions(-) + +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -56,6 +56,7 @@ + #include <linux/kprobes.h> + #include <linux/lockdep.h> + #include <linux/context_tracking.h> ++#include <linux/console.h> + + #include <asm/sections.h> + +@@ -574,8 +575,10 @@ static struct lock_trace *save_trace(voi + if (!debug_locks_off_graph_unlock()) + return NULL; + ++ nbcon_cpu_emergency_enter(); + print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + + return NULL; + } +@@ -782,6 +785,8 @@ static void lockdep_print_held_locks(str + { + int i, depth = READ_ONCE(p->lockdep_depth); + ++ nbcon_cpu_emergency_enter(); ++ + if (!depth) + printk("no locks held by %s/%d.\n", p->comm, task_pid_nr(p)); + else +@@ -792,11 +797,13 @@ static void lockdep_print_held_locks(str + * and it's not the current task. + */ + if (p != current && task_is_running(p)) +- return; ++ goto out; + for (i = 0; i < depth; i++) { + printk(" #%d: ", i); + print_lock(p->held_locks + i); + } ++out: ++ nbcon_cpu_emergency_exit(); + } + + static void print_kernel_ident(void) +@@ -888,11 +895,13 @@ look_up_lock_class(const struct lockdep_ + if (unlikely(subclass >= MAX_LOCKDEP_SUBCLASSES)) { + instrumentation_begin(); + debug_locks_off(); ++ nbcon_cpu_emergency_enter(); + printk(KERN_ERR + "BUG: looking up invalid subclass: %u\n", subclass); + printk(KERN_ERR + "turning off the locking correctness validator.\n"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + instrumentation_end(); + return NULL; + } +@@ -969,11 +978,13 @@ static bool assign_lock_key(struct lockd + else { + /* Debug-check: all keys must be persistent! */ + debug_locks_off(); ++ nbcon_cpu_emergency_enter(); + pr_err("INFO: trying to register non-static key.\n"); + pr_err("The code is fine but needs lockdep annotation, or maybe\n"); + pr_err("you didn't initialize this object before use?\n"); + pr_err("turning off the locking correctness validator.\n"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + return false; + } + +@@ -1317,8 +1328,10 @@ register_lock_class(struct lockdep_map * + return NULL; + } + ++ nbcon_cpu_emergency_enter(); + print_lockdep_off("BUG: MAX_LOCKDEP_KEYS too low!"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + return NULL; + } + nr_lock_classes++; +@@ -1350,11 +1363,13 @@ register_lock_class(struct lockdep_map * + if (verbose(class)) { + graph_unlock(); + ++ nbcon_cpu_emergency_enter(); + printk("\nnew class %px: %s", class->key, class->name); + if (class->name_version > 1) + printk(KERN_CONT "#%d", class->name_version); + printk(KERN_CONT "\n"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + + if (!graph_lock()) { + return NULL; +@@ -1393,8 +1408,10 @@ static struct lock_list *alloc_list_entr + if (!debug_locks_off_graph_unlock()) + return NULL; + ++ nbcon_cpu_emergency_enter(); + print_lockdep_off("BUG: MAX_LOCKDEP_ENTRIES too low!"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + return NULL; + } + nr_list_entries++; +@@ -2040,6 +2057,8 @@ static noinline void print_circular_bug( + + depth = get_lock_depth(target); + ++ nbcon_cpu_emergency_enter(); ++ + print_circular_bug_header(target, depth, check_src, check_tgt); + + parent = get_lock_parent(target); +@@ -2058,6 +2077,8 @@ static noinline void print_circular_bug( + + printk("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + static noinline void print_bfs_bug(int ret) +@@ -2570,6 +2591,8 @@ print_bad_irq_dependency(struct task_str + if (!debug_locks_off_graph_unlock() || debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("=====================================================\n"); + pr_warn("WARNING: %s-safe -> %s-unsafe lock order detected\n", +@@ -2619,11 +2642,13 @@ print_bad_irq_dependency(struct task_str + pr_warn(" and %s-irq-unsafe lock:\n", irqclass); + next_root->trace = save_trace(); + if (!next_root->trace) +- return; ++ goto out; + print_shortest_lock_dependencies(forwards_entry, next_root); + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++out: ++ nbcon_cpu_emergency_exit(); + } + + static const char *state_names[] = { +@@ -2988,6 +3013,8 @@ print_deadlock_bug(struct task_struct *c + if (!debug_locks_off_graph_unlock() || debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("============================================\n"); + pr_warn("WARNING: possible recursive locking detected\n"); +@@ -3010,6 +3037,8 @@ print_deadlock_bug(struct task_struct *c + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + /* +@@ -3607,6 +3636,8 @@ static void print_collision(struct task_ + struct held_lock *hlock_next, + struct lock_chain *chain) + { ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("============================\n"); + pr_warn("WARNING: chain_key collision\n"); +@@ -3623,6 +3654,8 @@ static void print_collision(struct task_ + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + #endif + +@@ -3713,8 +3746,10 @@ static inline int add_chain_cache(struct + if (!debug_locks_off_graph_unlock()) + return 0; + ++ nbcon_cpu_emergency_enter(); + print_lockdep_off("BUG: MAX_LOCKDEP_CHAINS too low!"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + return 0; + } + chain->chain_key = chain_key; +@@ -3731,8 +3766,10 @@ static inline int add_chain_cache(struct + if (!debug_locks_off_graph_unlock()) + return 0; + ++ nbcon_cpu_emergency_enter(); + print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + return 0; + } + +@@ -3971,6 +4008,8 @@ print_usage_bug(struct task_struct *curr + if (!debug_locks_off() || debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("================================\n"); + pr_warn("WARNING: inconsistent lock state\n"); +@@ -3999,6 +4038,8 @@ print_usage_bug(struct task_struct *curr + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + /* +@@ -4033,6 +4074,8 @@ print_irq_inversion_bug(struct task_stru + if (!debug_locks_off_graph_unlock() || debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("========================================================\n"); + pr_warn("WARNING: possible irq lock inversion dependency detected\n"); +@@ -4073,11 +4116,13 @@ print_irq_inversion_bug(struct task_stru + pr_warn("\nthe shortest dependencies between 2nd lock and 1st lock:\n"); + root->trace = save_trace(); + if (!root->trace) +- return; ++ goto out; + print_shortest_lock_dependencies(other, root); + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++out: ++ nbcon_cpu_emergency_exit(); + } + + /* +@@ -4154,6 +4199,8 @@ void print_irqtrace_events(struct task_s + { + const struct irqtrace_events *trace = &curr->irqtrace; + ++ nbcon_cpu_emergency_enter(); ++ + printk("irq event stamp: %u\n", trace->irq_events); + printk("hardirqs last enabled at (%u): [<%px>] %pS\n", + trace->hardirq_enable_event, (void *)trace->hardirq_enable_ip, +@@ -4167,6 +4214,8 @@ void print_irqtrace_events(struct task_s + printk("softirqs last disabled at (%u): [<%px>] %pS\n", + trace->softirq_disable_event, (void *)trace->softirq_disable_ip, + (void *)trace->softirq_disable_ip); ++ ++ nbcon_cpu_emergency_exit(); + } + + static int HARDIRQ_verbose(struct lock_class *class) +@@ -4687,10 +4736,12 @@ static int mark_lock(struct task_struct + * We must printk outside of the graph_lock: + */ + if (ret == 2) { ++ nbcon_cpu_emergency_enter(); + printk("\nmarked lock as {%s}:\n", usage_str[new_bit]); + print_lock(this); + print_irqtrace_events(curr); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + } + + return ret; +@@ -4731,6 +4782,8 @@ print_lock_invalid_wait_context(struct t + if (debug_locks_silent) + return 0; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("=============================\n"); + pr_warn("[ BUG: Invalid wait context ]\n"); +@@ -4750,6 +4803,8 @@ print_lock_invalid_wait_context(struct t + pr_warn("stack backtrace:\n"); + dump_stack(); + ++ nbcon_cpu_emergency_exit(); ++ + return 0; + } + +@@ -4954,6 +5009,8 @@ print_lock_nested_lock_not_held(struct t + if (debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("==================================\n"); + pr_warn("WARNING: Nested lock was not taken\n"); +@@ -4974,6 +5031,8 @@ print_lock_nested_lock_not_held(struct t + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + static int __lock_is_held(const struct lockdep_map *lock, int read); +@@ -5019,11 +5078,13 @@ static int __lock_acquire(struct lockdep + debug_class_ops_inc(class); + + if (very_verbose(class)) { ++ nbcon_cpu_emergency_enter(); + printk("\nacquire class [%px] %s", class->key, class->name); + if (class->name_version > 1) + printk(KERN_CONT "#%d", class->name_version); + printk(KERN_CONT "\n"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + } + + /* +@@ -5150,6 +5211,7 @@ static int __lock_acquire(struct lockdep + #endif + if (unlikely(curr->lockdep_depth >= MAX_LOCK_DEPTH)) { + debug_locks_off(); ++ nbcon_cpu_emergency_enter(); + print_lockdep_off("BUG: MAX_LOCK_DEPTH too low!"); + printk(KERN_DEBUG "depth: %i max: %lu!\n", + curr->lockdep_depth, MAX_LOCK_DEPTH); +@@ -5157,6 +5219,7 @@ static int __lock_acquire(struct lockdep + lockdep_print_held_locks(current); + debug_show_all_locks(); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + + return 0; + } +@@ -5176,6 +5239,8 @@ static void print_unlock_imbalance_bug(s + if (debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("=====================================\n"); + pr_warn("WARNING: bad unlock balance detected!\n"); +@@ -5192,6 +5257,8 @@ static void print_unlock_imbalance_bug(s + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + static noinstr int match_held_lock(const struct held_lock *hlock, +@@ -5895,6 +5962,8 @@ static void print_lock_contention_bug(st + if (debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("=================================\n"); + pr_warn("WARNING: bad contention detected!\n"); +@@ -5911,6 +5980,8 @@ static void print_lock_contention_bug(st + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + static void +@@ -6524,6 +6595,8 @@ print_freed_lock_bug(struct task_struct + if (debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("=========================\n"); + pr_warn("WARNING: held lock freed!\n"); +@@ -6536,6 +6609,8 @@ print_freed_lock_bug(struct task_struct + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + static inline int not_in_range(const void* mem_from, unsigned long mem_len, +@@ -6582,6 +6657,8 @@ static void print_held_locks_bug(void) + if (debug_locks_silent) + return; + ++ nbcon_cpu_emergency_enter(); ++ + pr_warn("\n"); + pr_warn("====================================\n"); + pr_warn("WARNING: %s/%d still has locks held!\n", +@@ -6591,6 +6668,8 @@ static void print_held_locks_bug(void) + lockdep_print_held_locks(current); + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + void debug_check_no_locks_held(void) +@@ -6609,6 +6688,7 @@ void debug_show_all_locks(void) + pr_warn("INFO: lockdep is turned off.\n"); + return; + } ++ nbcon_cpu_emergency_enter(); + pr_warn("\nShowing all locks held in the system:\n"); + + rcu_read_lock(); +@@ -6623,6 +6703,7 @@ void debug_show_all_locks(void) + + pr_warn("\n"); + pr_warn("=============================================\n\n"); ++ nbcon_cpu_emergency_exit(); + } + EXPORT_SYMBOL_GPL(debug_show_all_locks); + #endif +@@ -6648,6 +6729,7 @@ asmlinkage __visible void lockdep_sys_ex + if (unlikely(curr->lockdep_depth)) { + if (!debug_locks_off()) + return; ++ nbcon_cpu_emergency_enter(); + pr_warn("\n"); + pr_warn("================================================\n"); + pr_warn("WARNING: lock held when returning to user space!\n"); +@@ -6656,6 +6738,7 @@ asmlinkage __visible void lockdep_sys_ex + pr_warn("%s/%d is leaving the kernel with locks still held!\n", + curr->comm, curr->pid); + lockdep_print_held_locks(curr); ++ nbcon_cpu_emergency_exit(); + } + + /* +@@ -6672,6 +6755,7 @@ void lockdep_rcu_suspicious(const char * + bool rcu = warn_rcu_enter(); + + /* Note: the following can be executed concurrently, so be careful. */ ++ nbcon_cpu_emergency_enter(); + pr_warn("\n"); + pr_warn("=============================\n"); + pr_warn("WARNING: suspicious RCU usage\n"); +@@ -6710,6 +6794,7 @@ void lockdep_rcu_suspicious(const char * + lockdep_print_held_locks(curr); + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ nbcon_cpu_emergency_exit(); + warn_rcu_exit(rcu); + } + EXPORT_SYMBOL_GPL(lockdep_rcu_suspicious); diff --git a/debian/patches-rt/0037-printk-nbcon-Introduce-printing-kthreads.patch b/debian/patches-rt/0033-printk-nbcon-Introduce-printing-kthreads.patch index 712f144bee..12f69b52fc 100644 --- a/debian/patches-rt/0037-printk-nbcon-Introduce-printing-kthreads.patch +++ b/debian/patches-rt/0033-printk-nbcon-Introduce-printing-kthreads.patch @@ -1,25 +1,21 @@ From: Thomas Gleixner <tglx@linutronix.de> Date: Fri, 22 Sep 2023 14:12:21 +0000 -Subject: [PATCH 37/50] printk: nbcon: Introduce printing kthreads -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 33/48] printk: nbcon: Introduce printing kthreads +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Provide the main implementation for running a printer kthread per nbcon console that is takeover/handover aware. -The main print function nbcon_emit_next_record() will generate -a warning if a task other than the dedicated printer thread -tries to print using write_thread(). - Co-developed-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Thomas Gleixner (Intel) <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - include/linux/console.h | 8 ++ - kernel/printk/internal.h | 25 ++++++ - kernel/printk/nbcon.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++- - kernel/printk/printk.c | 31 +++++++ - 4 files changed, 249 insertions(+), 3 deletions(-) + include/linux/console.h | 26 ++++++ + kernel/printk/internal.h | 28 +++++++ + kernel/printk/nbcon.c | 187 +++++++++++++++++++++++++++++++++++++++++++++-- + kernel/printk/printk.c | 33 ++++++++ + 4 files changed, 269 insertions(+), 5 deletions(-) --- a/include/linux/console.h +++ b/include/linux/console.h @@ -31,34 +27,47 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include <linux/types.h> struct vc_data; -@@ -303,12 +304,15 @@ struct nbcon_write_context { - * @node: hlist node for the console list - * - * @write_atomic: Write callback for atomic context -+ * @write_thread: Write callback for non-atomic context - * @driver_enter: Callback to begin synchronization with driver code - * @driver_exit: Callback to finish synchronization with driver code +@@ -324,6 +325,8 @@ struct nbcon_drvdata { * @nbcon_state: State for nbcon consoles * @nbcon_seq: Sequence number of the next record for nbcon to print * @pbufs: Pointer to nbcon private buffer - * @locked_port: True, if the port lock is locked by nbcon + * @kthread: Printer kthread for this console + * @rcuwait: RCU-safe wait object for @kthread waking */ struct console { char name[16]; -@@ -332,12 +336,16 @@ struct console { - /* nbcon console specific members */ - bool (*write_atomic)(struct console *con, - struct nbcon_write_context *wctxt); -+ bool (*write_thread)(struct console *con, -+ struct nbcon_write_context *wctxt); - void (*driver_enter)(struct console *con, unsigned long *flags); - void (*driver_exit)(struct console *con, unsigned long flags); - atomic_t __private nbcon_state; - atomic_long_t __private nbcon_seq; +@@ -372,6 +375,27 @@ struct console { + void (*write_atomic)(struct console *con, struct nbcon_write_context *wctxt); + + /** ++ * @write_thread: ++ * ++ * NBCON callback to write out text in task context. (Optional) ++ * ++ * This callback is called with the console already acquired. Any ++ * additional driver synchronization should have been performed by ++ * device_lock(). ++ * ++ * This callback is always called from task context but with migration ++ * disabled. ++ * ++ * The same criteria for console ownership verification and unsafe ++ * sections applies as with write_atomic(). The difference between ++ * this callback and write_atomic() is that this callback is used ++ * during normal operation and is always called from task context. ++ * This provides drivers with a relatively relaxed locking context ++ * for synchronizing output to the hardware. ++ */ ++ void (*write_thread)(struct console *con, struct nbcon_write_context *wctxt); ++ ++ /** + * @device_lock: + * + * NBCON callback to begin synchronization with driver code. +@@ -431,6 +455,8 @@ struct console { + struct nbcon_drvdata *nbcon_drvdata; + struct printk_buffers *pbufs; - bool locked_port; + struct task_struct *kthread; + struct rcuwait rcuwait; }; @@ -66,24 +75,24 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_LOCKDEP --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -92,6 +92,7 @@ void nbcon_free(struct console *con); - enum nbcon_prio nbcon_get_default_prio(void); - void nbcon_atomic_flush_all(void); - bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, int cookie); +@@ -90,6 +90,7 @@ enum nbcon_prio nbcon_get_default_prio(v + void nbcon_atomic_flush_pending(void); + bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, + int cookie); +void nbcon_kthread_create(struct console *con); /* * Check if the given console is currently capable and allowed to print -@@ -110,6 +111,8 @@ static inline bool console_is_usable(str +@@ -108,6 +109,8 @@ static inline bool console_is_usable(str if (flags & CON_NBCON) { if (!con->write_atomic) return false; -+ if (!con->write_thread || !con->kthread) ++ if (!con->write_thread) + return false; } else { if (!con->write) return false; -@@ -126,12 +129,34 @@ static inline bool console_is_usable(str +@@ -124,12 +127,35 @@ static inline bool console_is_usable(str return true; } @@ -115,23 +124,30 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +static inline void nbcon_kthread_wake(struct console *con) { } +static inline void nbcon_kthread_create(struct console *con) { } - #define printing_via_unlock (false) - ++ /* + * In !PRINTK builds we still export console_sem + * semaphore and some of console functions (console_unlock()/etc.), so +@@ -153,6 +179,8 @@ static inline bool console_is_usable(str + + #endif /* CONFIG_PRINTK */ + ++extern bool have_boot_console; ++ + extern struct printk_buffers printk_shared_pbufs; + + /** --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -5,8 +5,10 @@ - #include <linux/kernel.h> - #include <linux/console.h> - #include <linux/delay.h> +@@ -10,6 +10,7 @@ + #include <linux/export.h> + #include <linux/init.h> + #include <linux/irqflags.h> +#include <linux/kthread.h> - #include <linux/slab.h> - #include <linux/serial_core.h> -+#include "printk_ringbuffer.h" - #include "internal.h" - /* - * Printk console printing implementation for consoles which does not depend -@@ -828,6 +830,7 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); + #include <linux/minmax.h> + #include <linux/percpu.h> + #include <linux/preempt.h> +@@ -837,6 +838,7 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); /** * nbcon_emit_next_record - Emit a record in the acquired context * @wctxt: The write context that will be handed to the write function @@ -139,7 +155,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * * Return: True if this context still owns the console. False if * ownership was handed over or taken. -@@ -841,7 +844,7 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); +@@ -850,7 +852,7 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); * When true is returned, @wctxt->ctxt.backlog indicates whether there are * still records pending in the ringbuffer, */ @@ -148,26 +164,23 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); struct console *con = ctxt->console; -@@ -891,9 +894,17 @@ static bool nbcon_emit_next_record(struc +@@ -899,8 +901,14 @@ static bool nbcon_emit_next_record(struc nbcon_state_read(con, &cur); wctxt->unsafe_takeover = cur.unsafe_takeover; -- if (con->write_atomic) +- if (con->write_atomic) { + if (use_atomic && + con->write_atomic) { - done = con->write_atomic(con, wctxt); - + con->write_atomic(con, wctxt); ++ + } else if (!use_atomic && -+ con->write_thread && -+ con->kthread) { -+ WARN_ON_ONCE(con->kthread != current); -+ done = con->write_thread(con, wctxt); -+ } ++ con->write_thread) { ++ con->write_thread(con, wctxt); + - if (!done) { + } else { /* - * The emit was aborted, probably due to a loss of ownership. -@@ -929,6 +940,118 @@ static bool nbcon_emit_next_record(struc + * This function should never be called for legacy consoles. +@@ -936,6 +944,118 @@ static bool nbcon_emit_next_record(struc return nbcon_context_exit_unsafe(ctxt); } @@ -185,7 +198,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + */ +static bool nbcon_kthread_should_wakeup(struct console *con, struct nbcon_context *ctxt) +{ -+ bool is_usable; ++ bool ret = false; + short flags; + int cookie; + @@ -193,17 +206,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + return true; + + cookie = console_srcu_read_lock(); -+ flags = console_srcu_read_flags(con); -+ is_usable = console_is_usable(con, flags); -+ console_srcu_read_unlock(cookie); + -+ if (!is_usable) -+ return false; ++ flags = console_srcu_read_flags(con); ++ if (console_is_usable(con, flags)) { ++ /* Bring the sequence in @ctxt up to date */ ++ ctxt->seq = nbcon_seq_read(con); + -+ /* Bring the sequence in @ctxt up to date */ -+ ctxt->seq = nbcon_seq_read(con); ++ ret = prb_read_valid(prb, ctxt->seq, NULL); ++ } + -+ return prb_read_valid(prb, ctxt->seq, NULL); ++ console_srcu_read_unlock(cookie); ++ return ret; +} + +/** @@ -254,7 +267,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + con_flags = console_srcu_read_flags(con); + + if (console_is_usable(con, con_flags)) { -+ con->driver_enter(con, &flags); ++ con->device_lock(con, &flags); + + /* + * Ensure this stays on the CPU to make handover and @@ -273,7 +286,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + } + } + -+ con->driver_exit(con, flags); ++ con->device_unlock(con, flags); + } + + console_srcu_read_unlock(cookie); @@ -286,16 +299,25 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Track the nbcon emergency nesting per CPU. */ static DEFINE_PER_CPU(unsigned int, nbcon_pcpu_emergency_nesting); static unsigned int early_nbcon_pcpu_emergency_nesting __initdata; -@@ -976,7 +1099,7 @@ static bool nbcon_atomic_emit_one(struct +@@ -982,7 +1102,7 @@ static bool nbcon_atomic_emit_one(struct * handed over or taken over. In both cases the context is no * longer valid. */ - if (!nbcon_emit_next_record(wctxt)) + if (!nbcon_emit_next_record(wctxt, true)) - return false; + return true; nbcon_context_release(ctxt); -@@ -1192,6 +1315,63 @@ void nbcon_cpu_emergency_exit(void) +@@ -1091,7 +1211,7 @@ static bool __nbcon_atomic_flush_pending + * handed over or taken over. In both cases the context is no + * longer valid. + */ +- if (!nbcon_emit_next_record(&wctxt)) ++ if (!nbcon_emit_next_record(&wctxt, true)) + return true; + + if (!ctxt->backlog) +@@ -1230,6 +1350,63 @@ void nbcon_cpu_emergency_exit(void) } /** @@ -359,15 +381,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * nbcon_alloc - Allocate buffers needed by the nbcon console * @con: Console to allocate buffers for * -@@ -1237,6 +1417,7 @@ void nbcon_init(struct console *con) +@@ -1273,6 +1450,7 @@ void nbcon_init(struct console *con) /* nbcon_alloc() must have been called and successful! */ BUG_ON(!con->pbufs); + rcuwait_init(&con->rcuwait); - nbcon_seq_force(con, con->seq); + nbcon_seq_force(con, 0); nbcon_state_set(con, &state); } -@@ -1249,6 +1430,7 @@ void nbcon_free(struct console *con) +@@ -1285,6 +1463,7 @@ void nbcon_free(struct console *con) { struct nbcon_state state = { }; @@ -377,7 +399,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Boot consoles share global printk buffers. */ --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -2689,6 +2689,8 @@ void suspend_console(void) +@@ -483,7 +483,7 @@ static bool have_nbcon_console; + * the console lock. This is because boot consoles and nbcon consoles may + * have mapped the same hardware. + */ +-static bool have_boot_console; ++bool have_boot_console; + + /* + * Specifies if the console lock/unlock dance is needed for console +@@ -2698,6 +2698,8 @@ void suspend_console(void) void resume_console(void) { struct console *con; @@ -386,7 +417,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!console_suspend_enabled) return; -@@ -2705,6 +2707,14 @@ void resume_console(void) +@@ -2714,6 +2716,14 @@ void resume_console(void) */ synchronize_srcu(&console_srcu); @@ -401,7 +432,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> pr_flush(1000, true); } -@@ -3025,6 +3035,13 @@ static bool console_flush_all(bool do_co +@@ -3034,6 +3044,13 @@ static bool console_flush_all(bool do_co u64 printk_seq; bool progress; @@ -415,7 +446,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!console_is_usable(con, flags)) continue; any_usable = true; -@@ -3320,9 +3337,23 @@ EXPORT_SYMBOL(console_stop); +@@ -3327,9 +3344,23 @@ EXPORT_SYMBOL(console_stop); void console_start(struct console *console) { diff --git a/debian/patches-rt/0038-printk-Atomic-print-in-printk-context-on-shutdown.patch b/debian/patches-rt/0034-printk-Atomic-print-in-printk-context-on-shutdown.patch index 1f51022ae4..68b58b5f41 100644 --- a/debian/patches-rt/0038-printk-Atomic-print-in-printk-context-on-shutdown.patch +++ b/debian/patches-rt/0034-printk-Atomic-print-in-printk-context-on-shutdown.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Mon, 23 Oct 2023 17:43:48 +0000 -Subject: [PATCH 38/50] printk: Atomic print in printk context on shutdown -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 34/48] printk: Atomic print in printk context on shutdown +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz For nbcon consoles, normally the printing is handled by the dedicated console printing threads. However, on shutdown the @@ -19,22 +19,21 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -2388,13 +2388,18 @@ asmlinkage int vprintk_emit(int facility +@@ -2402,12 +2402,17 @@ asmlinkage int vprintk_emit(int facility * * - When this CPU is in panic. * + * - During shutdown, since the printing threads may not get + * a chance to print the final messages. + * - * Note that if boot consoles are registered, the - * console_lock/console_unlock dance must be relied upon - * instead because nbcon consoles cannot print simultaneously - * with boot consoles. + * Note that if boot consoles are registered, the console + * lock/unlock dance must be relied upon instead because nbcon + * consoles cannot print simultaneously with boot consoles. */ - if (is_panic_context) + if (is_panic_context || + (system_state > SYSTEM_RUNNING)) { - nbcon_atomic_flush_all(); + nbcon_atomic_flush_pending(); + } } diff --git a/debian/patches-rt/0039-printk-nbcon-Add-context-to-console_is_usable.patch b/debian/patches-rt/0035-printk-nbcon-Add-context-to-console_is_usable.patch index 7702309536..bd434ec326 100644 --- a/debian/patches-rt/0039-printk-nbcon-Add-context-to-console_is_usable.patch +++ b/debian/patches-rt/0035-printk-nbcon-Add-context-to-console_is_usable.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 26 Sep 2023 14:43:30 +0000 -Subject: [PATCH 39/50] printk: nbcon: Add context to console_is_usable() -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 35/48] printk: nbcon: Add context to console_is_usable() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The nbcon consoles have two callbacks to be used for different contexts. In order to determine if an nbcon console is usable, @@ -20,7 +20,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -100,7 +100,7 @@ void nbcon_kthread_create(struct console +@@ -98,7 +98,7 @@ void nbcon_kthread_create(struct console * which can also play a role in deciding if @con can be used to print * records. */ @@ -29,26 +29,26 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { if (!(flags & CON_ENABLED)) return false; -@@ -109,10 +109,13 @@ static inline bool console_is_usable(str +@@ -107,10 +107,13 @@ static inline bool console_is_usable(str return false; if (flags & CON_NBCON) { - if (!con->write_atomic) - return false; -- if (!con->write_thread || !con->kthread) +- if (!con->write_thread) - return false; + if (use_atomic) { + if (!con->write_atomic) + return false; + } else { -+ if (!con->write_thread || !con->kthread) ++ if (!con->write_thread) + return false; + } } else { if (!con->write) return false; -@@ -178,7 +181,8 @@ static inline void nbcon_atomic_flush_al - static inline bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, +@@ -175,7 +178,8 @@ static inline void nbcon_atomic_flush_pe + static inline bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, int cookie) { return false; } -static inline bool console_is_usable(struct console *con, short flags) { return false; } @@ -59,25 +59,25 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -963,7 +963,7 @@ static bool nbcon_kthread_should_wakeup( - +@@ -968,7 +968,7 @@ static bool nbcon_kthread_should_wakeup( cookie = console_srcu_read_lock(); + flags = console_srcu_read_flags(con); -- is_usable = console_is_usable(con, flags); -+ is_usable = console_is_usable(con, flags, false); - console_srcu_read_unlock(cookie); +- if (console_is_usable(con, flags)) { ++ if (console_is_usable(con, flags, false)) { + /* Bring the sequence in @ctxt up to date */ + ctxt->seq = nbcon_seq_read(con); - if (!is_usable) -@@ -1022,7 +1022,7 @@ static int nbcon_kthread_func(void *__co +@@ -1026,7 +1026,7 @@ static int nbcon_kthread_func(void *__co con_flags = console_srcu_read_flags(con); - if (console_is_usable(con, con_flags)) { + if (console_is_usable(con, con_flags, false)) { - con->driver_enter(con, &flags); + con->device_lock(con, &flags); /* -@@ -1203,7 +1203,7 @@ static void __nbcon_atomic_flush_all(u64 +@@ -1246,7 +1246,7 @@ static void __nbcon_atomic_flush_pending if (!(flags & CON_NBCON)) continue; @@ -88,7 +88,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (nbcon_seq_read(con) >= stop_seq) --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -3047,7 +3047,7 @@ static bool console_flush_all(bool do_co +@@ -3056,7 +3056,7 @@ static bool console_flush_all(bool do_co if ((flags & CON_NBCON) && con->kthread) continue; @@ -97,7 +97,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> continue; any_usable = true; -@@ -3952,8 +3952,10 @@ static bool __pr_flush(struct console *c +@@ -3991,8 +3991,10 @@ static bool __pr_flush(struct console *c * that they make forward progress, so only increment * @diff for usable consoles. */ diff --git a/debian/patches-rt/0035-rcu-Mark-emergency-section-in-rcu-stalls.patch b/debian/patches-rt/0035-rcu-Mark-emergency-section-in-rcu-stalls.patch deleted file mode 100644 index 3608cd7954..0000000000 --- a/debian/patches-rt/0035-rcu-Mark-emergency-section-in-rcu-stalls.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Mon, 11 Sep 2023 15:53:39 +0000 -Subject: [PATCH 35/50] rcu: Mark emergency section in rcu stalls -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Mark an emergency section within print_other_cpu_stall(), where -RCU stall information is printed. In this section, the CPU will -not perform console output for the printk() calls. Instead, a -flushing of the console output will triggered when exiting the -emergency section. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/rcu/tree_stall.h | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/kernel/rcu/tree_stall.h -+++ b/kernel/rcu/tree_stall.h -@@ -9,6 +9,7 @@ - - #include <linux/kvm_para.h> - #include <linux/rcu_notifier.h> -+#include <linux/console.h> - - ////////////////////////////////////////////////////////////////////////////// - // -@@ -604,6 +605,8 @@ static void print_other_cpu_stall(unsign - if (rcu_stall_is_suppressed()) - return; - -+ nbcon_cpu_emergency_enter(); -+ - /* - * OK, time to rat on our buddy... - * See Documentation/RCU/stallwarn.rst for info on how to debug -@@ -658,6 +661,8 @@ static void print_other_cpu_stall(unsign - panic_on_rcu_stall(); - - rcu_force_quiescent_state(); /* Kick them all. */ -+ -+ nbcon_cpu_emergency_exit(); - } - - static void print_cpu_stall(unsigned long gps) diff --git a/debian/patches-rt/0036-lockdep-Mark-emergency-section-in-lockdep-splats.patch b/debian/patches-rt/0036-lockdep-Mark-emergency-section-in-lockdep-splats.patch deleted file mode 100644 index 550bcda637..0000000000 --- a/debian/patches-rt/0036-lockdep-Mark-emergency-section-in-lockdep-splats.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Mon, 18 Sep 2023 20:27:41 +0000 -Subject: [PATCH 36/50] lockdep: Mark emergency section in lockdep splats -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Mark an emergency section within print_usage_bug(), where -lockdep bugs are printed. In this section, the CPU will not -perform console output for the printk() calls. Instead, a -flushing of the console output will triggered when exiting -the emergency section. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/locking/lockdep.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/kernel/locking/lockdep.c -+++ b/kernel/locking/lockdep.c -@@ -56,6 +56,7 @@ - #include <linux/kprobes.h> - #include <linux/lockdep.h> - #include <linux/context_tracking.h> -+#include <linux/console.h> - - #include <asm/sections.h> - -@@ -3971,6 +3972,8 @@ print_usage_bug(struct task_struct *curr - if (!debug_locks_off() || debug_locks_silent) - return; - -+ nbcon_cpu_emergency_enter(); -+ - pr_warn("\n"); - pr_warn("================================\n"); - pr_warn("WARNING: inconsistent lock state\n"); -@@ -3999,6 +4002,8 @@ print_usage_bug(struct task_struct *curr - - pr_warn("\nstack backtrace:\n"); - dump_stack(); -+ -+ nbcon_cpu_emergency_exit(); - } - - /* diff --git a/debian/patches-rt/0040-printk-nbcon-Add-printer-thread-wakeups.patch b/debian/patches-rt/0036-printk-nbcon-Add-printer-thread-wakeups.patch index 89e086aa32..81701b90f0 100644 --- a/debian/patches-rt/0040-printk-nbcon-Add-printer-thread-wakeups.patch +++ b/debian/patches-rt/0036-printk-nbcon-Add-printer-thread-wakeups.patch @@ -1,7 +1,7 @@ From: Thomas Gleixner <tglx@linutronix.de> Date: Tue, 26 Sep 2023 13:03:52 +0000 -Subject: [PATCH 40/50] printk: nbcon: Add printer thread wakeups -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 36/48] printk: nbcon: Add printer thread wakeups +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Add a function to wakeup the printer threads. Use the new function when: @@ -34,16 +34,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include <linux/rculist.h> #include <linux/rcuwait.h> #include <linux/types.h> -@@ -313,6 +314,7 @@ struct nbcon_write_context { - * @locked_port: True, if the port lock is locked by nbcon +@@ -327,6 +328,7 @@ struct nbcon_drvdata { + * @pbufs: Pointer to nbcon private buffer * @kthread: Printer kthread for this console * @rcuwait: RCU-safe wait object for @kthread waking + * @irq_work: Defer @kthread waking to IRQ work context */ struct console { char name[16]; -@@ -346,6 +348,7 @@ struct console { - bool locked_port; +@@ -457,6 +459,7 @@ struct console { + struct printk_buffers *pbufs; struct task_struct *kthread; struct rcuwait rcuwait; + struct irq_work irq_work; @@ -52,9 +52,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_LOCKDEP --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -93,6 +93,7 @@ enum nbcon_prio nbcon_get_default_prio(v - void nbcon_atomic_flush_all(void); - bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, int cookie); +@@ -91,6 +91,7 @@ void nbcon_atomic_flush_pending(void); + bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, + int cookie); void nbcon_kthread_create(struct console *con); +void nbcon_wake_threads(void); @@ -62,7 +62,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Check if the given console is currently capable and allowed to print --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -1052,6 +1052,61 @@ static int nbcon_kthread_func(void *__co +@@ -1056,6 +1056,61 @@ static int nbcon_kthread_func(void *__co goto wait_for_event; } @@ -124,17 +124,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Track the nbcon emergency nesting per CPU. */ static DEFINE_PER_CPU(unsigned int, nbcon_pcpu_emergency_nesting); static unsigned int early_nbcon_pcpu_emergency_nesting __initdata; -@@ -1418,6 +1473,7 @@ void nbcon_init(struct console *con) +@@ -1451,6 +1506,7 @@ void nbcon_init(struct console *con) BUG_ON(!con->pbufs); rcuwait_init(&con->rcuwait); + init_irq_work(&con->irq_work, nbcon_irq_work); - nbcon_seq_force(con, con->seq); + nbcon_seq_force(con, 0); nbcon_state_set(con, &state); } --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -2402,6 +2402,8 @@ asmlinkage int vprintk_emit(int facility +@@ -2415,6 +2415,8 @@ asmlinkage int vprintk_emit(int facility } } @@ -143,7 +143,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (do_trylock_unlock) { /* * The caller may be holding system-critical or -@@ -2712,6 +2714,10 @@ void resume_console(void) +@@ -2721,6 +2723,10 @@ void resume_console(void) */ synchronize_srcu(&console_srcu); @@ -154,7 +154,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> cookie = console_srcu_read_lock(); for_each_console_srcu(con) { flags = console_srcu_read_flags(con); -@@ -4104,6 +4110,7 @@ void defer_console_output(void) +@@ -4151,6 +4157,7 @@ void defer_console_output(void) void printk_trigger_flush(void) { diff --git a/debian/patches-rt/0041-printk-nbcon-Stop-threads-on-shutdown-reboot.patch b/debian/patches-rt/0037-printk-nbcon-Stop-threads-on-shutdown-reboot.patch index f412a9adf0..28fccd7fc7 100644 --- a/debian/patches-rt/0041-printk-nbcon-Stop-threads-on-shutdown-reboot.patch +++ b/debian/patches-rt/0037-printk-nbcon-Stop-threads-on-shutdown-reboot.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 26 Sep 2023 13:04:15 +0000 -Subject: [PATCH 41/50] printk: nbcon: Stop threads on shutdown/reboot -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 37/48] printk: nbcon: Stop threads on shutdown/reboot +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Register a syscore_ops shutdown function to stop all threaded printers on shutdown/reboot. This allows printk to transition back @@ -16,18 +16,18 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -8,6 +8,7 @@ - #include <linux/kthread.h> - #include <linux/slab.h> - #include <linux/serial_core.h> +@@ -18,6 +18,7 @@ + #include <linux/smp.h> + #include <linux/stddef.h> + #include <linux/string.h> +#include <linux/syscore_ops.h> - #include "printk_ringbuffer.h" + #include <linux/types.h> #include "internal.h" - /* -@@ -1577,3 +1578,33 @@ void nbcon_release(struct uart_port *up) - con->locked_port = false; + #include "printk_ringbuffer.h" +@@ -1577,3 +1578,33 @@ void nbcon_driver_release(struct console + nbcon_context_release(ctxt); } - EXPORT_SYMBOL_GPL(nbcon_release); + EXPORT_SYMBOL_GPL(nbcon_driver_release); + +/** + * printk_kthread_shutdown - shutdown all threaded printers diff --git a/debian/patches-rt/0042-printk-nbcon-Start-printing-threads.patch b/debian/patches-rt/0038-printk-nbcon-Start-printing-threads.patch index 8360fe1876..63aae75ebb 100644 --- a/debian/patches-rt/0042-printk-nbcon-Start-printing-threads.patch +++ b/debian/patches-rt/0038-printk-nbcon-Start-printing-threads.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 5 Dec 2023 14:09:31 +0000 -Subject: [PATCH 42/50] printk: nbcon: Start printing threads -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 38/48] printk: nbcon: Start printing threads +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz If there are no boot consoles, the printing threads are started in early_initcall. @@ -25,25 +25,25 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -44,6 +44,7 @@ enum printk_info_flags { - }; +@@ -48,6 +48,7 @@ struct printk_ringbuffer; + struct dev_printk_info; extern struct printk_ringbuffer *prb; +extern bool printk_threads_enabled; - extern bool have_legacy_console; - extern bool have_boot_console; -@@ -161,6 +162,7 @@ static inline void nbcon_kthread_wake(st + __printf(4, 0) + int vprintk_store(int facility, int level, +@@ -159,6 +160,7 @@ static inline void nbcon_kthread_wake(st static inline void nbcon_kthread_wake(struct console *con) { } static inline void nbcon_kthread_create(struct console *con) { } +#define printk_threads_enabled (false) - #define printing_via_unlock (false) /* + * In !PRINTK builds we still export console_sem --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -205,6 +205,8 @@ static void nbcon_seq_try_update(struct +@@ -213,6 +213,8 @@ static void nbcon_seq_try_update(struct } } @@ -52,7 +52,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** * nbcon_context_try_acquire_direct - Try to acquire directly * @ctxt: The context of the caller -@@ -1401,7 +1403,7 @@ void nbcon_kthread_create(struct console +@@ -1436,7 +1438,7 @@ void nbcon_kthread_create(struct console if (!(con->flags & CON_NBCON) || !con->write_thread) return; @@ -61,7 +61,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return; /* -@@ -1427,6 +1429,19 @@ void nbcon_kthread_create(struct console +@@ -1462,6 +1464,19 @@ void nbcon_kthread_create(struct console sched_set_normal(con->kthread, -20); } @@ -81,9 +81,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** * nbcon_alloc - Allocate buffers needed by the nbcon console * @con: Console to allocate buffers for -@@ -1477,6 +1492,7 @@ void nbcon_init(struct console *con) +@@ -1510,6 +1525,7 @@ void nbcon_init(struct console *con) init_irq_work(&con->irq_work, nbcon_irq_work); - nbcon_seq_force(con, con->seq); + nbcon_seq_force(con, 0); nbcon_state_set(con, &state); + nbcon_kthread_create(con); } @@ -91,7 +91,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -2388,6 +2388,9 @@ asmlinkage int vprintk_emit(int facility +@@ -2402,6 +2402,9 @@ asmlinkage int vprintk_emit(int facility * * - When this CPU is in panic. * @@ -101,15 +101,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * - During shutdown, since the printing threads may not get * a chance to print the final messages. * -@@ -2397,6 +2400,7 @@ asmlinkage int vprintk_emit(int facility - * with boot consoles. +@@ -2410,6 +2413,7 @@ asmlinkage int vprintk_emit(int facility + * consoles cannot print simultaneously with boot consoles. */ if (is_panic_context || + !printk_threads_enabled || (system_state > SYSTEM_RUNNING)) { - nbcon_atomic_flush_all(); + nbcon_atomic_flush_pending(); } -@@ -3692,6 +3696,7 @@ EXPORT_SYMBOL(register_console); +@@ -3726,6 +3730,7 @@ EXPORT_SYMBOL(register_console); /* Must be called under console_list_lock(). */ static int unregister_console_locked(struct console *console) { @@ -117,9 +117,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> bool found_legacy_con = false; bool found_nbcon_con = false; bool found_boot_con = false; -@@ -3763,6 +3768,15 @@ static int unregister_console_locked(str +@@ -3797,6 +3802,15 @@ static int unregister_console_locked(str if (!found_nbcon_con) - have_nbcon_console = false; + have_nbcon_console = found_nbcon_con; + /* + * When the last boot console unregisters, start up the diff --git a/debian/patches-rt/0039-printk-Provide-helper-for-message-prepending.patch b/debian/patches-rt/0039-printk-Provide-helper-for-message-prepending.patch new file mode 100644 index 0000000000..35bfe33e7a --- /dev/null +++ b/debian/patches-rt/0039-printk-Provide-helper-for-message-prepending.patch @@ -0,0 +1,82 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Thu, 28 Mar 2024 13:29:10 +0000 +Subject: [PATCH 39/48] printk: Provide helper for message prepending +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +In order to support prepending different texts to printk +messages, split out the prepending code into a helper +function. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/printk/printk.c | 38 +++++++++++++++++++++++++++----------- + 1 file changed, 27 insertions(+), 11 deletions(-) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2819,30 +2819,25 @@ static void __console_unlock(void) + #ifdef CONFIG_PRINTK + + /* +- * Prepend the message in @pmsg->pbufs->outbuf with a "dropped message". This +- * is achieved by shifting the existing message over and inserting the dropped +- * message. ++ * Prepend the message in @pmsg->pbufs->outbuf with the message in ++ * @pmsg->pbufs->scratchbuf. This is achieved by shifting the existing message ++ * over and inserting the scratchbuf message. + * + * @pmsg is the printk message to prepend. + * +- * @dropped is the dropped count to report in the dropped message. ++ * @len is the length of the message in @pmsg->pbufs->scratchbuf. + * + * If the message text in @pmsg->pbufs->outbuf does not have enough space for +- * the dropped message, the message text will be sufficiently truncated. ++ * the scratchbuf message, the message text will be sufficiently truncated. + * + * If @pmsg->pbufs->outbuf is modified, @pmsg->outbuf_len is updated. + */ +-void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped) ++static void __console_prepend_scratch(struct printk_message *pmsg, size_t len) + { + struct printk_buffers *pbufs = pmsg->pbufs; +- const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf); + const size_t outbuf_sz = sizeof(pbufs->outbuf); + char *scratchbuf = &pbufs->scratchbuf[0]; + char *outbuf = &pbufs->outbuf[0]; +- size_t len; +- +- len = scnprintf(scratchbuf, scratchbuf_sz, +- "** %lu printk messages dropped **\n", dropped); + + /* + * Make sure outbuf is sufficiently large before prepending. +@@ -2865,6 +2860,27 @@ void console_prepend_dropped(struct prin + } + + /* ++ * Prepend the message in @pmsg->pbufs->outbuf with a "dropped message". ++ * @pmsg->outbuf_len is updated appropriately. ++ * ++ * @pmsg is the printk message to prepend. ++ * ++ * @dropped is the dropped count to report in the dropped message. ++ */ ++void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped) ++{ ++ struct printk_buffers *pbufs = pmsg->pbufs; ++ const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf); ++ char *scratchbuf = &pbufs->scratchbuf[0]; ++ size_t len; ++ ++ len = scnprintf(scratchbuf, scratchbuf_sz, ++ "** %lu printk messages dropped **\n", dropped); ++ ++ __console_prepend_scratch(pmsg, len); ++} ++ ++/* + * Read and format the specified record (or a later record if the specified + * record is not available). + * diff --git a/debian/patches-rt/0040-printk-nbcon-Show-replay-message-on-takeover.patch b/debian/patches-rt/0040-printk-nbcon-Show-replay-message-on-takeover.patch new file mode 100644 index 0000000000..ab1046954b --- /dev/null +++ b/debian/patches-rt/0040-printk-nbcon-Show-replay-message-on-takeover.patch @@ -0,0 +1,135 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Mon, 25 Mar 2024 21:00:40 +0000 +Subject: [PATCH 40/48] printk: nbcon: Show replay message on takeover +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +An emergency or panic context can takeover console ownership +while the current owner was printing a printk message. The +atomic printer will re-print the message that the previous +owner was printing. However, this can look confusing to the +user and may even seem as though a message was lost. + + [3430014.1 + [3430014.181123] usb 1-2: Product: USB Audio + +Add a new field @nbcon_prev_seq to struct console to track +the sequence number to print that was assigned to the previous +console owner. If this matches the sequence number to print +that the current owner is assigned, then a takeover must have +occurred. In this case, print an additional message to inform +the user that the previous message is being printed again. + + [3430014.1 + ** replaying previous printk message ** + [3430014.181123] usb 1-2: Product: USB Audio + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/console.h | 2 ++ + kernel/printk/internal.h | 1 + + kernel/printk/nbcon.c | 24 ++++++++++++++++++++++++ + kernel/printk/printk.c | 19 +++++++++++++++++++ + 4 files changed, 46 insertions(+) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -325,6 +325,7 @@ struct nbcon_drvdata { + * + * @nbcon_state: State for nbcon consoles + * @nbcon_seq: Sequence number of the next record for nbcon to print ++ * @nbcon_prev_seq: Seq num the previous nbcon owner was assigned to print + * @pbufs: Pointer to nbcon private buffer + * @kthread: Printer kthread for this console + * @rcuwait: RCU-safe wait object for @kthread waking +@@ -441,6 +442,7 @@ struct console { + + atomic_t __private nbcon_state; + atomic_long_t __private nbcon_seq; ++ atomic_long_t __private nbcon_prev_seq; + + /** + * @nbcon_drvdata: +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -222,4 +222,5 @@ bool printk_get_next_message(struct prin + + #ifdef CONFIG_PRINTK + void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped); ++void console_prepend_replay(struct printk_message *pmsg); + #endif +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -866,6 +866,7 @@ static bool nbcon_emit_next_record(struc + unsigned long con_dropped; + struct nbcon_state cur; + unsigned long dropped; ++ unsigned long ulseq; + + /* + * The printk buffers are filled within an unsafe section. This +@@ -891,6 +892,28 @@ static bool nbcon_emit_next_record(struc + if (dropped && !is_extended) + console_prepend_dropped(&pmsg, dropped); + ++ /* ++ * If the previous owner was assigned the same record, this context ++ * has taken over ownership and is replaying the record. Prepend a ++ * message to let the user know the record is replayed. ++ */ ++ ulseq = atomic_long_read(&ACCESS_PRIVATE(con, nbcon_prev_seq)); ++ if (__ulseq_to_u64seq(prb, ulseq) == pmsg.seq) { ++ console_prepend_replay(&pmsg); ++ } else { ++ /* ++ * Ensure this context is still the owner before trying to ++ * update @nbcon_prev_seq. Otherwise the value in @ulseq may ++ * not be from the previous owner. ++ */ ++ nbcon_state_read(con, &cur); ++ if (!nbcon_context_can_proceed(ctxt, &cur)) ++ return false; ++ ++ atomic_long_try_cmpxchg(&ACCESS_PRIVATE(con, nbcon_prev_seq), &ulseq, ++ __u64seq_to_ulseq(pmsg.seq)); ++ } ++ + if (!nbcon_context_exit_unsafe(ctxt)) + return false; + +@@ -1524,6 +1547,7 @@ void nbcon_init(struct console *con) + rcuwait_init(&con->rcuwait); + init_irq_work(&con->irq_work, nbcon_irq_work); + nbcon_seq_force(con, 0); ++ atomic_long_set(&ACCESS_PRIVATE(con, nbcon_prev_seq), -1UL); + nbcon_state_set(con, &state); + nbcon_kthread_create(con); + } +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2881,6 +2881,25 @@ void console_prepend_dropped(struct prin + } + + /* ++ * Prepend the message in @pmsg->pbufs->outbuf with a "replay message". ++ * @pmsg->outbuf_len is updated appropriately. ++ * ++ * @pmsg is the printk message to prepend. ++ */ ++void console_prepend_replay(struct printk_message *pmsg) ++{ ++ struct printk_buffers *pbufs = pmsg->pbufs; ++ const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf); ++ char *scratchbuf = &pbufs->scratchbuf[0]; ++ size_t len; ++ ++ len = scnprintf(scratchbuf, scratchbuf_sz, ++ "** replaying previous printk message **\n"); ++ ++ __console_prepend_scratch(pmsg, len); ++} ++ ++/* + * Read and format the specified record (or a later record if the specified + * record is not available). + * diff --git a/debian/patches-rt/0043-proc-Add-nbcon-support-for-proc-consoles.patch b/debian/patches-rt/0041-proc-Add-nbcon-support-for-proc-consoles.patch index 4e1b940659..edae68d991 100644 --- a/debian/patches-rt/0043-proc-Add-nbcon-support-for-proc-consoles.patch +++ b/debian/patches-rt/0041-proc-Add-nbcon-support-for-proc-consoles.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Tue, 26 Sep 2023 13:31:00 +0000 -Subject: [PATCH 43/50] proc: Add nbcon support for /proc/consoles -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 41/48] proc: Add nbcon support for /proc/consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Update /proc/consoles output to show 'W' if an nbcon write callback is implemented (write_atomic or write_thread). diff --git a/debian/patches-rt/0044-tty-sysfs-Add-nbcon-support-for-active.patch b/debian/patches-rt/0042-tty-sysfs-Add-nbcon-support-for-active.patch index e0cf557da2..0c5dc15561 100644 --- a/debian/patches-rt/0044-tty-sysfs-Add-nbcon-support-for-active.patch +++ b/debian/patches-rt/0042-tty-sysfs-Add-nbcon-support-for-active.patch @@ -1,29 +1,27 @@ From: John Ogness <john.ogness@linutronix.de> Date: Fri, 22 Sep 2023 14:31:09 +0000 -Subject: [PATCH 44/50] tty: sysfs: Add nbcon support for 'active' -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 42/48] tty: sysfs: Add nbcon support for 'active' +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Allow the 'active' attribute to list nbcon consoles. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - drivers/tty/tty_io.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) + drivers/tty/tty_io.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c -@@ -3544,8 +3544,15 @@ static ssize_t show_cons_active(struct d +@@ -3567,8 +3567,13 @@ static ssize_t show_cons_active(struct d for_each_console(c) { if (!c->device) continue; - if (!c->write) - continue; + if (c->flags & CON_NBCON) { -+ if (!c->write_atomic && -+ !(c->write_thread && c->kthread)) { ++ if (!c->write_atomic && !c->write_thread) + continue; -+ } + } else { + if (!c->write) + continue; diff --git a/debian/patches-rt/0045-printk-nbcon-Provide-function-to-reacquire-ownership.patch b/debian/patches-rt/0043-printk-nbcon-Provide-function-to-reacquire-ownership.patch index 98e303d30e..5dd9fe97d7 100644 --- a/debian/patches-rt/0045-printk-nbcon-Provide-function-to-reacquire-ownership.patch +++ b/debian/patches-rt/0043-printk-nbcon-Provide-function-to-reacquire-ownership.patch @@ -1,7 +1,7 @@ From: John Ogness <john.ogness@linutronix.de> Date: Fri, 20 Oct 2023 10:01:58 +0000 -Subject: [PATCH 45/50] printk: nbcon: Provide function to reacquire ownership -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 43/48] printk: nbcon: Provide function to reacquire ownership +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Contexts may become nbcon owners for various reasons, not just for printing. Indeed, the port->lock wrapper takes ownership @@ -27,13 +27,25 @@ lost. nbcon_reacquire() cannot be used to resume printing. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - include/linux/console.h | 2 ++ - kernel/printk/nbcon.c | 32 ++++++++++++++++++++++++++++++++ - 2 files changed, 34 insertions(+) + include/linux/console.h | 7 +++++++ + kernel/printk/nbcon.c | 41 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 48 insertions(+) --- a/include/linux/console.h +++ b/include/linux/console.h -@@ -481,12 +481,14 @@ extern void nbcon_cpu_emergency_exit(voi +@@ -371,6 +371,11 @@ struct console { + * functions are also points of possible ownership transfer. If + * either function returns false, ownership has been lost. + * ++ * If the driver must reacquire ownership in order to finalize or ++ * revert hardware changes, nbcon_reacquire() can be used. However, ++ * on reacquire the buffer content is no longer available. A ++ * reacquire cannot be used to resume printing. ++ * + * This callback can be called from any context (including NMI). + * Therefore it must avoid usage of any locking and instead rely + * on the console ownership for synchronization. +@@ -595,12 +600,14 @@ extern void nbcon_cpu_emergency_exit(voi extern bool nbcon_can_proceed(struct nbcon_write_context *wctxt); extern bool nbcon_enter_unsafe(struct nbcon_write_context *wctxt); extern bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt); @@ -50,7 +62,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> extern int console_set_on_cmdline; --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -831,6 +831,38 @@ bool nbcon_exit_unsafe(struct nbcon_writ +@@ -839,6 +839,38 @@ bool nbcon_exit_unsafe(struct nbcon_writ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); /** @@ -89,3 +101,19 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * nbcon_emit_next_record - Emit a record in the acquired context * @wctxt: The write context that will be handed to the write function * @use_atomic: True if the write_atomic callback is to be used +@@ -944,6 +976,15 @@ static bool nbcon_emit_next_record(struc + nbcon_context_release(ctxt); + return false; + } ++ ++ if (!wctxt->outbuf) { ++ /* ++ * Ownership was lost and reacquired by the driver. ++ * Handle it as if ownership was lost and try to continue. ++ */ ++ nbcon_context_release(ctxt); ++ return false; ++ } + + /* + * Since any dropped message was successfully output, reset the diff --git a/debian/patches-rt/0047-serial-8250-Switch-to-nbcon-console.patch b/debian/patches-rt/0044-serial-8250-Switch-to-nbcon-console.patch index 015a996d2c..22edc18426 100644 --- a/debian/patches-rt/0047-serial-8250-Switch-to-nbcon-console.patch +++ b/debian/patches-rt/0044-serial-8250-Switch-to-nbcon-console.patch @@ -1,13 +1,14 @@ From: John Ogness <john.ogness@linutronix.de> Date: Wed, 13 Sep 2023 15:30:36 +0000 -Subject: [PATCH 47/50] serial: 8250: Switch to nbcon console -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 44/48] serial: 8250: Switch to nbcon console +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Implement the necessary callbacks to switch the 8250 console driver to perform as an nbcon console. -Add implementations for the nbcon consoles (write_atomic, write_thread, -driver_enter, driver_exit) and add CON_NBCON to the initial flags. +Add implementations for the nbcon console callbacks (write_atomic, +write_thread, device_lock, device_unlock), provide @nbcon_drvdata, and +add CON_NBCON to the initial flags. The legacy code is kept in order to easily switch back to legacy mode by defining CONFIG_SERIAL_8250_LEGACY_CONSOLE. @@ -15,10 +16,10 @@ by defining CONFIG_SERIAL_8250_LEGACY_CONSOLE. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - drivers/tty/serial/8250/8250_core.c | 42 +++++++++ - drivers/tty/serial/8250/8250_port.c | 156 +++++++++++++++++++++++++++++++++++- + drivers/tty/serial/8250/8250_core.c | 45 ++++++++++ + drivers/tty/serial/8250/8250_port.c | 154 +++++++++++++++++++++++++++++++++++- include/linux/serial_8250.h | 6 + - 3 files changed, 201 insertions(+), 3 deletions(-) + 3 files changed, 202 insertions(+), 3 deletions(-) --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -30,45 +31,47 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static void univ8250_console_write(struct console *co, const char *s, unsigned int count) { -@@ -599,6 +600,37 @@ static void univ8250_console_write(struc +@@ -599,6 +600,39 @@ static void univ8250_console_write(struc serial8250_console_write(up, s, count); } +#else -+static bool univ8250_console_write_atomic(struct console *co, ++static void univ8250_console_write_atomic(struct console *co, + struct nbcon_write_context *wctxt) +{ + struct uart_8250_port *up = &serial8250_ports[co->index]; + -+ return serial8250_console_write_atomic(up, wctxt); ++ serial8250_console_write_atomic(up, wctxt); +} + -+static bool univ8250_console_write_thread(struct console *co, ++static void univ8250_console_write_thread(struct console *co, + struct nbcon_write_context *wctxt) +{ + struct uart_8250_port *up = &serial8250_ports[co->index]; + -+ return serial8250_console_write_thread(up, wctxt); ++ serial8250_console_write_thread(up, wctxt); +} + -+static void univ8250_console_driver_enter(struct console *con, unsigned long *flags) ++static void univ8250_console_device_lock(struct console *con, unsigned long *flags) +{ + struct uart_port *up = &serial8250_ports[con->index].port; + + __uart_port_lock_irqsave(up, flags); +} + -+static void univ8250_console_driver_exit(struct console *con, unsigned long flags) ++static void univ8250_console_device_unlock(struct console *con, unsigned long flags) +{ + struct uart_port *up = &serial8250_ports[con->index].port; + + __uart_port_unlock_irqrestore(up, flags); +} ++ ++static struct nbcon_drvdata serial8250_nbcon_drvdata; +#endif /* CONFIG_SERIAL_8250_LEGACY_CONSOLE */ static int univ8250_console_setup(struct console *co, char *options) { -@@ -698,12 +730,20 @@ static int univ8250_console_match(struct +@@ -698,12 +732,21 @@ static int univ8250_console_match(struct static struct console univ8250_console = { .name = "ttyS", @@ -78,9 +81,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +#else + .write_atomic = univ8250_console_write_atomic, + .write_thread = univ8250_console_write_thread, -+ .driver_enter = univ8250_console_driver_enter, -+ .driver_exit = univ8250_console_driver_exit, ++ .device_lock = univ8250_console_device_lock, ++ .device_unlock = univ8250_console_device_unlock, + .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON, ++ .nbcon_drvdata = &serial8250_nbcon_drvdata, +#endif .device = uart_console_device, .setup = univ8250_console_setup, @@ -92,19 +96,21 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c -@@ -550,6 +550,11 @@ static int serial8250_em485_init(struct +@@ -550,6 +550,13 @@ static int serial8250_em485_init(struct if (!p->em485) return -ENOMEM; +#ifndef CONFIG_SERIAL_8250_LEGACY_CONSOLE -+ if (uart_console(&p->port)) ++ if (uart_console(&p->port)) { + dev_warn(p->port.dev, "no atomic printing for rs485 consoles\n"); ++ p->port.cons->write_atomic = NULL; ++ } +#endif + hrtimer_init(&p->em485->stop_tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&p->em485->start_tx_timer, CLOCK_MONOTONIC, -@@ -702,7 +707,11 @@ static void serial8250_set_sleep(struct +@@ -702,7 +709,11 @@ static void serial8250_set_sleep(struct serial8250_rpm_put(p); } @@ -117,7 +123,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { if (up->capabilities & UART_CAP_UUE) serial_out(up, UART_IER, UART_IER_UUE); -@@ -710,6 +719,11 @@ static void serial8250_clear_IER(struct +@@ -710,6 +721,11 @@ static void serial8250_clear_IER(struct serial_out(up, UART_IER, 0); } @@ -129,7 +135,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_SERIAL_8250_RSA /* * Attempts to turn on the RSA FIFO. Returns zero on failure. -@@ -3320,6 +3334,11 @@ static void serial8250_console_putchar(s +@@ -3320,6 +3336,11 @@ static void serial8250_console_putchar(s wait_for_xmitr(up, UART_LSR_THRE); serial_port_out(port, UART_TX, ch); @@ -141,7 +147,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* -@@ -3348,6 +3367,7 @@ static void serial8250_console_restore(s +@@ -3348,6 +3369,7 @@ static void serial8250_console_restore(s serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); } @@ -149,7 +155,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Print a string to the serial port using the device FIFO * -@@ -3406,7 +3426,7 @@ void serial8250_console_write(struct uar +@@ -3406,7 +3428,7 @@ void serial8250_console_write(struct uar * First save the IER then disable the interrupts */ ier = serial_port_in(port, UART_IER); @@ -158,23 +164,22 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* check scratch reg to see if port powered off during system sleep */ if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { -@@ -3472,6 +3492,135 @@ void serial8250_console_write(struct uar +@@ -3472,6 +3494,131 @@ void serial8250_console_write(struct uar if (locked) uart_port_unlock_irqrestore(port, flags); } +#else -+bool serial8250_console_write_thread(struct uart_8250_port *up, ++void serial8250_console_write_thread(struct uart_8250_port *up, + struct nbcon_write_context *wctxt) +{ + struct uart_8250_em485 *em485 = up->em485; + struct uart_port *port = &up->port; -+ bool done = false; + unsigned int ier; + + touch_nmi_watchdog(); + + if (!nbcon_enter_unsafe(wctxt)) -+ return false; ++ return; + + /* First save IER then disable the interrupts. */ + ier = serial_port_in(port, UART_IER); @@ -220,7 +225,6 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + break; + } + } -+ done = (i == len); + } else { + nbcon_reacquire(wctxt); + } @@ -246,24 +250,23 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + if (up->msr_saved_flags) + serial8250_modem_status(up); + -+ /* Success if no handover/takeover and message fully printed. */ -+ return (nbcon_exit_unsafe(wctxt) && done); ++ nbcon_exit_unsafe(wctxt); +} + -+bool serial8250_console_write_atomic(struct uart_8250_port *up, ++void serial8250_console_write_atomic(struct uart_8250_port *up, + struct nbcon_write_context *wctxt) +{ + struct uart_port *port = &up->port; + unsigned int ier; + + /* Atomic console not supported for rs485 mode. */ -+ if (up->em485) -+ return false; ++ if (WARN_ON_ONCE(up->em485)) ++ return; + + touch_nmi_watchdog(); + + if (!nbcon_enter_unsafe(wctxt)) -+ return false; ++ return; + + /* + * First save IER then disable the interrupts. The special variant to @@ -287,14 +290,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); + serial_port_out(port, UART_IER, ier); + -+ /* Success if no handover/takeover. */ -+ return nbcon_exit_unsafe(wctxt); ++ nbcon_exit_unsafe(wctxt); +} +#endif /* CONFIG_SERIAL_8250_LEGACY_CONSOLE */ static unsigned int probe_baud(struct uart_port *port) { -@@ -3490,6 +3639,7 @@ static unsigned int probe_baud(struct ua +@@ -3490,6 +3637,7 @@ static unsigned int probe_baud(struct ua int serial8250_console_setup(struct uart_port *port, char *options, bool probe) { @@ -302,7 +304,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> int baud = 9600; int bits = 8; int parity = 'n'; -@@ -3499,6 +3649,8 @@ int serial8250_console_setup(struct uart +@@ -3499,6 +3647,8 @@ int serial8250_console_setup(struct uart if (!port->iobase && !port->membase) return -ENODEV; @@ -326,9 +328,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> void serial8250_set_defaults(struct uart_8250_port *up); void serial8250_console_write(struct uart_8250_port *up, const char *s, unsigned int count); -+bool serial8250_console_write_atomic(struct uart_8250_port *up, ++void serial8250_console_write_atomic(struct uart_8250_port *up, + struct nbcon_write_context *wctxt); -+bool serial8250_console_write_thread(struct uart_8250_port *up, ++void serial8250_console_write_thread(struct uart_8250_port *up, + struct nbcon_write_context *wctxt); int serial8250_console_setup(struct uart_port *port, char *options, bool probe); int serial8250_console_exit(struct uart_port *port); diff --git a/debian/patches-rt/0049-serial-8250-revert-drop-lockdep-annotation-from-seri.patch b/debian/patches-rt/0045-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch index 1be252903e..e9544b9f8c 100644 --- a/debian/patches-rt/0049-serial-8250-revert-drop-lockdep-annotation-from-seri.patch +++ b/debian/patches-rt/0045-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch @@ -1,8 +1,8 @@ From: John Ogness <john.ogness@linutronix.de> Date: Mon, 2 Oct 2023 15:30:43 +0000 -Subject: [PATCH 49/50] serial: 8250: revert "drop lockdep annotation from +Subject: [PATCH 45/48] serial: 8250: Revert "drop lockdep annotation from serial8250_clear_IER()" -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The 8250 driver no longer depends on @oops_in_progress and will no longer violate the port->lock locking constraints. @@ -17,7 +17,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c -@@ -721,6 +721,9 @@ static void __serial8250_clear_IER(struc +@@ -723,6 +723,9 @@ static void __serial8250_clear_IER(struc static inline void serial8250_clear_IER(struct uart_8250_port *up) { diff --git a/debian/patches-rt/0048-printk-Add-kthread-for-all-legacy-consoles.patch b/debian/patches-rt/0046-printk-Add-kthread-for-all-legacy-consoles.patch index 73a0c337be..e29281db8f 100644 --- a/debian/patches-rt/0048-printk-Add-kthread-for-all-legacy-consoles.patch +++ b/debian/patches-rt/0046-printk-Add-kthread-for-all-legacy-consoles.patch @@ -1,82 +1,210 @@ From: John Ogness <john.ogness@linutronix.de> Date: Fri, 22 Sep 2023 17:35:04 +0000 -Subject: [PATCH 48/50] printk: Add kthread for all legacy consoles -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Subject: [PATCH 46/48] printk: Add kthread for all legacy consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz -The write callback of legacy consoles make use of spinlocks. +The write callback of legacy consoles makes use of spinlocks. This is not permitted with PREEMPT_RT in atomic contexts. -Create a new kthread to handle printing of all the legacy -consoles (and nbcon consoles if boot consoles are registered). +For PREEMPT_RT, create a new kthread to handle printing of all +the legacy consoles (and nbcon consoles if boot consoles are +registered). -Since the consoles are printing in a task context, it is no -longer appropriate to support the legacy handover mechanism. +Since, if running from the kthread, the consoles are printing +in a task context, the legacy nbcon printing can use the +device_lock(), write_thread(), device_unlock() callbacks for +printing. -These changes exist only for CONFIG_PREEMPT_RT. +Introduce the macro force_printkthreads() to query if the +forced threading of legacy consoles is in effect. + +These changes only affect CONFIG_PREEMPT_RT. Signed-off-by: John Ogness <john.ogness@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/printk/internal.h | 1 - kernel/printk/nbcon.c | 18 ++- - kernel/printk/printk.c | 237 +++++++++++++++++++++++++++++++++++++++-------- - 3 files changed, 210 insertions(+), 46 deletions(-) + kernel/printk/internal.h | 20 +++ + kernel/printk/nbcon.c | 50 +++++---- + kernel/printk/printk.c | 252 +++++++++++++++++++++++++++++++++++++---------- + 3 files changed, 251 insertions(+), 71 deletions(-) --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h -@@ -95,6 +95,7 @@ void nbcon_atomic_flush_all(void); - bool nbcon_atomic_emit_next_record(struct console *con, bool *handover, int cookie); +@@ -21,6 +21,12 @@ int devkmsg_sysctl_set_loglvl(struct ctl + (con->flags & CON_BOOT) ? "boot" : "", \ + con->name, con->index, ##__VA_ARGS__) + ++#ifdef CONFIG_PREEMPT_RT ++# define force_printkthreads() (true) ++#else ++# define force_printkthreads() (false) ++#endif ++ + #ifdef CONFIG_PRINTK + + #ifdef CONFIG_PRINTK_CALLER +@@ -90,9 +96,10 @@ void nbcon_free(struct console *con); + enum nbcon_prio nbcon_get_default_prio(void); + void nbcon_atomic_flush_pending(void); + bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, +- int cookie); ++ int cookie, bool use_atomic); void nbcon_kthread_create(struct console *con); void nbcon_wake_threads(void); +void nbcon_legacy_kthread_create(void); /* * Check if the given console is currently capable and allowed to print +@@ -179,7 +186,7 @@ static inline void nbcon_free(struct con + static inline enum nbcon_prio nbcon_get_default_prio(void) { return NBCON_PRIO_NONE; } + static inline void nbcon_atomic_flush_pending(void) { } + static inline bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, +- int cookie) { return false; } ++ int cookie, bool use_atomic) { return false; } + + static inline bool console_is_usable(struct console *con, short flags, + bool use_atomic) { return false; } +@@ -187,6 +194,15 @@ static inline bool console_is_usable(str + #endif /* CONFIG_PRINTK */ + + extern bool have_boot_console; ++extern bool have_legacy_console; ++ ++/* ++ * Specifies if the console lock/unlock dance is needed for console ++ * printing. If @have_boot_console is true, the nbcon consoles will ++ * be printed serially along with the legacy consoles because nbcon ++ * consoles cannot print simultaneously with boot consoles. ++ */ ++#define printing_via_unlock (have_legacy_console || have_boot_console) + + extern struct printk_buffers printk_shared_pbufs; + --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c -@@ -1247,9 +1247,11 @@ bool nbcon_atomic_emit_next_record(struc +@@ -1202,9 +1202,10 @@ static __ref unsigned int *nbcon_get_cpu + } + + /** +- * nbcon_atomic_emit_one - Print one record for an nbcon console using the +- * write_atomic() callback ++ * nbcon_emit_one - Print one record for an nbcon console using the ++ * specified callback + * @wctxt: An initialized write context struct to use for this context ++ * @use_atomic: True if the write_atomic callback is to be used + * + * Return: False if it is known there are no more records to print, + * otherwise true. +@@ -1212,7 +1213,7 @@ static __ref unsigned int *nbcon_get_cpu + * This is an internal helper to handle the locking of the console before + * calling nbcon_emit_next_record(). + */ +-static bool nbcon_atomic_emit_one(struct nbcon_write_context *wctxt) ++static bool nbcon_emit_one(struct nbcon_write_context *wctxt, bool use_atomic) + { + struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); + +@@ -1224,7 +1225,7 @@ static bool nbcon_atomic_emit_one(struct + * handed over or taken over. In both cases the context is no + * longer valid. + */ +- if (!nbcon_emit_next_record(wctxt, true)) ++ if (!nbcon_emit_next_record(wctxt, use_atomic)) + return true; + + nbcon_context_release(ctxt); +@@ -1263,6 +1264,7 @@ enum nbcon_prio nbcon_get_default_prio(v + * both the console_lock and the SRCU read lock. Otherwise it + * is set to false. + * @cookie: The cookie from the SRCU read lock. ++ * @use_atomic: True if the write_atomic callback is to be used + * + * Context: Any context except NMI. + * Return: False if the given console has no next record to print, +@@ -1273,7 +1275,7 @@ enum nbcon_prio nbcon_get_default_prio(v + * Essentially it is the nbcon version of console_emit_next_record(). + */ + bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, +- int cookie) ++ int cookie, bool use_atomic) + { + struct nbcon_write_context wctxt = { }; + struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); +@@ -1282,19 +1284,29 @@ bool nbcon_legacy_emit_next_record(struc + *handover = false; - /* Use the same locking order as console_emit_next_record(). */ +- /* Use the same procedure as console_emit_next_record(). */ - printk_safe_enter_irqsave(flags); - console_lock_spinning_enable(); - stop_critical_timings(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) { -+ printk_safe_enter_irqsave(flags); -+ console_lock_spinning_enable(); -+ stop_critical_timings(); -+ } - - con->driver_enter(con, &driver_flags); - cant_migrate(); -@@ -1261,9 +1263,11 @@ bool nbcon_atomic_emit_next_record(struc - - con->driver_exit(con, driver_flags); - +- +- ctxt->console = con; +- ctxt->prio = nbcon_get_default_prio(); +- +- progress = nbcon_atomic_emit_one(&wctxt); +- - start_critical_timings(); - *handover = console_lock_spinning_disable_and_check(cookie); - printk_safe_exit_irqrestore(flags); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ ctxt->console = con; ++ ++ if (use_atomic) { ++ /* Use the same procedure as console_emit_next_record(). */ ++ printk_safe_enter_irqsave(flags); ++ console_lock_spinning_enable(); ++ stop_critical_timings(); ++ ++ ctxt->prio = nbcon_get_default_prio(); ++ progress = nbcon_emit_one(&wctxt, use_atomic); ++ + start_critical_timings(); + *handover = console_lock_spinning_disable_and_check(cookie); + printk_safe_exit_irqrestore(flags); ++ } else { ++ con->device_lock(con, &flags); ++ cant_migrate(); ++ ++ ctxt->prio = nbcon_get_default_prio(); ++ progress = nbcon_emit_one(&wctxt, use_atomic); ++ ++ con->device_unlock(con, flags); + } return progress; } -@@ -1469,6 +1473,8 @@ static int __init printk_setup_threads(v +@@ -1536,6 +1548,8 @@ static int __init printk_setup_threads(v printk_threads_enabled = true; for_each_console(con) nbcon_kthread_create(con); -+ if (IS_ENABLED(CONFIG_PREEMPT_RT) && printing_via_unlock) ++ if (force_printkthreads() && printing_via_unlock) + nbcon_legacy_kthread_create(); console_list_unlock(); return 0; } --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -487,6 +487,9 @@ bool have_boot_console; +@@ -468,7 +468,7 @@ static DEFINE_MUTEX(syslog_lock); + * present, it is necessary to perform the console lock/unlock dance + * whenever console flushing should occur. + */ +-static bool have_legacy_console; ++bool have_legacy_console; + /* + * Specifies if an nbcon console is registered. If nbcon consoles are present, +@@ -485,16 +485,11 @@ static bool have_nbcon_console; + */ + bool have_boot_console; + +-/* +- * Specifies if the console lock/unlock dance is needed for console +- * printing. If @have_boot_console is true, the nbcon consoles will +- * be printed serially along with the legacy consoles because nbcon +- * consoles cannot print simultaneously with boot consoles. +- */ +-#define printing_via_unlock (have_legacy_console || have_boot_console) +- #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); + @@ -85,17 +213,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* All 3 protected by @syslog_lock. */ /* the next printk record to read by syslog(READ) or /proc/kmsg */ static u64 syslog_seq; -@@ -2344,7 +2347,8 @@ asmlinkage int vprintk_emit(int facility +@@ -2358,7 +2353,8 @@ asmlinkage int vprintk_emit(int facility const struct dev_printk_info *dev_info, const char *fmt, va_list args) { - bool do_trylock_unlock = printing_via_unlock; + bool do_trylock_unlock = printing_via_unlock && -+ !IS_ENABLED(CONFIG_PREEMPT_RT); ++ !force_printkthreads(); int printed_len; /* Suppress unimportant messages after panic happens */ -@@ -2472,6 +2476,14 @@ EXPORT_SYMBOL(_printk); +@@ -2481,6 +2477,14 @@ EXPORT_SYMBOL(_printk); static bool pr_flush(int timeout_ms, bool reset_on_progress); static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress); @@ -110,7 +238,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #else /* CONFIG_PRINTK */ #define printk_time false -@@ -2485,6 +2497,8 @@ static u64 syslog_seq; +@@ -2494,6 +2498,8 @@ static u64 syslog_seq; static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; } static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; } @@ -119,7 +247,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #endif /* CONFIG_PRINTK */ #ifdef CONFIG_EARLY_PRINTK -@@ -2730,6 +2744,8 @@ void resume_console(void) +@@ -2739,6 +2745,8 @@ void resume_console(void) } console_srcu_read_unlock(cookie); @@ -128,17 +256,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> pr_flush(1000, true); } -@@ -2744,7 +2760,8 @@ void resume_console(void) +@@ -2753,7 +2761,8 @@ void resume_console(void) */ static int console_cpu_notify(unsigned int cpu) { - if (!cpuhp_tasks_frozen && printing_via_unlock) { + if (!cpuhp_tasks_frozen && printing_via_unlock && -+ !IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ !force_printkthreads()) { /* If trylock fails, someone else is doing the printing */ if (console_trylock()) console_unlock(); -@@ -2969,31 +2986,43 @@ static bool console_emit_next_record(str +@@ -3013,31 +3022,43 @@ static bool console_emit_next_record(str con->dropped = 0; } @@ -155,18 +283,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> - printk_safe_enter_irqsave(flags); - console_lock_spinning_enable(); + /* Write everything out to the hardware. */ - -- /* Do not trace print latency. */ -- stop_critical_timings(); -+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ ++ if (force_printkthreads()) { + /* -+ * On PREEMPT_RT this function is either in a thread or -+ * panic context. So there is no need for concern about ++ * With forced threading this function is either in a thread ++ * or panic context. So there is no need for concern about + * printk reentrance or handovers. + */ -- /* Write everything out to the hardware. */ -- con->write(con, outbuf, pmsg.outbuf_len); +- /* Do not trace print latency. */ +- stop_critical_timings(); + con->write(con, outbuf, pmsg.outbuf_len); + con->seq = pmsg.seq + 1; + } else { @@ -183,17 +309,19 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + printk_safe_enter_irqsave(flags); + console_lock_spinning_enable(); -- start_critical_timings(); +- /* Write everything out to the hardware. */ +- con->write(con, outbuf, pmsg.outbuf_len); + /* Do not trace print latency. */ + stop_critical_timings(); -- con->seq = pmsg.seq + 1; +- start_critical_timings(); + con->write(con, outbuf, pmsg.outbuf_len); +- con->seq = pmsg.seq + 1; ++ start_critical_timings(); + - *handover = console_lock_spinning_disable_and_check(cookie); - printk_safe_exit_irqrestore(flags); -+ start_critical_timings(); -+ + con->seq = pmsg.seq + 1; + + *handover = console_lock_spinning_disable_and_check(cookie); @@ -202,7 +330,23 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> skip: return true; } -@@ -3103,19 +3132,7 @@ static bool console_flush_all(bool do_co +@@ -3101,12 +3122,13 @@ static bool console_flush_all(bool do_co + if ((flags & CON_NBCON) && con->kthread) + continue; + +- if (!console_is_usable(con, flags, true)) ++ if (!console_is_usable(con, flags, !do_cond_resched)) + continue; + any_usable = true; + + if (flags & CON_NBCON) { +- progress = nbcon_legacy_emit_next_record(con, handover, cookie); ++ progress = nbcon_legacy_emit_next_record(con, handover, cookie, ++ !do_cond_resched); + printk_seq = nbcon_seq_read(con); + } else { + progress = console_emit_next_record(con, handover, cookie); +@@ -3145,19 +3167,7 @@ static bool console_flush_all(bool do_co return false; } @@ -223,7 +367,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { bool do_cond_resched; bool handover; -@@ -3159,6 +3176,32 @@ void console_unlock(void) +@@ -3201,6 +3211,32 @@ void console_unlock(void) */ } while (prb_read_valid(prb, next_seq, NULL) && console_trylock()); } @@ -243,10 +387,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +void console_unlock(void) +{ + /* -+ * PREEMPT_RT relies on kthread and atomic consoles for printing. -+ * It never attempts to print from console_unlock(). ++ * Forced threading relies on kthread and atomic consoles for ++ * printing. It never attempts to print from console_unlock(). + */ -+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ if (force_printkthreads()) { + __console_unlock(); + return; + } @@ -256,7 +400,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> EXPORT_SYMBOL(console_unlock); /** -@@ -3368,11 +3411,106 @@ void console_start(struct console *conso +@@ -3410,11 +3446,106 @@ void console_start(struct console *conso if (flags & CON_NBCON) nbcon_kthread_wake(console); @@ -338,7 +482,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + + lockdep_assert_held(&console_mutex); + -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ if (!force_printkthreads()) + return; + + if (!printk_threads_enabled || nbcon_legacy_kthread) @@ -363,15 +507,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static int __read_mostly keep_bootcon; static int __init keep_bootcon_setup(char *str) -@@ -3639,6 +3777,7 @@ void register_console(struct console *ne - nbcon_init(newcon); +@@ -3691,6 +3822,7 @@ void register_console(struct console *ne + newcon->seq = 0; } else { have_legacy_console = true; + nbcon_legacy_kthread_create(); } if (newcon->flags & CON_BOOT) -@@ -3777,6 +3916,13 @@ static int unregister_console_locked(str +@@ -3846,6 +3978,13 @@ static int unregister_console_locked(str nbcon_kthread_create(c); } @@ -385,7 +529,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return res; } -@@ -3936,8 +4082,12 @@ static bool __pr_flush(struct console *c +@@ -4004,8 +4143,12 @@ static bool __pr_flush(struct console *c seq = prb_next_reserve_seq(prb); @@ -396,19 +540,19 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + * Otherwise this function will just wait for the threaded printers + * to print up to @seq. + */ -+ if (printing_via_unlock && !IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ if (printing_via_unlock && !force_printkthreads()) { console_lock(); console_unlock(); } -@@ -4045,9 +4195,16 @@ static void wake_up_klogd_work_func(stru +@@ -4119,9 +4262,16 @@ static void wake_up_klogd_work_func(stru int pending = this_cpu_xchg(printk_pending, 0); if (pending & PRINTK_PENDING_OUTPUT) { - /* If trylock fails, someone else is doing the printing */ - if (console_trylock()) - console_unlock(); -+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) { -+ wake_up_interruptible(&legacy_wait); ++ if (force_printkthreads()) { ++ wake_up_legacy_kthread(); + } else { + /* + * If trylock fails, some other context diff --git a/debian/patches-rt/0046-serial-core-Provide-low-level-functions-to-port-lock.patch b/debian/patches-rt/0046-serial-core-Provide-low-level-functions-to-port-lock.patch deleted file mode 100644 index b6c03021b1..0000000000 --- a/debian/patches-rt/0046-serial-core-Provide-low-level-functions-to-port-lock.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Mon, 11 Dec 2023 09:19:18 +0000 -Subject: [PATCH 46/50] serial: core: Provide low-level functions to port lock -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -The nbcon console's driver_enter() and driver_exit() callbacks need -to lock the port lock in order to synchronize against other hardware -activity (such as adjusting baud rates). However, they cannot use -the uart_port_lock() wrappers because the printk subsystem will -perform nbcon locking after calling the driver_enter() callback. - -Provide low-level variants __uart_port_lock_irqsave() and -__uart_port_unlock_irqrestore() for this purpose. These are only -to be used by the driver_enter()/driver_exit() callbacks. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/serial_core.h | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/include/linux/serial_core.h -+++ b/include/linux/serial_core.h -@@ -681,6 +681,18 @@ static inline void uart_port_unlock_irqr - spin_unlock_irqrestore(&up->lock, flags); - } - -+/* Only for use in the console->driver_enter() callback. */ -+static inline void __uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) -+{ -+ spin_lock_irqsave(&up->lock, *flags); -+} -+ -+/* Only for use in the console->driver_exit() callback. */ -+static inline void __uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) -+{ -+ spin_unlock_irqrestore(&up->lock, flags); -+} -+ - static inline int serial_port_in(struct uart_port *up, int offset) - { - return up->serial_in(up, offset); diff --git a/debian/patches-rt/0047-printk-Provide-threadprintk-boot-argument.patch b/debian/patches-rt/0047-printk-Provide-threadprintk-boot-argument.patch new file mode 100644 index 0000000000..cc47be3205 --- /dev/null +++ b/debian/patches-rt/0047-printk-Provide-threadprintk-boot-argument.patch @@ -0,0 +1,96 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Tue, 6 Feb 2024 14:19:34 +0000 +Subject: [PATCH 47/48] printk: Provide threadprintk boot argument +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +For PREEMPT_RT, legacy console printing is performed in a dedicated +kthread. However, this behavior can also be interesting for other +preemption models as it minimizes the duration of printk() calls by +deferring all printing. + +Provide a new boot argument "threadprintk" that will create the +dedicated kthread for legacy console printing for !PREEMPT_RT +systems. + +The implementation is the same as "threadirqs" boot argument. + +Users should be aware that if this option is enabled, the shutdown, +reboot, and panic messages probably will not be visible on the +legacy consoles. + +Non-legacy consoles (NBCON) already have their own dedicated kernel +threads for printing and reliable shutdown, reboot, and panic +printing. This option really only applies to legacy consoles. + +Users can view /proc/consoles to see if their console driver is +legacy or not. NBCON console drivers are shown with 'N'. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + Documentation/admin-guide/kernel-parameters.txt | 12 ++++++++++++ + kernel/printk/internal.h | 4 +++- + kernel/printk/printk.c | 11 +++++++++++ + 3 files changed, 26 insertions(+), 1 deletion(-) + +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -6508,6 +6508,18 @@ + Force threading of all interrupt handlers except those + marked explicitly IRQF_NO_THREAD. + ++ threadprintk [KNL] ++ Force threaded printing of all legacy consoles. Be ++ aware that with this option, the shutdown, reboot, and ++ panic messages may not be printed on the legacy ++ consoles. Also, earlycon/earlyprintk printing will be ++ delayed until a regular console or the kthread is ++ available. ++ ++ Users can view /proc/consoles to see if their console ++ driver is legacy or not. Non-legacy (NBCON) console ++ drivers are already threaded and are shown with 'N'. ++ + topology= [S390] + Format: {off | on} + Specify if the kernel should make use of the cpu +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -3,6 +3,7 @@ + * internal.h - printk internal definitions + */ + #include <linux/console.h> ++#include <linux/jump_label.h> + #include <linux/percpu.h> + #include <linux/types.h> + +@@ -24,7 +25,8 @@ int devkmsg_sysctl_set_loglvl(struct ctl + #ifdef CONFIG_PREEMPT_RT + # define force_printkthreads() (true) + #else +-# define force_printkthreads() (false) ++DECLARE_STATIC_KEY_FALSE(force_printkthreads_key); ++# define force_printkthreads() (static_branch_unlikely(&force_printkthreads_key)) + #endif + + #ifdef CONFIG_PRINTK +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -195,6 +195,17 @@ static int __init control_devkmsg(char * + } + __setup("printk.devkmsg=", control_devkmsg); + ++#if !defined(CONFIG_PREEMPT_RT) ++DEFINE_STATIC_KEY_FALSE(force_printkthreads_key); ++ ++static int __init setup_forced_printkthreads(char *arg) ++{ ++ static_branch_enable(&force_printkthreads_key); ++ return 0; ++} ++early_param("threadprintk", setup_forced_printkthreads); ++#endif ++ + char devkmsg_log_str[DEVKMSG_STR_MAX_SIZE] = "ratelimit"; + #if defined(CONFIG_PRINTK) && defined(CONFIG_SYSCTL) + int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, diff --git a/debian/patches-rt/0048-printk-Avoid-false-positive-lockdep-report-for-legac.patch b/debian/patches-rt/0048-printk-Avoid-false-positive-lockdep-report-for-legac.patch new file mode 100644 index 0000000000..510b3c0808 --- /dev/null +++ b/debian/patches-rt/0048-printk-Avoid-false-positive-lockdep-report-for-legac.patch @@ -0,0 +1,86 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Mon, 11 Dec 2023 09:34:16 +0000 +Subject: [PATCH 48/48] printk: Avoid false positive lockdep report for legacy + printing +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Legacy console printing from printk() caller context may invoke +the console driver from atomic context. This leads to a lockdep +splat because the console driver will acquire a sleeping lock +and the caller may already hold a spinning lock. This is noticed +by lockdep on !PREEMPT_RT configurations because it will lead to +a problem on PREEMPT_RT. + +However, on PREEMPT_RT the printing path from atomic context is +always avoided and the console driver is always invoked from a +dedicated thread. Thus the lockdep splat on !PREEMPT_RT is a +false positive. + +For !PREEMPT_RT override the lock-context before invoking the +console driver to avoid the false positive. + +Do not override the lock-context for PREEMPT_RT in order to +allow lockdep to catch any real locking context issues related +to the write callback usage. + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/printk/printk.c | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2985,6 +2985,33 @@ bool printk_get_next_message(struct prin + } + + /* ++ * Legacy console printing from printk() caller context does not respect ++ * raw_spinlock/spinlock nesting. For !PREEMPT_RT the lockdep warning is a ++ * false positive. For PREEMPT_RT the false positive condition does not ++ * occur. ++ * ++ * This map is used to establish LD_WAIT_SLEEP context for the console write ++ * callbacks when legacy printing to avoid false positive lockdep complaints, ++ * thus allowing lockdep to continue to function for real issues. ++ */ ++#ifdef CONFIG_PREEMPT_RT ++static inline void printk_legacy_lock_map_acquire_try(void) { } ++static inline void printk_legacy_lock_map_release(void) { } ++#else ++static DEFINE_WAIT_OVERRIDE_MAP(printk_legacy_map, LD_WAIT_SLEEP); ++ ++static inline void printk_legacy_lock_map_acquire_try(void) ++{ ++ lock_map_acquire_try(&printk_legacy_map); ++} ++ ++static inline void printk_legacy_lock_map_release(void) ++{ ++ lock_map_release(&printk_legacy_map); ++} ++#endif /* CONFIG_PREEMPT_RT */ ++ ++/* + * Used as the printk buffers for non-panic, serialized console printing. + * This is for legacy (!CON_NBCON) as well as all boot (CON_BOOT) consoles. + * Its usage requires the console_lock held. +@@ -3039,7 +3066,7 @@ static bool console_emit_next_record(str + /* + * With forced threading this function is either in a thread + * or panic context. So there is no need for concern about +- * printk reentrance or handovers. ++ * printk reentrance, handovers, or lockdep complaints. + */ + + con->write(con, outbuf, pmsg.outbuf_len); +@@ -3061,7 +3088,9 @@ static bool console_emit_next_record(str + /* Do not trace print latency. */ + stop_critical_timings(); + ++ printk_legacy_lock_map_acquire_try(); + con->write(con, outbuf, pmsg.outbuf_len); ++ printk_legacy_lock_map_release(); + + start_critical_timings(); + diff --git a/debian/patches-rt/0050-printk-Avoid-false-positive-lockdep-report-for-legac.patch b/debian/patches-rt/0050-printk-Avoid-false-positive-lockdep-report-for-legac.patch deleted file mode 100644 index 7c9f453664..0000000000 --- a/debian/patches-rt/0050-printk-Avoid-false-positive-lockdep-report-for-legac.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: John Ogness <john.ogness@linutronix.de> -Date: Mon, 11 Dec 2023 09:34:16 +0000 -Subject: [PATCH 50/50] printk: Avoid false positive lockdep report for legacy - driver. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -printk may invoke the legacy console driver from atomic context. This leads to -a lockdep splat because the console driver will acquire a sleeping lock and the -caller may also hold a spinning lock. This is noticed by lockdep on !PREEMPT_RT -configurations because it will also lead to a problem on PREEMPT_RT. - -On PREEMPT_RT the atomic path is always avoided and the console driver is -always invoked from a dedicated thread. Thus the lockdep splat is a false -positive. - -Override the lock-context before invoking the console driver. - -Signed-off-by: John Ogness <john.ogness@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/printk/printk.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -2824,6 +2824,8 @@ static void __console_unlock(void) - up_console_sem(); - } - -+static DEFINE_WAIT_OVERRIDE_MAP(printk_legacy_map, LD_WAIT_SLEEP); -+ - #ifdef CONFIG_PRINTK - - /* -@@ -2992,7 +2994,7 @@ static bool console_emit_next_record(str - /* - * On PREEMPT_RT this function is either in a thread or - * panic context. So there is no need for concern about -- * printk reentrance or handovers. -+ * printk reentrance, handovers, or lockdep complaints. - */ - - con->write(con, outbuf, pmsg.outbuf_len); -@@ -3014,7 +3016,9 @@ static bool console_emit_next_record(str - /* Do not trace print latency. */ - stop_critical_timings(); - -+ lock_map_acquire_try(&printk_legacy_map); - con->write(con, outbuf, pmsg.outbuf_len); -+ lock_map_release(&printk_legacy_map); - - start_critical_timings(); - -@@ -3091,7 +3095,10 @@ static bool console_flush_all(bool do_co - any_usable = true; - - if (flags & CON_NBCON) { -+ -+ lock_map_acquire_try(&printk_legacy_map); - progress = nbcon_atomic_emit_next_record(con, handover, cookie); -+ lock_map_release(&printk_legacy_map); - - printk_seq = nbcon_seq_read(con); - } else { diff --git a/debian/patches-rt/ARM64__Allow_to_enable_RT.patch b/debian/patches-rt/ARM64__Allow_to_enable_RT.patch index e89d7841ae..9f85cf15b9 100644 --- a/debian/patches-rt/ARM64__Allow_to_enable_RT.patch +++ b/debian/patches-rt/ARM64__Allow_to_enable_RT.patch @@ -1,7 +1,7 @@ Subject: ARM64: Allow to enable RT From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri Oct 11 13:14:35 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> @@ -17,7 +17,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -97,6 +97,7 @@ config ARM64 +@@ -98,6 +98,7 @@ config ARM64 select ARCH_SUPPORTS_NUMA_BALANCING select ARCH_SUPPORTS_PAGE_TABLE_CHECK select ARCH_SUPPORTS_PER_VMA_LOCK diff --git a/debian/patches-rt/ARM__Allow_to_enable_RT.patch b/debian/patches-rt/ARM__Allow_to_enable_RT.patch index b5749a71ea..08fb67f116 100644 --- a/debian/patches-rt/ARM__Allow_to_enable_RT.patch +++ b/debian/patches-rt/ARM__Allow_to_enable_RT.patch @@ -1,7 +1,7 @@ Subject: ARM: Allow to enable RT From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri Oct 11 13:14:29 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> @@ -17,7 +17,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -36,6 +36,7 @@ +@@ -36,6 +36,7 @@ config ARM select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_HUGETLBFS if ARM_LPAE select ARCH_SUPPORTS_PER_VMA_LOCK @@ -25,7 +25,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF select ARCH_USE_MEMTEST -@@ -120,6 +121,7 @@ +@@ -120,6 +121,7 @@ config ARM select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP diff --git a/debian/patches-rt/ARM__enable_irq_in_translation_section_permission_fault_handlers.patch b/debian/patches-rt/ARM__enable_irq_in_translation_section_permission_fault_handlers.patch index b8c3c370fb..9ca02d6a8b 100644 --- a/debian/patches-rt/ARM__enable_irq_in_translation_section_permission_fault_handlers.patch +++ b/debian/patches-rt/ARM__enable_irq_in_translation_section_permission_fault_handlers.patch @@ -1,7 +1,7 @@ Subject: ARM: enable irq in translation/section permission fault handlers From: Yadi.hu <yadi.hu@windriver.com> Date: Wed Dec 10 10:32:09 2014 +0800 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Yadi.hu <yadi.hu@windriver.com> @@ -69,7 +69,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c -@@ -404,6 +404,9 @@ do_translation_fault(unsigned long addr, +@@ -436,6 +436,9 @@ do_translation_fault(unsigned long addr, if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); @@ -79,7 +79,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (user_mode(regs)) goto bad_area; -@@ -474,6 +477,9 @@ do_translation_fault(unsigned long addr, +@@ -506,6 +509,9 @@ do_translation_fault(unsigned long addr, static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { diff --git a/debian/patches-rt/Add_localversion_for_-RT_release.patch b/debian/patches-rt/Add_localversion_for_-RT_release.patch index 7a09b5ac27..1dbdcfcb68 100644 --- a/debian/patches-rt/Add_localversion_for_-RT_release.patch +++ b/debian/patches-rt/Add_localversion_for_-RT_release.patch @@ -1,7 +1,7 @@ Subject: Add localversion for -RT release From: Thomas Gleixner <tglx@linutronix.de> Date: Fri Jul 8 20:25:16 2011 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Thomas Gleixner <tglx@linutronix.de> @@ -16,4 +16,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- /dev/null +++ b/localversion-rt @@ -0,0 +1 @@ -+-rt6 ++-rt11 diff --git a/debian/patches-rt/POWERPC__Allow_to_enable_RT.patch b/debian/patches-rt/POWERPC__Allow_to_enable_RT.patch index 12443b10dc..34d9aae651 100644 --- a/debian/patches-rt/POWERPC__Allow_to_enable_RT.patch +++ b/debian/patches-rt/POWERPC__Allow_to_enable_RT.patch @@ -1,7 +1,7 @@ Subject: POWERPC: Allow to enable RT From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri Oct 11 13:14:41 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> @@ -25,7 +25,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF if PPC64 select ARCH_USE_MEMTEST -@@ -269,6 +270,7 @@ config PPC +@@ -270,6 +271,7 @@ config PPC select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RELIABLE_STACKTRACE diff --git a/debian/patches-rt/PREEMPT_AUTO.patch b/debian/patches-rt/PREEMPT_AUTO.patch index 323b18f798..338abae7c3 100644 --- a/debian/patches-rt/PREEMPT_AUTO.patch +++ b/debian/patches-rt/PREEMPT_AUTO.patch @@ -1,7 +1,7 @@ From: Thomas Gleixner <tglx@linutronix.de> Date: Sat, 23 Sep 2023 03:11:05 +0200 Subject: [PATCH] sched: define TIF_ALLOW_RESCHED -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz On Fri, Sep 22 2023 at 00:55, Thomas Gleixner wrote: > On Thu, Sep 21 2023 at 09:00, Linus Torvalds wrote: @@ -122,7 +122,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -272,6 +272,7 @@ config X86 +@@ -277,6 +277,7 @@ config X86 select HAVE_STATIC_CALL select HAVE_STATIC_CALL_INLINE if HAVE_OBJTOOL select HAVE_PREEMPT_DYNAMIC_CALL @@ -165,7 +165,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h -@@ -60,7 +60,7 @@ +@@ -65,7 +65,7 @@ #define EXIT_TO_USER_MODE_WORK \ (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ _TIF_NEED_RESCHED | _TIF_PATCH_PENDING | _TIF_NOTIFY_SIGNAL | \ @@ -187,7 +187,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -2055,17 +2055,17 @@ static inline void update_tsk_thread_fla +@@ -1934,17 +1934,17 @@ static inline void update_tsk_thread_fla update_ti_thread_flag(task_thread_info(tsk), flag, value); } @@ -208,7 +208,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { return test_ti_thread_flag(task_thread_info(tsk), flag); } -@@ -2078,9 +2078,11 @@ static inline void set_tsk_need_resched( +@@ -1957,9 +1957,11 @@ static inline void set_tsk_need_resched( static inline void clear_tsk_need_resched(struct task_struct *tsk) { clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); @@ -221,7 +221,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); } -@@ -2261,7 +2263,7 @@ static inline int rwlock_needbreak(rwloc +@@ -2100,7 +2102,7 @@ static inline bool preempt_model_preempt static __always_inline bool need_resched(void) { @@ -383,7 +383,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> default y if HAVE_PREEMPT_DYNAMIC_CALL --- a/kernel/entry/common.c +++ b/kernel/entry/common.c -@@ -155,7 +155,7 @@ static unsigned long exit_to_user_mode_l +@@ -92,7 +92,7 @@ void __weak arch_do_signal_or_restart(st local_irq_enable_exit_to_user(ti_work); @@ -392,7 +392,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> schedule(); if (ti_work & _TIF_UPROBE) -@@ -385,7 +385,7 @@ void raw_irqentry_exit_cond_resched(void +@@ -301,7 +301,7 @@ void raw_irqentry_exit_cond_resched(void rcu_irq_exit_check_preempt(); if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) WARN_ON_ONCE(!on_thread_stack()); @@ -414,7 +414,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (ti_work & _TIF_NOTIFY_RESUME) --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -898,14 +898,15 @@ static inline void hrtick_rq_init(struct +@@ -899,14 +899,15 @@ static inline void hrtick_rq_init(struct #if defined(CONFIG_SMP) && defined(TIF_POLLING_NRFLAG) /* @@ -433,7 +433,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* -@@ -922,7 +923,7 @@ static bool set_nr_if_polling(struct tas +@@ -923,7 +924,7 @@ static bool set_nr_if_polling(struct tas do { if (!(val & _TIF_POLLING_NRFLAG)) return false; @@ -442,7 +442,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return true; } while (!try_cmpxchg(&ti->flags, &val, val | _TIF_NEED_RESCHED)); -@@ -930,9 +931,9 @@ static bool set_nr_if_polling(struct tas +@@ -931,9 +932,9 @@ static bool set_nr_if_polling(struct tas } #else @@ -454,7 +454,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return true; } -@@ -1037,28 +1038,47 @@ void wake_up_q(struct wake_q_head *head) +@@ -1038,28 +1039,47 @@ void wake_up_q(struct wake_q_head *head) * might also involve a cross-CPU call to trigger the scheduler on * the target CPU. */ @@ -510,10 +510,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } void resched_cpu(int cpu) -@@ -1131,7 +1151,7 @@ static void wake_up_idle_cpu(int cpu) - if (cpu == smp_processor_id()) - return; - +@@ -1154,7 +1174,7 @@ static void wake_up_idle_cpu(int cpu) + * and testing of the above solutions didn't appear to report + * much benefits. + */ - if (set_nr_and_not_polling(rq->idle)) + if (set_nr_and_not_polling(rq->idle, TIF_NEED_RESCHED)) smp_send_reschedule(cpu); @@ -556,7 +556,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> late_initcall(sched_init_debug); --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c -@@ -1001,8 +1001,10 @@ static void clear_buddies(struct cfs_rq +@@ -975,8 +975,10 @@ static void clear_buddies(struct cfs_rq * XXX: strictly: vd_i += N*r_i/w_i such that: vd_i > ve_i * this is probably good enough. */ @@ -568,7 +568,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if ((s64)(se->vruntime - se->deadline) < 0) return; -@@ -1021,10 +1023,19 @@ static void update_deadline(struct cfs_r +@@ -995,10 +997,19 @@ static void update_deadline(struct cfs_r /* * The task has consumed its request, reschedule. */ @@ -591,7 +591,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } #include "pelt.h" -@@ -1132,7 +1143,7 @@ static void update_tg_load_avg(struct cf +@@ -1153,7 +1164,7 @@ s64 update_curr_common(struct rq *rq) /* * Update the current task's runtime statistics. */ @@ -599,17 +599,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +static void __update_curr(struct cfs_rq *cfs_rq, bool tick) { struct sched_entity *curr = cfs_rq->curr; - u64 now = rq_clock_task(rq_of(cfs_rq)); -@@ -1159,7 +1170,7 @@ static void update_curr(struct cfs_rq *c - schedstat_add(cfs_rq->exec_clock, delta_exec); + s64 delta_exec; +@@ -1166,7 +1177,7 @@ static void update_curr(struct cfs_rq *c + return; curr->vruntime += calc_delta_fair(delta_exec, curr); - update_deadline(cfs_rq, curr); + update_deadline(cfs_rq, curr, tick); update_min_vruntime(cfs_rq); - if (entity_is_task(curr)) { -@@ -1173,6 +1184,11 @@ static void update_curr(struct cfs_rq *c + if (entity_is_task(curr)) +@@ -1175,6 +1186,11 @@ static void update_curr(struct cfs_rq *c account_cfs_rq_runtime(cfs_rq, delta_exec); } @@ -621,7 +621,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static void update_curr_fair(struct rq *rq) { update_curr(cfs_rq_of(&rq->curr->se)); -@@ -5449,7 +5465,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc +@@ -5493,7 +5509,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc /* * Update run-time statistics of the 'current'. */ @@ -630,7 +630,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Ensure that runnable average is periodically updated. -@@ -5463,7 +5479,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc +@@ -5507,7 +5523,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc * validating it and just reschedule. */ if (queued) { @@ -639,7 +639,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return; } /* -@@ -5609,7 +5625,7 @@ static void __account_cfs_rq_runtime(str +@@ -5653,7 +5669,7 @@ static void __account_cfs_rq_runtime(str * hierarchy can be throttled */ if (!assign_cfs_rq_runtime(cfs_rq) && likely(cfs_rq->curr)) @@ -648,7 +648,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static __always_inline -@@ -5869,7 +5885,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cf +@@ -5913,7 +5929,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cf /* Determine whether we need to wake up potentially idle CPU: */ if (rq->curr == rq->idle && rq->cfs.nr_running) @@ -657,7 +657,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } #ifdef CONFIG_SMP -@@ -6584,7 +6600,7 @@ static void hrtick_start_fair(struct rq +@@ -6628,7 +6644,7 @@ static void hrtick_start_fair(struct rq if (delta < 0) { if (task_current(rq, p)) @@ -666,7 +666,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return; } hrtick_start(rq, delta); -@@ -8240,7 +8256,7 @@ static void check_preempt_wakeup_fair(st +@@ -8304,7 +8320,7 @@ static void check_preempt_wakeup_fair(st * prevents us from potentially nominating it as a false LAST_BUDDY * below. */ @@ -675,7 +675,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return; /* Idle tasks are by definition preempted by non-idle tasks. */ -@@ -8282,7 +8298,7 @@ static void check_preempt_wakeup_fair(st +@@ -8346,7 +8362,7 @@ static void check_preempt_wakeup_fair(st return; preempt: @@ -684,7 +684,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } #ifdef CONFIG_SMP -@@ -12449,7 +12465,7 @@ static inline void task_tick_core(struct +@@ -12516,7 +12532,7 @@ static inline void task_tick_core(struct */ if (rq->core->core_forceidle_count && rq->cfs.nr_running == 1 && __entity_slice_used(&curr->se, MIN_NR_TASKS_DURING_FORCEIDLE)) @@ -693,7 +693,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* -@@ -12614,7 +12630,7 @@ prio_changed_fair(struct rq *rq, struct +@@ -12681,7 +12697,7 @@ prio_changed_fair(struct rq *rq, struct */ if (task_current(rq, p)) { if (p->prio > oldprio) @@ -704,7 +704,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } --- a/kernel/sched/features.h +++ b/kernel/sched/features.h -@@ -88,3 +88,5 @@ SCHED_FEAT(UTIL_EST_FASTUP, true) +@@ -87,3 +87,5 @@ SCHED_FEAT(UTIL_EST, true) SCHED_FEAT(LATENCY_WARN, false) SCHED_FEAT(HZ_BW, true) @@ -724,7 +724,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h -@@ -2419,6 +2419,7 @@ extern void init_sched_fair_class(void); +@@ -2463,6 +2463,7 @@ extern void init_sched_fair_class(void); extern void reweight_task(struct task_struct *p, int prio); extern void resched_curr(struct rq *rq); @@ -734,7 +734,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> extern struct rt_bandwidth def_rt_bandwidth; --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -2723,6 +2723,8 @@ unsigned int tracing_gen_ctx_irq_test(un +@@ -2717,6 +2717,8 @@ unsigned int tracing_gen_ctx_irq_test(un if (tif_need_resched()) trace_flags |= TRACE_FLAG_NEED_RESCHED; diff --git a/debian/patches-rt/Revert-drm-i915-Depend-on-PREEMPT_RT.patch b/debian/patches-rt/Revert-drm-i915-Depend-on-PREEMPT_RT.patch index 1797f4ee2d..9c05d2aeb7 100644 --- a/debian/patches-rt/Revert-drm-i915-Depend-on-PREEMPT_RT.patch +++ b/debian/patches-rt/Revert-drm-i915-Depend-on-PREEMPT_RT.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Mon, 21 Feb 2022 17:59:14 +0100 Subject: [PATCH] Revert "drm/i915: Depend on !PREEMPT_RT." -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Once the known issues are addressed, it should be safe to enable the driver. diff --git a/debian/patches-rt/arm-Disable-FAST_GUP-on-PREEMPT_RT-if-HIGHPTE-is-als.patch b/debian/patches-rt/arm-Disable-FAST_GUP-on-PREEMPT_RT-if-HIGHPTE-is-als.patch new file mode 100644 index 0000000000..09dcd78d53 --- /dev/null +++ b/debian/patches-rt/arm-Disable-FAST_GUP-on-PREEMPT_RT-if-HIGHPTE-is-als.patch @@ -0,0 +1,35 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Tue, 23 Jan 2024 12:56:21 +0100 +Subject: [PATCH] arm: Disable FAST_GUP on PREEMPT_RT if HIGHPTE is also + enabled. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +gup_pgd_range() is invoked with disabled interrupts and invokes +__kmap_local_page_prot() via pte_offset_map(), gup_p4d_range(). +With HIGHPTE enabled, __kmap_local_page_prot() invokes kmap_high_get() +which uses a spinlock_t via lock_kmap_any(). This leads to an +sleeping-while-atomic error on PREEMPT_RT because spinlock_t becomes a +sleeping lock and must not be acquired in atomic context. + +The loop in map_new_virtual() uses wait_queue_head_t for wake up which +also is using a spinlock_t. + +Limit HAVE_FAST_GUP additionaly to remain disabled on PREEMPT_RT with +HIGHPTE enabled. + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + arch/arm/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -98,7 +98,7 @@ config ARM + select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE + select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU + select HAVE_EXIT_THREAD +- select HAVE_FAST_GUP if ARM_LPAE ++ select HAVE_FAST_GUP if ARM_LPAE && !(PREEMPT_RT && HIGHPTE) + select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL + select HAVE_FUNCTION_ERROR_INJECTION + select HAVE_FUNCTION_GRAPH_TRACER diff --git a/debian/patches-rt/drm-i915-guc-Consider-also-RCU-depth-in-busy-loop.patch b/debian/patches-rt/drm-i915-guc-Consider-also-RCU-depth-in-busy-loop.patch index 0ed0ac24ae..76342bd2d7 100644 --- a/debian/patches-rt/drm-i915-guc-Consider-also-RCU-depth-in-busy-loop.patch +++ b/debian/patches-rt/drm-i915-guc-Consider-also-RCU-depth-in-busy-loop.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Tue, 3 Oct 2023 21:37:21 +0200 Subject: [PATCH] drm/i915/guc: Consider also RCU depth in busy loop. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz intel_guc_send_busy_loop() looks at in_atomic() and irqs_disabled() to decide if it should busy-spin while waiting or if it may sleep. @@ -18,7 +18,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h -@@ -349,7 +349,7 @@ static inline int intel_guc_send_busy_lo +@@ -362,7 +362,7 @@ static inline int intel_guc_send_busy_lo { int err; unsigned int sleep_period_ms = 1; diff --git a/debian/patches-rt/net-Avoid-the-IPI-to-free-the.patch b/debian/patches-rt/net-Avoid-the-IPI-to-free-the.patch deleted file mode 100644 index 70bfac405a..0000000000 --- a/debian/patches-rt/net-Avoid-the-IPI-to-free-the.patch +++ /dev/null @@ -1,119 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Mon, 15 Aug 2022 17:29:50 +0200 -Subject: [PATCH] net: Avoid the IPI to free the -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -skb_attempt_defer_free() collects a skbs, which was allocated on a -remote CPU, on a per-CPU list. These skbs are either freed on that -remote CPU once the CPU enters NET_RX or an remote IPI function is -invoked in to raise the NET_RX softirq if a threshold of pending skb has -been exceeded. -This remote IPI can cause the wakeup of ksoftirqd on PREEMPT_RT if the -remote CPU idle was idle. This is undesired because once the ksoftirqd -is running it will acquire all pending softirqs and they will not be -executed as part of the threaded interrupt until ksoftird goes idle -again. - -To void all this, schedule the deferred clean up from a worker. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/netdevice.h | 4 ++++ - net/core/dev.c | 39 ++++++++++++++++++++++++++++++--------- - net/core/skbuff.c | 7 ++++++- - 3 files changed, 40 insertions(+), 10 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -3288,7 +3288,11 @@ struct softnet_data { - int defer_count; - int defer_ipi_scheduled; - struct sk_buff *defer_list; -+#ifndef CONFIG_PREEMPT_RT - call_single_data_t defer_csd; -+#else -+ struct work_struct defer_work; -+#endif - }; - - static inline void input_queue_head_incr(struct softnet_data *sd) ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -4679,15 +4679,6 @@ static void rps_trigger_softirq(void *da - - #endif /* CONFIG_RPS */ - --/* Called from hardirq (IPI) context */ --static void trigger_rx_softirq(void *data) --{ -- struct softnet_data *sd = data; -- -- __raise_softirq_irqoff(NET_RX_SOFTIRQ); -- smp_store_release(&sd->defer_ipi_scheduled, 0); --} -- - /* - * After we queued a packet into sd->input_pkt_queue, - * we need to make sure this queue is serviced soon. -@@ -6658,6 +6649,32 @@ static void skb_defer_free_flush(struct - } - } - -+#ifndef CONFIG_PREEMPT_RT -+ -+/* Called from hardirq (IPI) context */ -+static void trigger_rx_softirq(void *data) -+{ -+ struct softnet_data *sd = data; -+ -+ __raise_softirq_irqoff(NET_RX_SOFTIRQ); -+ smp_store_release(&sd->defer_ipi_scheduled, 0); -+} -+ -+#else -+ -+static void trigger_rx_softirq(struct work_struct *defer_work) -+{ -+ struct softnet_data *sd; -+ -+ sd = container_of(defer_work, struct softnet_data, defer_work); -+ smp_store_release(&sd->defer_ipi_scheduled, 0); -+ local_bh_disable(); -+ skb_defer_free_flush(sd); -+ local_bh_enable(); -+} -+ -+#endif -+ - static int napi_threaded_poll(void *data) - { - struct napi_struct *napi = data; -@@ -11621,7 +11638,11 @@ static int __init net_dev_init(void) - INIT_CSD(&sd->csd, rps_trigger_softirq, sd); - sd->cpu = i; - #endif -+#ifndef CONFIG_PREEMPT_RT - INIT_CSD(&sd->defer_csd, trigger_rx_softirq, sd); -+#else -+ INIT_WORK(&sd->defer_work, trigger_rx_softirq); -+#endif - spin_lock_init(&sd->defer_lock); - - init_gro_hash(&sd->backlog); ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -6858,8 +6858,13 @@ nodefer: __kfree_skb(skb); - /* Make sure to trigger NET_RX_SOFTIRQ on the remote CPU - * if we are unlucky enough (this seems very unlikely). - */ -- if (unlikely(kick) && !cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) -+ if (unlikely(kick) && !cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) { -+#ifndef CONFIG_PREEMPT_RT - smp_call_function_single_async(cpu, &sd->defer_csd); -+#else -+ schedule_work_on(cpu, &sd->defer_work); -+#endif -+ } - } - - static void skb_splice_csum_page(struct sk_buff *skb, struct page *page, diff --git a/debian/patches-rt/powerpc-pseries-Select-the-generic-memory-allocator.patch b/debian/patches-rt/powerpc-pseries-Select-the-generic-memory-allocator.patch index 35ced542ba..e1c231f6cb 100644 --- a/debian/patches-rt/powerpc-pseries-Select-the-generic-memory-allocator.patch +++ b/debian/patches-rt/powerpc-pseries-Select-the-generic-memory-allocator.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Thu, 9 Mar 2023 09:13:52 +0100 Subject: [PATCH] powerpc/pseries: Select the generic memory allocator. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The RTAS work area allocator is using the generic memory allocator and as such it must select it. diff --git a/debian/patches-rt/powerpc__traps__Use_PREEMPT_RT.patch b/debian/patches-rt/powerpc__traps__Use_PREEMPT_RT.patch index 7d9af1ed24..0b7d65c60a 100644 --- a/debian/patches-rt/powerpc__traps__Use_PREEMPT_RT.patch +++ b/debian/patches-rt/powerpc__traps__Use_PREEMPT_RT.patch @@ -1,7 +1,7 @@ Subject: powerpc: traps: Use PREEMPT_RT From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri Jul 26 11:30:49 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> diff --git a/debian/patches-rt/powerpc_kvm__Disable_in-kernel_MPIC_emulation_for_PREEMPT_RT.patch b/debian/patches-rt/powerpc_kvm__Disable_in-kernel_MPIC_emulation_for_PREEMPT_RT.patch index 0cb5032994..871e35c564 100644 --- a/debian/patches-rt/powerpc_kvm__Disable_in-kernel_MPIC_emulation_for_PREEMPT_RT.patch +++ b/debian/patches-rt/powerpc_kvm__Disable_in-kernel_MPIC_emulation_for_PREEMPT_RT.patch @@ -1,7 +1,7 @@ Subject: powerpc/kvm: Disable in-kernel MPIC emulation for PREEMPT_RT From: Bogdan Purcareata <bogdan.purcareata@freescale.com> Date: Fri Apr 24 15:53:13 2015 +0000 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Bogdan Purcareata <bogdan.purcareata@freescale.com> @@ -33,11 +33,11 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig -@@ -224,6 +224,7 @@ config KVM_E500MC +@@ -222,6 +222,7 @@ config KVM_E500MC config KVM_MPIC bool "KVM in-kernel MPIC emulation" depends on KVM && PPC_E500 + depends on !PREEMPT_RT select HAVE_KVM_IRQCHIP - select HAVE_KVM_IRQFD select HAVE_KVM_IRQ_ROUTING + select HAVE_KVM_MSI diff --git a/debian/patches-rt/powerpc_pseries_iommu__Use_a_locallock_instead_local_irq_save.patch b/debian/patches-rt/powerpc_pseries_iommu__Use_a_locallock_instead_local_irq_save.patch index db47dc2146..d88fbd396a 100644 --- a/debian/patches-rt/powerpc_pseries_iommu__Use_a_locallock_instead_local_irq_save.patch +++ b/debian/patches-rt/powerpc_pseries_iommu__Use_a_locallock_instead_local_irq_save.patch @@ -1,7 +1,7 @@ Subject: powerpc/pseries/iommu: Use a locallock instead local_irq_save() From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Tue Mar 26 18:31:54 2019 +0100 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> diff --git a/debian/patches-rt/powerpc_stackprotector__work_around_stack-guard_init_from_atomic.patch b/debian/patches-rt/powerpc_stackprotector__work_around_stack-guard_init_from_atomic.patch index 41f2983999..f61851260e 100644 --- a/debian/patches-rt/powerpc_stackprotector__work_around_stack-guard_init_from_atomic.patch +++ b/debian/patches-rt/powerpc_stackprotector__work_around_stack-guard_init_from_atomic.patch @@ -1,7 +1,7 @@ Subject: powerpc/stackprotector: work around stack-guard init from atomic From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Tue Mar 26 18:31:29 2019 +0100 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> diff --git a/debian/patches-rt/preempt-Put-preempt_enable-within-an-instrumentation.patch b/debian/patches-rt/preempt-Put-preempt_enable-within-an-instrumentation.patch deleted file mode 100644 index 9a39dab226..0000000000 --- a/debian/patches-rt/preempt-Put-preempt_enable-within-an-instrumentation.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 8 Mar 2023 16:29:38 +0100 -Subject: [PATCH] preempt: Put preempt_enable() within an instrumentation*() - section. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -Callers of preempt_enable() can be within an noinstr section leading to: -| vmlinux.o: warning: objtool: native_sched_clock+0x97: call to preempt_schedule_notrace_thunk() leaves .noinstr.text section -| vmlinux.o: warning: objtool: kvm_clock_read+0x22: call to preempt_schedule_notrace_thunk() leaves .noinstr.text section -| vmlinux.o: warning: objtool: local_clock+0xb4: call to preempt_schedule_notrace_thunk() leaves .noinstr.text section -| vmlinux.o: warning: objtool: enter_from_user_mode+0xea: call to preempt_schedule_thunk() leaves .noinstr.text section -| vmlinux.o: warning: objtool: syscall_enter_from_user_mode+0x140: call to preempt_schedule_thunk() leaves .noinstr.text section -| vmlinux.o: warning: objtool: syscall_enter_from_user_mode_prepare+0xf2: call to preempt_schedule_thunk() leaves .noinstr.text section -| vmlinux.o: warning: objtool: irqentry_enter_from_user_mode+0xea: call to preempt_schedule_thunk() leaves .noinstr.text section - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Link: https://lore.kernel.org/r/20230309072724.3F6zRkvw@linutronix.de ---- - include/linux/preempt.h | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - ---- a/include/linux/preempt.h -+++ b/include/linux/preempt.h -@@ -230,15 +230,21 @@ do { \ - #define preempt_enable() \ - do { \ - barrier(); \ -- if (unlikely(preempt_count_dec_and_test())) \ -+ if (unlikely(preempt_count_dec_and_test())) { \ -+ instrumentation_begin(); \ - __preempt_schedule(); \ -+ instrumentation_end(); \ -+ } \ - } while (0) - - #define preempt_enable_notrace() \ - do { \ - barrier(); \ -- if (unlikely(__preempt_count_dec_and_test())) \ -+ if (unlikely(__preempt_count_dec_and_test())) { \ -+ instrumentation_begin(); \ - __preempt_schedule_notrace(); \ -+ instrumentation_end(); \ -+ } \ - } while (0) - - #define preempt_check_resched() \ diff --git a/debian/patches-rt/rcutorture-Also-force-sched-priority-to-timersd-on-b.patch b/debian/patches-rt/rcutorture-Also-force-sched-priority-to-timersd-on-b.patch index 601db1b514..97f6c5b9bf 100644 --- a/debian/patches-rt/rcutorture-Also-force-sched-priority-to-timersd-on-b.patch +++ b/debian/patches-rt/rcutorture-Also-force-sched-priority-to-timersd-on-b.patch @@ -2,7 +2,7 @@ From: Frederic Weisbecker <frederic@kernel.org> Date: Tue, 5 Apr 2022 03:07:51 +0200 Subject: [PATCH] rcutorture: Also force sched priority to timersd on boosting test. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz ksoftirqd is statically boosted to the priority level right above the one of rcu_torture_boost() so that timers, which torture readers rely on, diff --git a/debian/patches-rt/riscv-add-PREEMPT_AUTO-support.patch b/debian/patches-rt/riscv-add-PREEMPT_AUTO-support.patch index 17219c0a1b..0158d653a0 100644 --- a/debian/patches-rt/riscv-add-PREEMPT_AUTO-support.patch +++ b/debian/patches-rt/riscv-add-PREEMPT_AUTO-support.patch @@ -1,7 +1,7 @@ From: Jisheng Zhang <jszhang@kernel.org> Date: Tue, 31 Oct 2023 22:35:20 +0800 Subject: [PATCH] riscv: add PREEMPT_AUTO support -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz riscv has switched to GENERIC_ENTRY, so adding PREEMPT_AUTO is as simple as adding TIF_ARCH_RESCHED_LAZY related definitions and enabling @@ -16,7 +16,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig -@@ -137,6 +137,7 @@ config RISCV +@@ -142,6 +142,7 @@ config RISCV select HAVE_PERF_USER_STACK_DUMP select HAVE_POSIX_CPU_TIMERS_TASK_WORK select HAVE_PREEMPT_DYNAMIC_KEY if !XIP_KERNEL @@ -26,7 +26,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> select HAVE_RSEQ --- a/arch/riscv/include/asm/thread_info.h +++ b/arch/riscv/include/asm/thread_info.h -@@ -95,6 +95,7 @@ int arch_dup_task_struct(struct task_str +@@ -94,6 +94,7 @@ int arch_dup_task_struct(struct task_str * - pending work-to-be-done flags are in lowest half-word * - other flags in upper half-word(s) */ @@ -34,11 +34,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ -@@ -109,6 +110,7 @@ int arch_dup_task_struct(struct task_str - #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) - #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) - #define _TIF_UPROBE (1 << TIF_UPROBE) -+#define _TIF_ARCH_RESCHED_LAZY (1 << TIF_ARCH_RESCHED_LAZY) +@@ -104,6 +105,7 @@ int arch_dup_task_struct(struct task_str + #define TIF_32BIT 11 /* compat-mode 32bit process */ + #define TIF_RISCV_V_DEFER_RESTORE 12 /* restore Vector before returing to user */ - #define _TIF_WORK_MASK \ - (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED | \ ++#define _TIF_ARCH_RESCHED_LAZY (1 << TIF_ARCH_RESCHED_LAZY) + #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) + #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) + #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) diff --git a/debian/patches-rt/riscv-allow-to-enable-RT.patch b/debian/patches-rt/riscv-allow-to-enable-RT.patch index f39489b4f6..4a8356d70f 100644 --- a/debian/patches-rt/riscv-allow-to-enable-RT.patch +++ b/debian/patches-rt/riscv-allow-to-enable-RT.patch @@ -1,7 +1,7 @@ From: Jisheng Zhang <jszhang@kernel.org> Date: Tue, 31 Oct 2023 22:35:21 +0800 Subject: [PATCH] riscv: allow to enable RT -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz Now, it's ready to enable RT on riscv. diff --git a/debian/patches-rt/sched-rt-Don-t-try-push-tasks-if-there-are-none.patch b/debian/patches-rt/sched-rt-Don-t-try-push-tasks-if-there-are-none.patch index 9c757c60df..dd0fd1eb70 100644 --- a/debian/patches-rt/sched-rt-Don-t-try-push-tasks-if-there-are-none.patch +++ b/debian/patches-rt/sched-rt-Don-t-try-push-tasks-if-there-are-none.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Tue, 1 Aug 2023 17:26:48 +0200 Subject: [PATCH] sched/rt: Don't try push tasks if there are none. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz I have a RT task X at a high priority and cyclictest on each CPU with lower priority than X's. If X is active and each CPU wakes their own @@ -43,7 +43,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c -@@ -2203,8 +2203,11 @@ static int rto_next_cpu(struct root_doma +@@ -2194,8 +2194,11 @@ static int rto_next_cpu(struct root_doma rd->rto_cpu = cpu; diff --git a/debian/patches-rt/series b/debian/patches-rt/series index f3d94c14e2..3429bdc302 100644 --- a/debian/patches-rt/series +++ b/debian/patches-rt/series @@ -9,12 +9,42 @@ ########################################################################### # Posted ########################################################################### -# printk related + +# tty/ serial +0001-serial-amba-pl011-Use-uart_prepare_sysrq_char.patch +0002-serial-ar933x-Use-uart_prepare_sysrq_char.patch +0003-serial-bcm63xx-Use-uart_prepare_sysrq_char.patch +0004-serial-meson-Use-uart_prepare_sysrq_char.patch +0005-serial-msm-Use-uart_prepare_sysrq_char.patch +0006-serial-omap-Use-uart_prepare_sysrq_char.patch +0007-serial-pxa-Use-uart_prepare_sysrq_char.patch +0008-serial-sunplus-Use-uart_prepare_sysrq_char.patch +0009-serial-lpc32xx_hs-Use-uart_prepare_sysrq_char-to-han.patch +0010-serial-owl-Use-uart_prepare_sysrq_char-to-handle-sys.patch +0011-serial-rda-Use-uart_prepare_sysrq_char-to-handle-sys.patch +0012-serial-sifive-Use-uart_prepare_sysrq_char-to-handle-.patch +0013-serial-pch-Invoke-handle_rx_to-directly.patch +0014-serial-pch-Make-push_rx-return-void.patch +0015-serial-pch-Don-t-disable-interrupts-while-acquiring-.patch +0016-serial-pch-Don-t-initialize-uart_port-s-spin_lock.patch +0017-serial-pch-Remove-eg20t_port-lock.patch +0018-serial-pch-Use-uart_prepare_sysrq_char.patch + +# net, RPS, v5 +0001-net-Remove-conditional-threaded-NAPI-wakeup-based-on.patch +0002-net-Allow-to-use-SMP-threads-for-backlog-NAPI.patch +0003-net-Use-backlog-NAPI-to-clean-up-the-defer_list.patch +0004-net-Rename-rps_lock-to-backlog_lock.patch + +# perf, sigtrap, v3 +0001-perf-Move-irq_work_queue-where-the-event-is-prepared.patch +0002-perf-Enqueue-SIGTRAP-always-via-task_work.patch +0003-perf-Remove-perf_swevent_get_recursion_context-from-.patch +0004-perf-Split-__perf_pending_irq-out-of-perf_pending_ir.patch ########################################################################### # Post ########################################################################### -net-Avoid-the-IPI-to-free-the.patch ########################################################################### # X86: @@ -34,7 +64,7 @@ rcutorture-Also-force-sched-priority-to-timersd-on-b.patch tick-Fix-timer-storm-since-introduction-of-timersd.patch softirq-Wake-ktimers-thread-also-in-softirq.patch zram-Replace-bit-spinlocks-with-spinlock_t-for-PREEM.patch -preempt-Put-preempt_enable-within-an-instrumentation.patch +# preempt-Put-preempt_enable-within-an-instrumentation.patch # Sched 0001-sched-core-Provide-a-method-to-check-if-a-task-is-PI.patch @@ -44,47 +74,51 @@ preempt-Put-preempt_enable-within-an-instrumentation.patch ########################################################################### # John's printk queue ########################################################################### -0005-printk-ringbuffer-Clarify-special-lpos-values.patch -0006-printk-For-suppress_panic_printk-check-for-other-CPU.patch -0011-printk-ringbuffer-Consider-committed-as-finalized-in.patch -0013-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch -0014-panic-Flush-kernel-log-buffer-at-the-end.patch -0015-printk-Consider-nbcon-boot-consoles-on-seq-init.patch -0016-printk-Add-sparse-notation-to-console_srcu-locking.patch -0017-printk-nbcon-Ensure-ownership-release-on-failed-emit.patch -0018-printk-Check-printk_deferred_enter-_exit-usage.patch -0019-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch -0020-printk-nbcon-Add-driver_enter-driver_exit-console-ca.patch -0021-printk-Make-console_is_usable-available-to-nbcon.patch -0022-printk-Let-console_is_usable-handle-nbcon.patch -0023-printk-Add-flags-argument-for-console_is_usable.patch -0024-printk-nbcon-Provide-function-to-flush-using-write_a.patch -0025-printk-Track-registered-boot-consoles.patch -0026-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch -0027-printk-nbcon-Assign-priority-based-on-CPU-state.patch -0028-printk-nbcon-Add-unsafe-flushing-on-panic.patch -0029-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch -0030-printk-Track-nbcon-consoles.patch -0031-printk-Coordinate-direct-printing-in-panic.patch -0032-printk-nbcon-Implement-emergency-sections.patch -0033-panic-Mark-emergency-section-in-warn.patch -0034-panic-Mark-emergency-section-in-oops.patch -0035-rcu-Mark-emergency-section-in-rcu-stalls.patch -0036-lockdep-Mark-emergency-section-in-lockdep-splats.patch -0037-printk-nbcon-Introduce-printing-kthreads.patch -0038-printk-Atomic-print-in-printk-context-on-shutdown.patch -0039-printk-nbcon-Add-context-to-console_is_usable.patch -0040-printk-nbcon-Add-printer-thread-wakeups.patch -0041-printk-nbcon-Stop-threads-on-shutdown-reboot.patch -0042-printk-nbcon-Start-printing-threads.patch -0043-proc-Add-nbcon-support-for-proc-consoles.patch -0044-tty-sysfs-Add-nbcon-support-for-active.patch -0045-printk-nbcon-Provide-function-to-reacquire-ownership.patch -0046-serial-core-Provide-low-level-functions-to-port-lock.patch -0047-serial-8250-Switch-to-nbcon-console.patch -0048-printk-Add-kthread-for-all-legacy-consoles.patch -0049-serial-8250-revert-drop-lockdep-annotation-from-seri.patch -0050-printk-Avoid-false-positive-lockdep-report-for-legac.patch +0001-printk-ringbuffer-Clarify-special-lpos-values.patch +0003-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch +0006-printk-Add-notation-to-console_srcu-locking.patch +0007-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch +0008-printk-nbcon-Remove-return-value-for-write_atomic.patch +0009-printk-Check-printk_deferred_enter-_exit-usage.patch +0010-printk-nbcon-Add-detailed-doc-for-write_atomic.patch +0011-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch +0012-printk-nbcon-Use-driver-synchronization-while-regist.patch +0013-serial-core-Provide-low-level-functions-to-lock-port.patch +0014-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch +0015-printk-nbcon-Do-not-rely-on-proxy-headers.patch +0016-printk-nbcon-Fix-kerneldoc-for-enums.patch +0017-printk-Make-console_is_usable-available-to-nbcon.patch +0018-printk-Let-console_is_usable-handle-nbcon.patch +0019-printk-Add-flags-argument-for-console_is_usable.patch +0020-printk-nbcon-Provide-function-to-flush-using-write_a.patch +0021-printk-Track-registered-boot-consoles.patch +0022-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch +0023-printk-nbcon-Assign-priority-based-on-CPU-state.patch +0024-printk-nbcon-Add-unsafe-flushing-on-panic.patch +0025-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch +0026-printk-Track-nbcon-consoles.patch +0027-printk-Coordinate-direct-printing-in-panic.patch +0028-printk-nbcon-Implement-emergency-sections.patch +0029-panic-Mark-emergency-section-in-warn.patch +0030-panic-Mark-emergency-section-in-oops.patch +0031-rcu-Mark-emergency-sections-in-rcu-stalls.patch +0032-lockdep-Mark-emergency-sections-in-lockdep-splats.patch +0033-printk-nbcon-Introduce-printing-kthreads.patch +0034-printk-Atomic-print-in-printk-context-on-shutdown.patch +0035-printk-nbcon-Add-context-to-console_is_usable.patch +0036-printk-nbcon-Add-printer-thread-wakeups.patch +0037-printk-nbcon-Stop-threads-on-shutdown-reboot.patch +0038-printk-nbcon-Start-printing-threads.patch +0039-printk-Provide-helper-for-message-prepending.patch +0040-printk-nbcon-Show-replay-message-on-takeover.patch +0041-proc-Add-nbcon-support-for-proc-consoles.patch +0042-tty-sysfs-Add-nbcon-support-for-active.patch +0043-printk-nbcon-Provide-function-to-reacquire-ownership.patch +0044-serial-8250-Switch-to-nbcon-console.patch +0045-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch +0046-printk-Add-kthread-for-all-legacy-consoles.patch +0047-printk-Provide-threadprintk-boot-argument.patch +0048-printk-Avoid-false-positive-lockdep-report-for-legac.patch ########################################################################### # DRM: @@ -110,9 +144,8 @@ PREEMPT_AUTO.patch ########################################################################### 0001-arm-Disable-jump-label-on-PREEMPT_RT.patch ARM__enable_irq_in_translation_section_permission_fault_handlers.patch +arm-Disable-FAST_GUP-on-PREEMPT_RT-if-HIGHPTE-is-als.patch # arm64-signal-Use-ARCH_RT_DELAYS_SIGNAL_SEND.patch -tty_serial_omap__Make_the_locking_RT_aware.patch -tty_serial_pl011__Make_the_locking_work_on_RT.patch 0001-ARM-vfp-Provide-vfp_lock-for-VFP-locking.patch 0002-ARM-vfp-Use-vfp_lock-in-vfp_sync_hwstate.patch 0003-ARM-vfp-Use-vfp_lock-in-vfp_support_entry.patch diff --git a/debian/patches-rt/softirq-Use-a-dedicated-thread-for-timer-wakeups.patch b/debian/patches-rt/softirq-Use-a-dedicated-thread-for-timer-wakeups.patch index 7d6eb399b5..a5f1a10093 100644 --- a/debian/patches-rt/softirq-Use-a-dedicated-thread-for-timer-wakeups.patch +++ b/debian/patches-rt/softirq-Use-a-dedicated-thread-for-timer-wakeups.patch @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed, 1 Dec 2021 17:41:09 +0100 Subject: [PATCH] softirq: Use a dedicated thread for timer wakeups. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz A timer/hrtimer softirq is raised in-IRQ context. With threaded interrupts enabled or on PREEMPT_RT this leads to waking the ksoftirqd @@ -191,7 +191,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> early_initcall(spawn_ksoftirqd); --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1808,7 +1808,7 @@ void hrtimer_interrupt(struct clock_even +@@ -1809,7 +1809,7 @@ void hrtimer_interrupt(struct clock_even if (!ktime_before(now, cpu_base->softirq_expires_next)) { cpu_base->softirq_expires_next = KTIME_MAX; cpu_base->softirq_activated = 1; @@ -200,7 +200,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); -@@ -1921,7 +1921,7 @@ void hrtimer_run_queues(void) +@@ -1922,7 +1922,7 @@ void hrtimer_run_queues(void) if (!ktime_before(now, cpu_base->softirq_expires_next)) { cpu_base->softirq_expires_next = KTIME_MAX; cpu_base->softirq_activated = 1; @@ -211,7 +211,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); --- a/kernel/time/timer.c +++ b/kernel/time/timer.c -@@ -2054,7 +2054,7 @@ static void run_local_timers(void) +@@ -2070,7 +2070,7 @@ static void run_local_timers(void) if (time_before(jiffies, base->next_expiry)) return; } diff --git a/debian/patches-rt/softirq-Wake-ktimers-thread-also-in-softirq.patch b/debian/patches-rt/softirq-Wake-ktimers-thread-also-in-softirq.patch index 23fe32ea39..0528a0e138 100644 --- a/debian/patches-rt/softirq-Wake-ktimers-thread-also-in-softirq.patch +++ b/debian/patches-rt/softirq-Wake-ktimers-thread-also-in-softirq.patch @@ -1,7 +1,7 @@ From: Junxiao Chang <junxiao.chang@intel.com> Date: Mon, 20 Feb 2023 09:12:20 +0100 Subject: [PATCH] softirq: Wake ktimers thread also in softirq. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz If the hrtimer is raised while a softirq is processed then it does not wake the corresponding ktimers thread. This is due to the optimisation in the diff --git a/debian/patches-rt/sysfs__Add__sys_kernel_realtime_entry.patch b/debian/patches-rt/sysfs__Add__sys_kernel_realtime_entry.patch index 56e82149df..8ae88f1168 100644 --- a/debian/patches-rt/sysfs__Add__sys_kernel_realtime_entry.patch +++ b/debian/patches-rt/sysfs__Add__sys_kernel_realtime_entry.patch @@ -1,7 +1,7 @@ Subject: sysfs: Add /sys/kernel/realtime entry From: Clark Williams <williams@redhat.com> Date: Sat Jul 30 21:55:53 2011 -0500 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Clark Williams <williams@redhat.com> diff --git a/debian/patches-rt/tick-Fix-timer-storm-since-introduction-of-timersd.patch b/debian/patches-rt/tick-Fix-timer-storm-since-introduction-of-timersd.patch index c04b555691..be10774fe2 100644 --- a/debian/patches-rt/tick-Fix-timer-storm-since-introduction-of-timersd.patch +++ b/debian/patches-rt/tick-Fix-timer-storm-since-introduction-of-timersd.patch @@ -1,7 +1,7 @@ From: Frederic Weisbecker <frederic@kernel.org> Date: Tue, 5 Apr 2022 03:07:52 +0200 Subject: [PATCH] tick: Fix timer storm since introduction of timersd -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz If timers are pending while the tick is reprogrammed on nohz_mode, the next expiry is not armed to fire now, it is delayed one jiffy forward diff --git a/debian/patches-rt/tty_serial_omap__Make_the_locking_RT_aware.patch b/debian/patches-rt/tty_serial_omap__Make_the_locking_RT_aware.patch deleted file mode 100644 index fd1f459b75..0000000000 --- a/debian/patches-rt/tty_serial_omap__Make_the_locking_RT_aware.patch +++ /dev/null @@ -1,47 +0,0 @@ -Subject: tty/serial/omap: Make the locking RT aware -From: Thomas Gleixner <tglx@linutronix.de> -Date: Thu Jul 28 13:32:57 2011 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -From: Thomas Gleixner <tglx@linutronix.de> - -The lock is a sleeping lock and local_irq_save() is not the -optimsation we are looking for. Redo it to make it work on -RT and -non-RT. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> - - ---- - drivers/tty/serial/omap-serial.c | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) ---- ---- a/drivers/tty/serial/omap-serial.c -+++ b/drivers/tty/serial/omap-serial.c -@@ -1212,13 +1212,10 @@ serial_omap_console_write(struct console - unsigned int ier; - int locked = 1; - -- local_irq_save(flags); -- if (up->port.sysrq) -- locked = 0; -- else if (oops_in_progress) -- locked = uart_port_trylock(&up->port); -+ if (up->port.sysrq || oops_in_progress) -+ locked = uart_port_trylock_irqsave(&up->port, &flags); - else -- uart_port_lock(&up->port); -+ uart_port_lock_irqsave(&up->port, &flags); - - /* - * First save the IER then disable the interrupts -@@ -1245,8 +1242,7 @@ serial_omap_console_write(struct console - check_modem_status(up); - - if (locked) -- uart_port_unlock(&up->port); -- local_irq_restore(flags); -+ uart_port_unlock_irqrestore(&up->port, flags); - } - - static int __init diff --git a/debian/patches-rt/tty_serial_pl011__Make_the_locking_work_on_RT.patch b/debian/patches-rt/tty_serial_pl011__Make_the_locking_work_on_RT.patch deleted file mode 100644 index c9a40db398..0000000000 --- a/debian/patches-rt/tty_serial_pl011__Make_the_locking_work_on_RT.patch +++ /dev/null @@ -1,46 +0,0 @@ -Subject: tty/serial/pl011: Make the locking work on RT -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue Jan 8 21:36:51 2013 +0100 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz - -From: Thomas Gleixner <tglx@linutronix.de> - -The lock is a sleeping lock and local_irq_save() is not the optimsation -we are looking for. Redo it to make it work on -RT and non-RT. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> - - ---- - drivers/tty/serial/amba-pl011.c | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) ---- ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -2332,13 +2332,10 @@ pl011_console_write(struct console *co, - - clk_enable(uap->clk); - -- local_irq_save(flags); -- if (uap->port.sysrq) -- locked = 0; -- else if (oops_in_progress) -- locked = uart_port_trylock(&uap->port); -+ if (uap->port.sysrq || oops_in_progress) -+ locked = uart_port_trylock_irqsave(&uap->port, &flags); - else -- uart_port_lock(&uap->port); -+ uart_port_lock_irqsave(&uap->port, &flags); - - /* - * First save the CR then disable the interrupts -@@ -2364,8 +2361,7 @@ pl011_console_write(struct console *co, - pl011_write(old_cr, uap, REG_CR); - - if (locked) -- uart_port_unlock(&uap->port); -- local_irq_restore(flags); -+ uart_port_unlock_irqrestore(&uap->port, flags); - - clk_disable(uap->clk); - } diff --git a/debian/patches-rt/x86__Allow_to_enable_RT.patch b/debian/patches-rt/x86__Allow_to_enable_RT.patch index a0c01233f8..9e900b332c 100644 --- a/debian/patches-rt/x86__Allow_to_enable_RT.patch +++ b/debian/patches-rt/x86__Allow_to_enable_RT.patch @@ -1,7 +1,7 @@ Subject: x86: Allow to enable RT From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed Aug 7 18:15:38 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> diff --git a/debian/patches-rt/x86__Enable_RT_also_on_32bit.patch b/debian/patches-rt/x86__Enable_RT_also_on_32bit.patch index 6b6f7e84af..5f49eedcca 100644 --- a/debian/patches-rt/x86__Enable_RT_also_on_32bit.patch +++ b/debian/patches-rt/x86__Enable_RT_also_on_32bit.patch @@ -1,7 +1,7 @@ Subject: x86: Enable RT also on 32bit From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Thu Nov 7 17:49:20 2019 +0100 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> @@ -10,20 +10,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - arch/x86/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + arch/x86/Kconfig | 1 + + 1 file changed, 1 insertion(+) --- --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -27,7 +27,6 @@ config X86_64 - # Options that are inherently 64-bit kernel only: - select ARCH_HAS_GIGANTIC_PAGE - select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 -- select ARCH_SUPPORTS_PER_VMA_LOCK - select ARCH_SUPPORTS_RT - select HAVE_ARCH_SOFT_DIRTY - select MODULES_USE_ELF_RELA -@@ -117,6 +116,7 @@ config X86 +@@ -120,6 +120,7 @@ config X86 select ARCH_USES_CFI_TRAPS if X86_64 && CFI_CLANG select ARCH_SUPPORTS_LTO_CLANG select ARCH_SUPPORTS_LTO_CLANG_THIN diff --git a/debian/patches-rt/zram-Replace-bit-spinlocks-with-spinlock_t-for-PREEM.patch b/debian/patches-rt/zram-Replace-bit-spinlocks-with-spinlock_t-for-PREEM.patch index 24895a4fb5..497f896e71 100644 --- a/debian/patches-rt/zram-Replace-bit-spinlocks-with-spinlock_t-for-PREEM.patch +++ b/debian/patches-rt/zram-Replace-bit-spinlocks-with-spinlock_t-for-PREEM.patch @@ -1,7 +1,7 @@ From: Mike Galbraith <umgwanakikbuti@gmail.com> Date: Thu, 31 Mar 2016 04:08:28 +0200 Subject: [PATCH] zram: Replace bit spinlocks with spinlock_t for PREEMPT_RT. -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.7/older/patches-6.7-rt6.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz The bit spinlock disables preemption. The spinlock_t lock becomes a sleeping lock on PREEMPT_RT and it can not be acquired in this context. In this locked @@ -72,7 +72,7 @@ Link: https://lore.kernel.org/20230323161830.jFbWCosd@linutronix.de static inline bool init_done(struct zram *zram) { -@@ -1242,6 +1278,7 @@ static bool zram_meta_alloc(struct zram +@@ -1241,6 +1277,7 @@ static bool zram_meta_alloc(struct zram if (!huge_class_size) huge_class_size = zs_huge_class_size(zram->mem_pool); @@ -89,6 +89,6 @@ Link: https://lore.kernel.org/20230323161830.jFbWCosd@linutronix.de +#ifdef CONFIG_PREEMPT_RT + spinlock_t lock; +#endif - #ifdef CONFIG_ZRAM_MEMORY_TRACKING + #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME ktime_t ac_time; #endif |