From f25552c1068a054f2d99afd67a671d5991bf19c1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 7 Aug 2024 15:11:44 +0200 Subject: Merging debian version 6.9.7-1. Signed-off-by: Daniel Baumann --- ...-ARM-vfp-Provide-vfp_lock-for-VFP-locking.patch | 2 +- ...0001-arm-Disable-jump-label-on-PREEMPT_RT.patch | 4 +- ...conditional-threaded-NAPI-wakeup-based-on.patch | 12 +- ...rq_work_queue-where-the-event-is-prepared.patch | 6 +- ...intk-Add-notation-to-console_srcu-locking.patch | 35 ++ ...tk-ringbuffer-Clarify-special-lpos-values.patch | 95 ---- ...Provide-a-method-to-check-if-a-task-is-PI.patch | 6 +- ...al-amba-pl011-Use-uart_prepare_sysrq_char.patch | 92 ---- ...-ARM-vfp-Use-vfp_lock-in-vfp_sync_hwstate.patch | 2 +- ...Allow-to-use-SMP-threads-for-backlog-NAPI.patch | 43 +- ...perf-Enqueue-SIGTRAP-always-via-task_work.patch | 10 +- ...erly-deal-with-nbcon-consoles-on-seq-init.patch | 190 +++++++ ...serial-ar933x-Use-uart_prepare_sysrq_char.patch | 68 --- ...-Add-function-to-preempt-serving-softirqs.patch | 4 +- ...ARM-vfp-Use-vfp_lock-in-vfp_support_entry.patch | 2 +- ...e-preempt_disable-enable_rt-where-recomme.patch | 10 +- ...e-backlog-NAPI-to-clean-up-the-defer_list.patch | 20 +- ...-perf_swevent_get_recursion_context-from-.patch | 2 +- ...void-non-panic-CPUs-writing-to-ringbuffer.patch | 86 ---- ...bcon-Remove-return-value-for-write_atomic.patch | 69 +++ ...erial-bcm63xx-Use-uart_prepare_sysrq_char.patch | 78 --- ...03-time-Allow-to-preempt-after-a-callback.patch | 4 +- ...e-sending-signals-outside-of-vfp_lock-ed-.patch | 2 +- ...n-t-disable-interrupts-on-PREEMPT_RT-duri.patch | 51 +- .../0004-net-Rename-rps_lock-to-backlog_lock.patch | 32 +- ...__perf_pending_irq-out-of-perf_pending_ir.patch | 6 +- ...k-Check-printk_deferred_enter-_exit-usage.patch | 74 +++ ...-serial-meson-Use-uart_prepare_sysrq_char.patch | 77 --- ...n-t-check-for-atomic-context-on-PREEMPT_R.patch | 2 +- ...k-nbcon-Add-detailed-doc-for-write_atomic.patch | 72 +++ ...05-serial-msm-Use-uart_prepare_sysrq_char.patch | 116 ----- ...i915-Disable-tracing-points-on-PREEMPT_RT.patch | 45 -- ...intk-Add-notation-to-console_srcu-locking.patch | 35 -- ...n-Add-callbacks-to-synchronize-with-drive.patch | 84 +++ ...6-serial-omap-Use-uart_prepare_sysrq_char.patch | 66 --- ...ip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch | 29 -- ...erly-deal-with-nbcon-consoles-on-seq-init.patch | 116 ----- ...n-Use-driver-synchronization-while-un-reg.patch | 109 ++++ ...07-serial-pxa-Use-uart_prepare_sysrq_char.patch | 68 --- ...5-gt-Queue-and-wait-for-the-irq_work-item.patch | 42 -- ...bcon-Remove-return-value-for-write_atomic.patch | 68 --- ...-Provide-low-level-functions-to-lock-port.patch | 50 ++ ...erial-sunplus-Use-uart_prepare_sysrq_char.patch | 67 --- ...-Use-spin_lock_irq-instead-of-local_irq_d.patch | 2 +- ...k-Check-printk_deferred_enter-_exit-usage.patch | 74 --- ...e-Introduce-wrapper-to-set-uart_port-cons.patch | 116 +++++ ...2xx_hs-Use-uart_prepare_sysrq_char-to-han.patch | 68 --- ...-Improve-console_srcu_read_flags-comments.patch | 72 +++ ...010-drm-i915-Drop-the-irqs_disabled-check.patch | 6 +- ...k-nbcon-Add-detailed-doc-for-write_atomic.patch | 71 --- ...Use-uart_prepare_sysrq_char-to-handle-sys.patch | 104 ---- ...de-functions-for-drivers-to-acquire-conso.patch | 160 ++++++ ...n-Add-callbacks-to-synchronize-with-drive.patch | 72 --- ...Use-uart_prepare_sysrq_char-to-handle-sys.patch | 91 ---- ...n-Use-driver-synchronization-while-regist.patch | 68 --- ...-Implement-processing-in-port-lock-wrappe.patch | 180 +++++++ ...ve-Use-uart_prepare_sysrq_char-to-handle-.patch | 71 --- ...printk-nbcon-Do-not-rely-on-proxy-headers.patch | 88 ++++ ...-Provide-low-level-functions-to-lock-port.patch | 48 -- ...3-serial-pch-Invoke-handle_rx_to-directly.patch | 39 -- ...Make-console_is_usable-available-to-nbcon.patch | 103 ++++ ...n-Implement-processing-in-port-lock-wrapp.patch | 478 ----------------- .../0014-serial-pch-Make-push_rx-return-void.patch | 56 -- ...printk-Let-console_is_usable-handle-nbcon.patch | 43 ++ ...printk-nbcon-Do-not-rely-on-proxy-headers.patch | 87 ---- ...Don-t-disable-interrupts-while-acquiring-.patch | 42 -- ...-Add-flags-argument-for-console_is_usable.patch | 67 +++ ...0016-printk-nbcon-Fix-kerneldoc-for-enums.patch | 36 -- ...ch-Don-t-initialize-uart_port-s-spin_lock.patch | 28 - ...Make-console_is_usable-available-to-nbcon.patch | 103 ---- ...n-Add-helper-to-assign-priority-based-on-.patch | 67 +++ .../0017-serial-pch-Remove-eg20t_port-lock.patch | 128 ----- ...printk-Let-console_is_usable-handle-nbcon.patch | 43 -- ...n-Provide-function-to-flush-using-write_a.patch | 260 ++++++++++ ...18-serial-pch-Use-uart_prepare_sysrq_char.patch | 79 --- ...-Add-flags-argument-for-console_is_usable.patch | 67 --- ...019-printk-Track-registered-boot-consoles.patch | 80 +++ ...n-Provide-function-to-flush-using-write_a.patch | 193 ------- ...n-Use-nbcon-consoles-in-console_flush_all.patch | 209 ++++++++ ...021-printk-Track-registered-boot-consoles.patch | 79 --- ...printk-nbcon-Add-unsafe-flushing-on-panic.patch | 159 ++++++ ...d-console_lock-dance-if-no-legacy-or-boot.patch | 207 ++++++++ ...n-Use-nbcon-consoles-in-console_flush_all.patch | 200 -------- .../0023-printk-Track-nbcon-consoles.patch | 66 +++ ...-nbcon-Assign-priority-based-on-CPU-state.patch | 84 --- ...rintk-Coordinate-direct-printing-in-panic.patch | 164 ++++++ ...printk-nbcon-Add-unsafe-flushing-on-panic.patch | 125 ----- ...d-console_lock-dance-if-no-legacy-or-boot.patch | 207 -------- ...printk-nbcon-Implement-emergency-sections.patch | 283 +++++++++++ ...0026-panic-Mark-emergency-section-in-warn.patch | 39 ++ .../0026-printk-Track-nbcon-consoles.patch | 65 --- ...0027-panic-Mark-emergency-section-in-oops.patch | 40 ++ ...rintk-Coordinate-direct-printing-in-panic.patch | 163 ------ ...printk-nbcon-Implement-emergency-sections.patch | 201 -------- ...rcu-Mark-emergency-sections-in-rcu-stalls.patch | 128 +++++ ...Mark-emergency-sections-in-lockdep-splats.patch | 461 +++++++++++++++++ ...0029-panic-Mark-emergency-section-in-warn.patch | 38 -- ...0030-panic-Mark-emergency-section-in-oops.patch | 39 -- ...-printk-nbcon-Introduce-printing-kthreads.patch | 478 +++++++++++++++++ ...tomic-print-in-printk-context-on-shutdown.patch | 40 ++ ...rcu-Mark-emergency-sections-in-rcu-stalls.patch | 96 ---- ...Mark-emergency-sections-in-lockdep-splats.patch | 487 ------------------ ...tk-nbcon-Add-context-to-console_is_usable.patch | 120 +++++ ...3-printk-nbcon-Add-printer-thread-wakeups.patch | 164 ++++++ ...-printk-nbcon-Introduce-printing-kthreads.patch | 472 ----------------- ...tomic-print-in-printk-context-on-shutdown.patch | 40 -- ...ntk-nbcon-Stop-threads-on-shutdown-reboot.patch | 60 +++ ...tk-nbcon-Add-context-to-console_is_usable.patch | 111 ---- .../0035-printk-nbcon-Start-printing-threads.patch | 135 +++++ ...ntk-Provide-helper-for-message-prepending.patch | 82 +++ ...6-printk-nbcon-Add-printer-thread-wakeups.patch | 164 ------ ...ntk-nbcon-Show-replay-message-on-takeover.patch | 136 +++++ ...ntk-nbcon-Stop-threads-on-shutdown-reboot.patch | 60 --- .../0038-printk-nbcon-Start-printing-threads.patch | 135 ----- ...c-consoles-Add-notation-to-c_start-c_stop.patch | 34 ++ ...ntk-Provide-helper-for-message-prepending.patch | 82 --- ...-proc-Add-nbcon-support-for-proc-consoles.patch | 53 ++ ...ntk-nbcon-Show-replay-message-on-takeover.patch | 135 ----- ...40-tty-sysfs-Add-nbcon-support-for-active.patch | 31 ++ ...n-Provide-function-to-reacquire-ownership.patch | 120 +++++ ...-proc-Add-nbcon-support-for-proc-consoles.patch | 53 -- .../0042-serial-8250-Switch-to-nbcon-console.patch | 334 ++++++++++++ ...42-tty-sysfs-Add-nbcon-support-for-active.patch | 31 -- ...n-Provide-function-to-reacquire-ownership.patch | 119 ----- ...-Revert-drop-lockdep-annotation-from-seri.patch | 29 ++ ...rintk-Add-kthread-for-all-legacy-consoles.patch | 532 +++++++++++++++++++ .../0044-serial-8250-Switch-to-nbcon-console.patch | 337 ------------ ...printk-Provide-threadprintk-boot-argument.patch | 96 ++++ ...-Revert-drop-lockdep-annotation-from-seri.patch | 29 -- ...rintk-Add-kthread-for-all-legacy-consoles.patch | 566 --------------------- ...d-false-positive-lockdep-report-for-legac.patch | 86 ++++ ...printk-Provide-threadprintk-boot-argument.patch | 96 ---- ...d-false-positive-lockdep-report-for-legac.patch | 86 ---- debian/patches-rt/ARM64__Allow_to_enable_RT.patch | 2 +- debian/patches-rt/ARM__Allow_to_enable_RT.patch | 6 +- ...slation_section_permission_fault_handlers.patch | 6 +- .../Add_localversion_for_-RT_release.patch | 4 +- .../patches-rt/POWERPC__Allow_to_enable_RT.patch | 2 +- debian/patches-rt/PREEMPT_AUTO.patch | 54 +- .../Revert-drm-i915-Depend-on-PREEMPT_RT.patch | 2 +- ...-FAST_GUP-on-PREEMPT_RT-if-HIGHPTE-is-als.patch | 4 +- ...i915-Disable-tracing-points-on-PREEMPT_RT.patch | 59 +++ ...-guc-Consider-also-RCU-depth-in-busy-loop.patch | 4 +- ...ts-Let-ttm_bo_test-consider-different-ww_.patch | 52 ++ ...esas-rzg2l-Use-spin_-lock-unlock-_irq-sav.patch | 38 ++ ...eries-Select-the-generic-memory-allocator.patch | 2 +- .../powerpc__traps__Use_PREEMPT_RT.patch | 2 +- ...e_in-kernel_MPIC_emulation_for_PREEMPT_RT.patch | 4 +- ...u__Use_a_locallock_instead_local_irq_save.patch | 2 +- ..._work_around_stack-guard_init_from_atomic.patch | 2 +- ...Also-force-sched-priority-to-timersd-on-b.patch | 8 +- .../riscv-add-PREEMPT_AUTO-support.patch | 4 +- debian/patches-rt/riscv-allow-to-enable-RT.patch | 6 +- ...rt-Don-t-try-push-tasks-if-there-are-none.patch | 2 +- debian/patches-rt/series | 121 ++--- ...-Use-a-dedicated-thread-for-timer-wakeups.patch | 28 +- ...ftirq-Wake-ktimers-thread-also-in-softirq.patch | 4 +- .../sysfs__Add__sys_kernel_realtime_entry.patch | 8 +- ...timer-storm-since-introduction-of-timersd.patch | 12 +- debian/patches-rt/x86__Allow_to_enable_RT.patch | 2 +- .../patches-rt/x86__Enable_RT_also_on_32bit.patch | 4 +- ...e-bit-spinlocks-with-spinlock_t-for-PREEM.patch | 2 +- 162 files changed, 6612 insertions(+), 7761 deletions(-) create mode 100644 debian/patches-rt/0001-printk-Add-notation-to-console_srcu-locking.patch delete mode 100644 debian/patches-rt/0001-printk-ringbuffer-Clarify-special-lpos-values.patch delete mode 100644 debian/patches-rt/0001-serial-amba-pl011-Use-uart_prepare_sysrq_char.patch create mode 100644 debian/patches-rt/0002-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch delete mode 100644 debian/patches-rt/0002-serial-ar933x-Use-uart_prepare_sysrq_char.patch delete mode 100644 debian/patches-rt/0003-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch create mode 100644 debian/patches-rt/0003-printk-nbcon-Remove-return-value-for-write_atomic.patch delete mode 100644 debian/patches-rt/0003-serial-bcm63xx-Use-uart_prepare_sysrq_char.patch create mode 100644 debian/patches-rt/0004-printk-Check-printk_deferred_enter-_exit-usage.patch delete mode 100644 debian/patches-rt/0004-serial-meson-Use-uart_prepare_sysrq_char.patch create mode 100644 debian/patches-rt/0005-printk-nbcon-Add-detailed-doc-for-write_atomic.patch delete mode 100644 debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch delete mode 100644 debian/patches-rt/0006-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch delete mode 100644 debian/patches-rt/0006-printk-Add-notation-to-console_srcu-locking.patch create mode 100644 debian/patches-rt/0006-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch delete mode 100644 debian/patches-rt/0006-serial-omap-Use-uart_prepare_sysrq_char.patch delete mode 100644 debian/patches-rt/0007-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch delete mode 100644 debian/patches-rt/0007-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch create mode 100644 debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch delete mode 100644 debian/patches-rt/0007-serial-pxa-Use-uart_prepare_sysrq_char.patch delete mode 100644 debian/patches-rt/0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch delete mode 100644 debian/patches-rt/0008-printk-nbcon-Remove-return-value-for-write_atomic.patch create mode 100644 debian/patches-rt/0008-serial-core-Provide-low-level-functions-to-lock-port.patch delete mode 100644 debian/patches-rt/0008-serial-sunplus-Use-uart_prepare_sysrq_char.patch delete mode 100644 debian/patches-rt/0009-printk-Check-printk_deferred_enter-_exit-usage.patch create mode 100644 debian/patches-rt/0009-serial-core-Introduce-wrapper-to-set-uart_port-cons.patch delete mode 100644 debian/patches-rt/0009-serial-lpc32xx_hs-Use-uart_prepare_sysrq_char-to-han.patch create mode 100644 debian/patches-rt/0010-console-Improve-console_srcu_read_flags-comments.patch delete mode 100644 debian/patches-rt/0010-printk-nbcon-Add-detailed-doc-for-write_atomic.patch delete mode 100644 debian/patches-rt/0010-serial-owl-Use-uart_prepare_sysrq_char-to-handle-sys.patch create mode 100644 debian/patches-rt/0011-nbcon-Provide-functions-for-drivers-to-acquire-conso.patch delete mode 100644 debian/patches-rt/0011-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch delete mode 100644 debian/patches-rt/0011-serial-rda-Use-uart_prepare_sysrq_char-to-handle-sys.patch delete mode 100644 debian/patches-rt/0012-printk-nbcon-Use-driver-synchronization-while-regist.patch create mode 100644 debian/patches-rt/0012-serial-core-Implement-processing-in-port-lock-wrappe.patch delete mode 100644 debian/patches-rt/0012-serial-sifive-Use-uart_prepare_sysrq_char-to-handle-.patch create mode 100644 debian/patches-rt/0013-printk-nbcon-Do-not-rely-on-proxy-headers.patch delete mode 100644 debian/patches-rt/0013-serial-core-Provide-low-level-functions-to-lock-port.patch delete mode 100644 debian/patches-rt/0013-serial-pch-Invoke-handle_rx_to-directly.patch create mode 100644 debian/patches-rt/0014-printk-Make-console_is_usable-available-to-nbcon.patch delete mode 100644 debian/patches-rt/0014-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch delete mode 100644 debian/patches-rt/0014-serial-pch-Make-push_rx-return-void.patch create mode 100644 debian/patches-rt/0015-printk-Let-console_is_usable-handle-nbcon.patch delete mode 100644 debian/patches-rt/0015-printk-nbcon-Do-not-rely-on-proxy-headers.patch delete mode 100644 debian/patches-rt/0015-serial-pch-Don-t-disable-interrupts-while-acquiring-.patch create mode 100644 debian/patches-rt/0016-printk-Add-flags-argument-for-console_is_usable.patch delete mode 100644 debian/patches-rt/0016-printk-nbcon-Fix-kerneldoc-for-enums.patch delete mode 100644 debian/patches-rt/0016-serial-pch-Don-t-initialize-uart_port-s-spin_lock.patch delete mode 100644 debian/patches-rt/0017-printk-Make-console_is_usable-available-to-nbcon.patch create mode 100644 debian/patches-rt/0017-printk-nbcon-Add-helper-to-assign-priority-based-on-.patch delete mode 100644 debian/patches-rt/0017-serial-pch-Remove-eg20t_port-lock.patch delete mode 100644 debian/patches-rt/0018-printk-Let-console_is_usable-handle-nbcon.patch create mode 100644 debian/patches-rt/0018-printk-nbcon-Provide-function-to-flush-using-write_a.patch delete mode 100644 debian/patches-rt/0018-serial-pch-Use-uart_prepare_sysrq_char.patch delete mode 100644 debian/patches-rt/0019-printk-Add-flags-argument-for-console_is_usable.patch create mode 100644 debian/patches-rt/0019-printk-Track-registered-boot-consoles.patch delete mode 100644 debian/patches-rt/0020-printk-nbcon-Provide-function-to-flush-using-write_a.patch create mode 100644 debian/patches-rt/0020-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch delete mode 100644 debian/patches-rt/0021-printk-Track-registered-boot-consoles.patch create mode 100644 debian/patches-rt/0021-printk-nbcon-Add-unsafe-flushing-on-panic.patch create mode 100644 debian/patches-rt/0022-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch delete mode 100644 debian/patches-rt/0022-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch create mode 100644 debian/patches-rt/0023-printk-Track-nbcon-consoles.patch delete mode 100644 debian/patches-rt/0023-printk-nbcon-Assign-priority-based-on-CPU-state.patch create mode 100644 debian/patches-rt/0024-printk-Coordinate-direct-printing-in-panic.patch delete mode 100644 debian/patches-rt/0024-printk-nbcon-Add-unsafe-flushing-on-panic.patch delete mode 100644 debian/patches-rt/0025-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch create mode 100644 debian/patches-rt/0025-printk-nbcon-Implement-emergency-sections.patch create mode 100644 debian/patches-rt/0026-panic-Mark-emergency-section-in-warn.patch delete mode 100644 debian/patches-rt/0026-printk-Track-nbcon-consoles.patch create mode 100644 debian/patches-rt/0027-panic-Mark-emergency-section-in-oops.patch delete mode 100644 debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch delete mode 100644 debian/patches-rt/0028-printk-nbcon-Implement-emergency-sections.patch create mode 100644 debian/patches-rt/0028-rcu-Mark-emergency-sections-in-rcu-stalls.patch create mode 100644 debian/patches-rt/0029-lockdep-Mark-emergency-sections-in-lockdep-splats.patch delete mode 100644 debian/patches-rt/0029-panic-Mark-emergency-section-in-warn.patch delete mode 100644 debian/patches-rt/0030-panic-Mark-emergency-section-in-oops.patch create mode 100644 debian/patches-rt/0030-printk-nbcon-Introduce-printing-kthreads.patch create mode 100644 debian/patches-rt/0031-printk-Atomic-print-in-printk-context-on-shutdown.patch delete mode 100644 debian/patches-rt/0031-rcu-Mark-emergency-sections-in-rcu-stalls.patch delete mode 100644 debian/patches-rt/0032-lockdep-Mark-emergency-sections-in-lockdep-splats.patch create mode 100644 debian/patches-rt/0032-printk-nbcon-Add-context-to-console_is_usable.patch create mode 100644 debian/patches-rt/0033-printk-nbcon-Add-printer-thread-wakeups.patch delete mode 100644 debian/patches-rt/0033-printk-nbcon-Introduce-printing-kthreads.patch delete mode 100644 debian/patches-rt/0034-printk-Atomic-print-in-printk-context-on-shutdown.patch create mode 100644 debian/patches-rt/0034-printk-nbcon-Stop-threads-on-shutdown-reboot.patch delete mode 100644 debian/patches-rt/0035-printk-nbcon-Add-context-to-console_is_usable.patch create mode 100644 debian/patches-rt/0035-printk-nbcon-Start-printing-threads.patch create mode 100644 debian/patches-rt/0036-printk-Provide-helper-for-message-prepending.patch delete mode 100644 debian/patches-rt/0036-printk-nbcon-Add-printer-thread-wakeups.patch create mode 100644 debian/patches-rt/0037-printk-nbcon-Show-replay-message-on-takeover.patch delete mode 100644 debian/patches-rt/0037-printk-nbcon-Stop-threads-on-shutdown-reboot.patch delete mode 100644 debian/patches-rt/0038-printk-nbcon-Start-printing-threads.patch create mode 100644 debian/patches-rt/0038-proc-consoles-Add-notation-to-c_start-c_stop.patch delete mode 100644 debian/patches-rt/0039-printk-Provide-helper-for-message-prepending.patch create mode 100644 debian/patches-rt/0039-proc-Add-nbcon-support-for-proc-consoles.patch delete mode 100644 debian/patches-rt/0040-printk-nbcon-Show-replay-message-on-takeover.patch create mode 100644 debian/patches-rt/0040-tty-sysfs-Add-nbcon-support-for-active.patch create mode 100644 debian/patches-rt/0041-printk-nbcon-Provide-function-to-reacquire-ownership.patch delete mode 100644 debian/patches-rt/0041-proc-Add-nbcon-support-for-proc-consoles.patch create mode 100644 debian/patches-rt/0042-serial-8250-Switch-to-nbcon-console.patch delete mode 100644 debian/patches-rt/0042-tty-sysfs-Add-nbcon-support-for-active.patch delete mode 100644 debian/patches-rt/0043-printk-nbcon-Provide-function-to-reacquire-ownership.patch create mode 100644 debian/patches-rt/0043-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch create mode 100644 debian/patches-rt/0044-printk-Add-kthread-for-all-legacy-consoles.patch delete mode 100644 debian/patches-rt/0044-serial-8250-Switch-to-nbcon-console.patch create mode 100644 debian/patches-rt/0045-printk-Provide-threadprintk-boot-argument.patch delete mode 100644 debian/patches-rt/0045-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch delete mode 100644 debian/patches-rt/0046-printk-Add-kthread-for-all-legacy-consoles.patch create mode 100644 debian/patches-rt/0046-printk-Avoid-false-positive-lockdep-report-for-legac.patch delete mode 100644 debian/patches-rt/0047-printk-Provide-threadprintk-boot-argument.patch delete mode 100644 debian/patches-rt/0048-printk-Avoid-false-positive-lockdep-report-for-legac.patch create mode 100644 debian/patches-rt/drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch create mode 100644 debian/patches-rt/drm-ttm-tests-Let-ttm_bo_test-consider-different-ww_.patch create mode 100644 debian/patches-rt/pinctrl-renesas-rzg2l-Use-spin_-lock-unlock-_irq-sav.patch (limited to 'debian/patches-rt') 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 b2ee39b051..4fb5196d59 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 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 7fbdfa5062..403d1baade 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 -@@ -75,7 +75,7 @@ config ARM +@@ -76,7 +76,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 index ae507f979e..882e69292f 100644 --- 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 @@ -1,8 +1,8 @@ From: Sebastian Andrzej Siewior -Date: Sat, 9 Mar 2024 10:05:09 +0100 +Date: Mon, 25 Mar 2024 08:40:28 +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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -24,7 +24,7 @@ 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 -Link: https://lore.kernel.org/r/20240309090824.2956805-2-bigeasy@linutronix.de +Link: https://lore.kernel.org/r/20240325074943.289909-2-bigeasy@linutronix.de Signed-off-by: Sebastian Andrzej Siewior --- net/core/dev.c | 14 ++------------ @@ -32,7 +32,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -4452,13 +4452,7 @@ static inline void ____napi_schedule(str +@@ -4433,13 +4433,7 @@ static inline void ____napi_schedule(str */ thread = READ_ONCE(napi->thread); if (thread) { @@ -47,7 +47,7 @@ Signed-off-by: Sebastian Andrzej Siewior wake_up_process(thread); return; } -@@ -6654,8 +6648,6 @@ static int napi_poll(struct napi_struct +@@ -6716,8 +6710,6 @@ static int napi_poll(struct napi_struct static int napi_thread_wait(struct napi_struct *napi) { @@ -56,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { -@@ -6664,15 +6656,13 @@ static int napi_thread_wait(struct napi_ +@@ -6726,15 +6718,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(). */ 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 index 08a2950a4a..b5d1590348 100644 --- 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 @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior 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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -24,7 +24,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/kernel/events/core.c +++ b/kernel/events/core.c -@@ -9595,6 +9595,7 @@ static int __perf_event_overflow(struct +@@ -9591,6 +9591,7 @@ static int __perf_event_overflow(struct if (!event->pending_sigtrap) { event->pending_sigtrap = pending_id; local_inc(&event->ctx->nr_pending); @@ -32,7 +32,7 @@ Signed-off-by: Sebastian Andrzej Siewior } 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 +@@ -9610,7 +9611,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; diff --git a/debian/patches-rt/0001-printk-Add-notation-to-console_srcu-locking.patch b/debian/patches-rt/0001-printk-Add-notation-to-console_srcu-locking.patch new file mode 100644 index 0000000000..d2d214826b --- /dev/null +++ b/debian/patches-rt/0001-printk-Add-notation-to-console_srcu-locking.patch @@ -0,0 +1,35 @@ +From: John Ogness +Date: Mon, 9 Oct 2023 13:55:19 +0000 +Subject: [PATCH 01/46] printk: Add notation to console_srcu locking +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 + +Fixes: 6c4afa79147e ("printk: Prepare for SRCU console list protection") +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/printk.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -282,6 +282,7 @@ EXPORT_SYMBOL(console_list_unlock); + * Return: A cookie to pass to console_srcu_read_unlock(). + */ + int console_srcu_read_lock(void) ++ __acquires(&console_srcu) + { + return srcu_read_lock_nmisafe(&console_srcu); + } +@@ -295,6 +296,7 @@ EXPORT_SYMBOL(console_srcu_read_lock); + * Counterpart to console_srcu_read_lock() + */ + void console_srcu_read_unlock(int cookie) ++ __releases(&console_srcu) + { + srcu_read_unlock_nmisafe(&console_srcu, cookie); + } diff --git a/debian/patches-rt/0001-printk-ringbuffer-Clarify-special-lpos-values.patch b/debian/patches-rt/0001-printk-ringbuffer-Clarify-special-lpos-values.patch deleted file mode 100644 index e4ea76a5c3..0000000000 --- a/debian/patches-rt/0001-printk-ringbuffer-Clarify-special-lpos-values.patch +++ /dev/null @@ -1,95 +0,0 @@ -From: John Ogness -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 -values (in fields of @prb_desc.text_blk_lpos). - -Currently the macro NO_LPOS is used for empty line records. -This name is confusing because it does not imply _why_ there is -no data block. - -Rename NO_LPOS to EMPTY_LINE_LPOS so that it is clear why there -is no data block. - -Also add comments explaining the use of EMPTY_LINE_LPOS as well -as clarification to the values used to represent data-less -blocks. - -Signed-off-by: John Ogness -Reviewed-by: Petr Mladek -Link: https://lore.kernel.org/r/20240207134103.1357162-6-john.ogness@linutronix.de -Signed-off-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/printk_ringbuffer.c | 20 ++++++++++++++++---- - kernel/printk/printk_ringbuffer.h | 16 +++++++++++++++- - 2 files changed, 31 insertions(+), 5 deletions(-) - ---- a/kernel/printk/printk_ringbuffer.c -+++ b/kernel/printk/printk_ringbuffer.c -@@ -1034,9 +1034,13 @@ static char *data_alloc(struct printk_ri - unsigned long next_lpos; - - if (size == 0) { -- /* Specify a data-less block. */ -- blk_lpos->begin = NO_LPOS; -- blk_lpos->next = NO_LPOS; -+ /* -+ * Data blocks are not created for empty lines. Instead, the -+ * reader will recognize these special lpos values and handle -+ * it appropriately. -+ */ -+ blk_lpos->begin = EMPTY_LINE_LPOS; -+ blk_lpos->next = EMPTY_LINE_LPOS; - return NULL; - } - -@@ -1214,10 +1218,18 @@ static const char *get_data(struct prb_d - - /* Data-less data block description. */ - if (BLK_DATALESS(blk_lpos)) { -- if (blk_lpos->begin == NO_LPOS && blk_lpos->next == NO_LPOS) { -+ /* -+ * Records that are just empty lines are also valid, even -+ * though they do not have a data block. For such records -+ * explicitly return empty string data to signify success. -+ */ -+ if (blk_lpos->begin == EMPTY_LINE_LPOS && -+ blk_lpos->next == EMPTY_LINE_LPOS) { - *data_size = 0; - return ""; - } -+ -+ /* Data lost, invalid, or otherwise unavailable. */ - return NULL; - } - ---- a/kernel/printk/printk_ringbuffer.h -+++ b/kernel/printk/printk_ringbuffer.h -@@ -127,8 +127,22 @@ enum desc_state { - #define DESC_SV(id, state) (((unsigned long)state << DESC_FLAGS_SHIFT) | id) - #define DESC_ID_MASK (~DESC_FLAGS_MASK) - #define DESC_ID(sv) ((sv) & DESC_ID_MASK) -+ -+/* -+ * Special data block logical position values (for fields of -+ * @prb_desc.text_blk_lpos). -+ * -+ * - Bit0 is used to identify if the record has no data block. (Implemented in -+ * the LPOS_DATALESS() macro.) -+ * -+ * - Bit1 specifies the reason for not having a data block. -+ * -+ * These special values could never be real lpos values because of the -+ * meta data and alignment padding of data blocks. (See to_blk_size() for -+ * details.) -+ */ - #define FAILED_LPOS 0x1 --#define NO_LPOS 0x3 -+#define EMPTY_LINE_LPOS 0x3 - - #define FAILED_BLK_LPOS \ - { \ 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 366fb021df..716c67be4e 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1791,6 +1791,7 @@ static inline int dl_task_check_affinity +@@ -1795,6 +1795,7 @@ static inline int dl_task_check_affinity } #endif @@ -30,7 +30,7 @@ Signed-off-by: Sebastian Andrzej Siewior extern int task_prio(const struct task_struct *p); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -8890,6 +8890,21 @@ static inline void preempt_dynamic_init( +@@ -8911,6 +8911,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 deleted file mode 100644 index 9acb1fcaa1..0000000000 --- a/debian/patches-rt/0001-serial-amba-pl011-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,92 +0,0 @@ -From: Sebastian Andrzej Siewior -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 -Link: https://lore.kernel.org/r/20240301215246.891055-2-bigeasy@linutronix.de -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 8cff78066f..175da5e4b4 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 index acdfbddf5a..3e4b5b7bec 100644 --- 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 @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior -Date: Sat, 9 Mar 2024 10:05:10 +0100 +Date: Mon, 25 Mar 2024 08:40:29 +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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -60,7 +60,7 @@ argument "thread_backlog_napi". It is mandatory for PREEMPT_RT to avoid the wakeup of ksoftirqd from the IPI. Acked-by: Jakub Kicinski -Link: https://lore.kernel.org/r/20240309090824.2956805-3-bigeasy@linutronix.de +Link: https://lore.kernel.org/r/20240325074943.289909-3-bigeasy@linutronix.de Signed-off-by: Sebastian Andrzej Siewior --- net/core/dev.c | 152 +++++++++++++++++++++++++++++++++++++++++++-------------- @@ -76,7 +76,7 @@ Signed-off-by: Sebastian Andrzej Siewior #include #include #include -@@ -216,6 +217,31 @@ static inline struct hlist_head *dev_ind +@@ -197,6 +198,31 @@ static inline struct hlist_head *dev_ind return &net->dev_index_head[ifindex & (NETDEV_HASHENTRIES - 1)]; } @@ -108,15 +108,15 @@ Signed-off-by: Sebastian Andrzej Siewior static inline void rps_lock_irqsave(struct softnet_data *sd, unsigned long *flags) { -@@ -4420,6 +4446,7 @@ EXPORT_SYMBOL(__dev_direct_xmit); +@@ -4410,6 +4436,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 + unsigned int sysctl_skb_defer_max __read_mostly = 64; + int weight_p __read_mostly = 64; /* old backlog weight */ +@@ -4433,12 +4460,16 @@ static inline void ____napi_schedule(str */ thread = READ_ONCE(napi->thread); if (thread) { @@ -133,7 +133,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -4678,6 +4709,11 @@ static void napi_schedule_rps(struct sof #ifdef CONFIG_RPS if (sd != mysd) { @@ -145,7 +145,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -5937,7 +5973,7 @@ static void net_rps_action_and_irq_enabl #ifdef CONFIG_RPS struct softnet_data *remsd = sd->rps_ipi_list; @@ -154,7 +154,7 @@ Signed-off-by: Sebastian Andrzej Siewior sd->rps_ipi_list = NULL; local_irq_enable(); -@@ -5941,7 +5977,7 @@ static void net_rps_action_and_irq_enabl +@@ -5952,7 +5988,7 @@ static void net_rps_action_and_irq_enabl static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) { #ifdef CONFIG_RPS @@ -163,7 +163,7 @@ Signed-off-by: Sebastian Andrzej Siewior #else return false; #endif -@@ -5985,7 +6021,7 @@ static int process_backlog(struct napi_s +@@ -5996,7 +6032,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. */ @@ -172,8 +172,8 @@ Signed-off-by: Sebastian Andrzej Siewior again = false; } else { skb_queue_splice_tail_init(&sd->input_pkt_queue, -@@ -6691,43 +6727,48 @@ static void skb_defer_free_flush(struct - } +@@ -6732,43 +6768,48 @@ static int napi_thread_wait(struct napi_ + return -1; } -static int napi_threaded_poll(void *data) @@ -250,7 +250,7 @@ Signed-off-by: Sebastian Andrzej Siewior return 0; } -@@ -11326,7 +11367,7 @@ static int dev_cpu_dead(unsigned int old +@@ -11369,7 +11410,7 @@ static int dev_cpu_dead(unsigned int old list_del_init(&napi->poll_list); if (napi->poll == process_backlog) @@ -259,7 +259,7 @@ Signed-off-by: Sebastian Andrzej Siewior else ____napi_schedule(sd, napi); } -@@ -11334,12 +11375,14 @@ static int dev_cpu_dead(unsigned int old +@@ -11377,12 +11418,14 @@ static int dev_cpu_dead(unsigned int old raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); @@ -278,9 +278,9 @@ Signed-off-by: Sebastian Andrzej Siewior /* 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( - * - */ +@@ -11721,6 +11764,38 @@ static int net_page_pool_create(int cpui + return 0; + } +static int backlog_napi_should_run(unsigned int cpu) +{ @@ -317,11 +317,14 @@ Signed-off-by: Sebastian Andrzej Siewior /* * 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) +@@ -11772,10 +11847,13 @@ 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 (net_page_pool_create(i)) + goto out; } + if (use_backlog_threads()) + smpboot_register_percpu_thread(&backlog_threads); 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 index e6e684ad51..03a9a576ad 100644 --- 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 @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior 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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -89,7 +89,7 @@ Signed-off-by: Sebastian Andrzej Siewior if (event->pending_disable) { event->pending_disable = 0; perf_event_disable_local(event); -@@ -9592,14 +9572,23 @@ static int __perf_event_overflow(struct +@@ -9588,14 +9568,23 @@ static int __perf_event_overflow(struct if (regs) pending_id = hash32_ptr((void *)instruction_pointer(regs)) ?: 1; @@ -117,7 +117,7 @@ Signed-off-by: Sebastian Andrzej Siewior * * 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 +@@ -9605,7 +9594,7 @@ static int __perf_event_overflow(struct * To approximate progress (with false negatives), * check 32-bit hash of the current IP. */ @@ -126,7 +126,7 @@ Signed-off-by: Sebastian Andrzej Siewior } event->pending_addr = 0; -@@ -13049,6 +13038,13 @@ static void sync_child_event(struct perf +@@ -13045,6 +13034,13 @@ static void sync_child_event(struct perf &parent_event->child_total_time_running); } @@ -140,7 +140,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -13084,6 +13080,17 @@ perf_event_exit_event(struct perf_event * Kick perf_poll() for is_event_hup(); */ perf_event_wakeup(parent_event); diff --git a/debian/patches-rt/0002-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch b/debian/patches-rt/0002-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch new file mode 100644 index 0000000000..e42d83f140 --- /dev/null +++ b/debian/patches-rt/0002-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch @@ -0,0 +1,190 @@ +From: Petr Mladek +Date: Wed, 22 Nov 2023 11:23:43 +0000 +Subject: [PATCH 02/46] printk: Properly deal with nbcon consoles on seq init +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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, avoid usage of con->seq as temporary storage of the +starting record. Instead, rename console_init_seq() to +get_init_console_seq() and just return the value. For nbcon +consoles set the sequence via nbcon_init(), for legacy consoles +set con->seq. + +The cleaned design should make sure that the value stays and is +set before the printing kthread is created. + +Signed-off-by: Petr Mladek +Reviewed-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 4 ++-- + kernel/printk/nbcon.c | 10 +++------- + kernel/printk/printk.c | 41 +++++++++++++++++++++++++++++------------ + 3 files changed, 34 insertions(+), 21 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -75,7 +75,7 @@ u16 printk_parse_prefix(const char *text + u64 nbcon_seq_read(struct console *con); + void nbcon_seq_force(struct console *con, u64 seq); + bool nbcon_alloc(struct console *con); +-void nbcon_init(struct console *con); ++void nbcon_init(struct console *con, u64 init_seq); + void nbcon_free(struct console *con); + + #else +@@ -96,7 +96,7 @@ static inline bool printk_percpu_data_re + static inline u64 nbcon_seq_read(struct console *con) { return 0; } + static inline void nbcon_seq_force(struct console *con, u64 seq) { } + static inline bool nbcon_alloc(struct console *con) { return false; } +-static inline void nbcon_init(struct console *con) { } ++static inline void nbcon_init(struct console *con, u64 init_seq) { } + static inline void nbcon_free(struct console *con) { } + + #endif /* CONFIG_PRINTK */ +--- 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; + } + + /** +@@ -961,20 +958,19 @@ bool nbcon_alloc(struct console *con) + /** + * nbcon_init - Initialize the nbcon console specific data + * @con: Console to initialize ++ * @init_seq: Sequence number of the first record to be emitted + * + * 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) ++void nbcon_init(struct console *con, u64 init_seq) + { + struct nbcon_state state = { }; + + /* nbcon_alloc() must have been called and successful! */ + BUG_ON(!con->pbufs); + +- nbcon_seq_force(con, con->seq); ++ nbcon_seq_force(con, init_seq); + nbcon_state_set(con, &state); + } + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -3363,19 +3363,21 @@ static void try_enable_default_console(s + newcon->flags |= CON_CONSDEV; + } + +-static void console_init_seq(struct console *newcon, bool bootcon_registered) ++/* Return the starting sequence number for a newly registered console. */ ++static u64 get_init_console_seq(struct console *newcon, bool bootcon_registered) + { + struct console *con; + bool handover; ++ u64 init_seq; + + if (newcon->flags & (CON_PRINTBUFFER | CON_BOOT)) { + /* Get a consistent copy of @syslog_seq. */ + mutex_lock(&syslog_lock); +- newcon->seq = syslog_seq; ++ init_seq = syslog_seq; + mutex_unlock(&syslog_lock); + } else { + /* Begin with next message added to ringbuffer. */ +- newcon->seq = prb_next_seq(prb); ++ init_seq = prb_next_seq(prb); + + /* + * If any enabled boot consoles are due to be unregistered +@@ -3396,7 +3398,7 @@ static void console_init_seq(struct cons + * Flush all consoles and set the console to start at + * the next unprinted sequence number. + */ +- if (!console_flush_all(true, &newcon->seq, &handover)) { ++ if (!console_flush_all(true, &init_seq, &handover)) { + /* + * Flushing failed. Just choose the lowest + * sequence of the enabled boot consoles. +@@ -3409,19 +3411,30 @@ static void console_init_seq(struct cons + if (handover) + console_lock(); + +- newcon->seq = prb_next_seq(prb); ++ init_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 < init_seq) ++ init_seq = seq; + } + } + + console_unlock(); + } + } ++ ++ return init_seq; + } + + #define console_first() \ +@@ -3453,6 +3466,7 @@ void register_console(struct console *ne + struct console *con; + bool bootcon_registered = false; + bool realcon_registered = false; ++ u64 init_seq; + int err; + + console_list_lock(); +@@ -3530,10 +3544,13 @@ void register_console(struct console *ne + } + + newcon->dropped = 0; +- console_init_seq(newcon, bootcon_registered); ++ init_seq = get_init_console_seq(newcon, bootcon_registered); + +- if (newcon->flags & CON_NBCON) +- nbcon_init(newcon); ++ if (newcon->flags & CON_NBCON) { ++ nbcon_init(newcon, init_seq); ++ } else { ++ newcon->seq = init_seq; ++ } + + /* + * Put this console in the list - keep the 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 deleted file mode 100644 index f8f97abf10..0000000000 --- a/debian/patches-rt/0002-serial-ar933x-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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 24f73e8d86..50da7bdae5 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -38,7 +38,7 @@ Signed-off-by: Sebastian Andrzej Siewior #endif /* _LINUX_BH_H */ --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -247,6 +247,19 @@ void __local_bh_enable_ip(unsigned long +@@ -248,6 +248,19 @@ void __local_bh_enable_ip(unsigned long } EXPORT_SYMBOL(__local_bh_enable_ip); 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 2e2ea53f2a..4ec0cd7b62 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 86275329f1..5c4a72e137 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz Mario Kleiner suggest in commit ad3543ede630f ("drm/intel: Push get_scanout_position() timestamping into kms driver.") @@ -34,7 +34,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c -@@ -275,6 +275,26 @@ int intel_crtc_scanline_to_hw(struct int +@@ -276,6 +276,26 @@ int intel_crtc_scanline_to_hw(struct int * all register accesses to the same cacheline to be serialized, * otherwise they may hang. */ @@ -61,7 +61,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -333,10 +353,10 @@ static bool i915_get_crtc_scanoutpos(str * timing critical raw register reads, potentially with * preemption disabled, so the following code must not block. */ @@ -75,7 +75,7 @@ Signed-off-by: Sebastian Andrzej Siewior /* Get optional system timestamp before query. */ if (stime) -@@ -399,10 +419,10 @@ static bool i915_get_crtc_scanoutpos(str +@@ -400,10 +420,10 @@ static bool i915_get_crtc_scanoutpos(str if (etime) *etime = ktime_get(); @@ -89,7 +89,7 @@ Signed-off-by: Sebastian Andrzej Siewior /* * While in vblank, position will be negative -@@ -440,13 +460,11 @@ int intel_get_crtc_scanline(struct intel +@@ -441,13 +461,11 @@ int intel_get_crtc_scanline(struct intel unsigned long irqflags; int 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 index ae46bdf942..66b0a2cf23 100644 --- 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 @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior -Date: Sat, 9 Mar 2024 10:05:11 +0100 +Date: Mon, 25 Mar 2024 08:40:30 +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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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. @@ -26,7 +26,7 @@ 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 -Link: https://lore.kernel.org/r/20240309090824.2956805-4-bigeasy@linutronix.de +Link: https://lore.kernel.org/r/20240325074943.289909-4-bigeasy@linutronix.de Signed-off-by: Sebastian Andrzej Siewior --- include/linux/netdevice.h | 1 + @@ -36,7 +36,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -3365,6 +3365,7 @@ static inline void dev_xmit_recursion_de +@@ -3287,6 +3287,7 @@ static inline void dev_xmit_recursion_de __this_cpu_dec(softnet_data.xmit.recursion); } @@ -46,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -245,7 +245,7 @@ static bool use_backlog_threads(void) +@@ -226,7 +226,7 @@ static bool use_backlog_threads(void) static inline void rps_lock_irqsave(struct softnet_data *sd, unsigned long *flags) { @@ -55,7 +55,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -234,7 +234,7 @@ static inline void rps_lock_irqsave(stru static inline void rps_lock_irq_disable(struct softnet_data *sd) { @@ -64,7 +64,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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( +@@ -243,7 +243,7 @@ static inline void rps_lock_irq_disable( static inline void rps_unlock_irq_restore(struct softnet_data *sd, unsigned long *flags) { @@ -73,7 +73,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -251,7 +251,7 @@ static inline void rps_unlock_irq_restor static inline void rps_unlock_irq_enable(struct softnet_data *sd) { @@ -82,7 +82,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -4728,6 +4728,23 @@ static void napi_schedule_rps(struct sof __napi_schedule_irqoff(&mysd->backlog); } @@ -108,7 +108,7 @@ Signed-off-by: Sebastian Andrzej Siewior #endif --- a/net/core/skbuff.c +++ b/net/core/skbuff.c -@@ -6929,8 +6929,8 @@ nodefer: __kfree_skb(skb); +@@ -7050,8 +7050,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). */ 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 index 150b5530d2..55e31a0ebd 100644 --- 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 @@ -2,7 +2,7 @@ From: Sebastian Andrzej Siewior 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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 diff --git a/debian/patches-rt/0003-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch b/debian/patches-rt/0003-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch deleted file mode 100644 index d7575e9a50..0000000000 --- a/debian/patches-rt/0003-printk-Avoid-non-panic-CPUs-writing-to-ringbuffer.patch +++ /dev/null @@ -1,86 +0,0 @@ -From: John Ogness -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 -if too many messages are being dropped. Aside from trying to -workaround the livelock bugs of legacy consoles, it was also -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 -Reviewed-by: Petr Mladek -Link: https://lore.kernel.org/r/20240207134103.1357162-13-john.ogness@linutronix.de -Signed-off-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/printk.c | 26 ++++++-------------------- - 1 file changed, 6 insertions(+), 20 deletions(-) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -462,12 +462,6 @@ static int console_msg_format = MSG_FORM - static DEFINE_MUTEX(syslog_lock); - - #ifdef CONFIG_PRINTK --/* -- * During panic, heavy printk by other CPUs can delay the -- * panic and risk deadlock on console resources. -- */ --static int __read_mostly suppress_panic_printk; -- - DECLARE_WAIT_QUEUE_HEAD(log_wait); - /* All 3 protected by @syslog_lock. */ - /* the next printk record to read by syslog(READ) or /proc/kmsg */ -@@ -2322,7 +2316,12 @@ asmlinkage int vprintk_emit(int facility - if (unlikely(suppress_printk)) - return 0; - -- if (unlikely(suppress_panic_printk) && other_cpu_in_panic()) -+ /* -+ * The messages on the panic CPU are the most important. If -+ * non-panic CPUs are generating any messages, they will be -+ * silently dropped. -+ */ -+ if (other_cpu_in_panic()) - return 0; - - if (level == LOGLEVEL_SCHED) { -@@ -2807,8 +2806,6 @@ void console_prepend_dropped(struct prin - bool printk_get_next_message(struct printk_message *pmsg, u64 seq, - bool is_extended, bool may_suppress) - { -- static int panic_console_dropped; -- - struct printk_buffers *pbufs = pmsg->pbufs; - const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf); - const size_t outbuf_sz = sizeof(pbufs->outbuf); -@@ -2836,17 +2833,6 @@ bool printk_get_next_message(struct prin - pmsg->seq = r.info->seq; - pmsg->dropped = r.info->seq - seq; - -- /* -- * Check for dropped messages in panic here so that printk -- * suppression can occur as early as possible if necessary. -- */ -- if (pmsg->dropped && -- panic_in_progress() && -- panic_console_dropped++ > 10) { -- suppress_panic_printk = 1; -- pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n"); -- } -- - /* Skip record that has level above the console loglevel. */ - if (may_suppress && suppress_message_printing(r.info->level)) - goto out; diff --git a/debian/patches-rt/0003-printk-nbcon-Remove-return-value-for-write_atomic.patch b/debian/patches-rt/0003-printk-nbcon-Remove-return-value-for-write_atomic.patch new file mode 100644 index 0000000000..92ecbe0366 --- /dev/null +++ b/debian/patches-rt/0003-printk-nbcon-Remove-return-value-for-write_atomic.patch @@ -0,0 +1,69 @@ +From: John Ogness +Date: Fri, 20 Oct 2023 09:52:59 +0000 +Subject: [PATCH 03/46] printk: nbcon: Remove return value for write_atomic() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + 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 +@@ -345,7 +345,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/0003-serial-bcm63xx-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0003-serial-bcm63xx-Use-uart_prepare_sysrq_char.patch deleted file mode 100644 index 580b336885..0000000000 --- a/debian/patches-rt/0003-serial-bcm63xx-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,78 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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 486b98521f..3b6f87857c 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/kernel/time/timer.c +++ b/kernel/time/timer.c -@@ -1470,9 +1470,16 @@ static inline void timer_base_unlock_exp +@@ -1563,9 +1563,16 @@ static inline void timer_base_unlock_exp */ static void timer_sync_wait_running(struct timer_base *base) { 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 b5f618d1c5..34f4e6e0ec 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 3d26b9d6cc..aebb5534f6 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz Commit 8d7849db3eab7 ("drm/i915: Make sprite updates atomic") @@ -32,12 +32,13 @@ Don't disable interrupts on PREEMPT_RT during atomic updates. Signed-off-by: Mike Galbraith Signed-off-by: Sebastian Andrzej Siewior --- - drivers/gpu/drm/i915/display/intel_crtc.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) + drivers/gpu/drm/i915/display/intel_crtc.c | 9 ++++++--- + drivers/gpu/drm/i915/display/intel_vblank.c | 6 ++++-- + 2 files changed, 10 insertions(+), 5 deletions(-) --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c -@@ -580,7 +580,8 @@ void intel_pipe_update_start(struct inte +@@ -512,7 +512,8 @@ void intel_pipe_update_start(struct inte */ intel_psr_wait_for_idle_locked(new_crtc_state); @@ -45,25 +46,9 @@ Signed-off-by: Sebastian Andrzej Siewior + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_irq_disable(); - crtc->debug.min_vbl = min; - crtc->debug.max_vbl = max; -@@ -605,11 +606,13 @@ void intel_pipe_update_start(struct inte - break; - } - -- local_irq_enable(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ local_irq_enable(); - - timeout = schedule_timeout(timeout); - -- local_irq_disable(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ local_irq_disable(); - } - - finish_wait(wq, &wait); -@@ -642,7 +645,8 @@ void intel_pipe_update_start(struct inte + crtc->debug.min_vbl = evade.min; + crtc->debug.max_vbl = evade.max; +@@ -530,7 +531,8 @@ void intel_pipe_update_start(struct inte return; irq_disable: @@ -73,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior } #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE) -@@ -744,7 +748,8 @@ void intel_pipe_update_end(struct intel_ +@@ -632,7 +634,8 @@ void intel_pipe_update_end(struct intel_ */ intel_vrr_send_push(new_crtc_state); @@ -83,3 +68,21 @@ Signed-off-by: Sebastian Andrzej Siewior if (intel_vgpu_active(dev_priv)) goto out; +--- a/drivers/gpu/drm/i915/display/intel_vblank.c ++++ b/drivers/gpu/drm/i915/display/intel_vblank.c +@@ -700,11 +700,13 @@ int intel_vblank_evade(struct intel_vbla + break; + } + +- local_irq_enable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_enable(); + + timeout = schedule_timeout(timeout); + +- local_irq_disable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_disable(); + } + + finish_wait(wq, &wait); 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 index 70de5b94e2..c40d93a753 100644 --- 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 @@ -1,7 +1,7 @@ From: Sebastian Andrzej Siewior -Date: Sat, 9 Mar 2024 10:05:12 +0100 +Date: Mon, 25 Mar 2024 08:40:31 +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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -19,7 +19,7 @@ Rename the rps_lock*() functions to backlog_lock*(). Suggested-by: Jakub Kicinski Acked-by: Jakub Kicinski -Link: https://lore.kernel.org/r/20240309090824.2956805-5-bigeasy@linutronix.de +Link: https://lore.kernel.org/r/20240325074943.289909-5-bigeasy@linutronix.de Signed-off-by: Sebastian Andrzej Siewior --- net/core/dev.c | 34 +++++++++++++++++----------------- @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -242,8 +242,8 @@ static bool use_backlog_threads(void) +@@ -223,8 +223,8 @@ static bool use_backlog_threads(void) #endif @@ -38,7 +38,7 @@ Signed-off-by: Sebastian Andrzej Siewior { 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 +@@ -232,7 +232,7 @@ static inline void rps_lock_irqsave(stru local_irq_save(*flags); } @@ -47,7 +47,7 @@ Signed-off-by: Sebastian Andrzej Siewior { 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( +@@ -240,8 +240,8 @@ static inline void rps_lock_irq_disable( local_irq_disable(); } @@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior { 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 +@@ -249,7 +249,7 @@ static inline void rps_unlock_irq_restor local_irq_restore(*flags); } @@ -67,7 +67,7 @@ Signed-off-by: Sebastian Andrzej Siewior { 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 +@@ -4733,12 +4733,12 @@ void kick_defer_list_purge(struct softne unsigned long flags; if (use_backlog_threads()) { @@ -82,7 +82,7 @@ Signed-off-by: Sebastian Andrzej Siewior } 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_ +@@ -4800,7 +4800,7 @@ static int enqueue_to_backlog(struct sk_ reason = SKB_DROP_REASON_NOT_SPECIFIED; sd = &per_cpu(softnet_data, cpu); @@ -91,7 +91,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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_ +@@ -4810,7 +4810,7 @@ static int enqueue_to_backlog(struct sk_ enqueue: __skb_queue_tail(&sd->input_pkt_queue, skb); input_queue_tail_incr_save(sd, qtail); @@ -100,7 +100,7 @@ Signed-off-by: Sebastian Andrzej Siewior return NET_RX_SUCCESS; } -@@ -4849,7 +4849,7 @@ static int enqueue_to_backlog(struct sk_ +@@ -4825,7 +4825,7 @@ static int enqueue_to_backlog(struct sk_ drop: sd->dropped++; @@ -109,7 +109,7 @@ Signed-off-by: Sebastian Andrzej Siewior dev_core_stats_rx_dropped_inc(skb->dev); kfree_skb_reason(skb, reason); -@@ -5880,7 +5880,7 @@ static void flush_backlog(struct work_st +@@ -5891,7 +5891,7 @@ static void flush_backlog(struct work_st local_bh_disable(); sd = this_cpu_ptr(&softnet_data); @@ -118,7 +118,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -5899,7 +5899,7 @@ static void flush_backlog(struct work_st input_queue_head_incr(sd); } } @@ -127,7 +127,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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) +@@ -5917,14 +5917,14 @@ static bool flush_required(int cpu) struct softnet_data *sd = &per_cpu(softnet_data, cpu); bool do_flush; @@ -144,7 +144,7 @@ Signed-off-by: Sebastian Andrzej Siewior return do_flush; #endif -@@ -6028,7 +6028,7 @@ static int process_backlog(struct napi_s +@@ -6039,7 +6039,7 @@ static int process_backlog(struct napi_s } @@ -153,7 +153,7 @@ Signed-off-by: Sebastian Andrzej Siewior 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 +@@ -6055,7 +6055,7 @@ static int process_backlog(struct napi_s skb_queue_splice_tail_init(&sd->input_pkt_queue, &sd->process_queue); } 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 index 3f1d2a5e00..a96b966fa5 100644 --- 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 @@ -2,7 +2,7 @@ From: Sebastian Andrzej Siewior 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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -115,7 +115,7 @@ Signed-off-by: Sebastian Andrzej Siewior if (rctx >= 0) perf_swevent_put_recursion_context(rctx); } -@@ -9572,7 +9586,7 @@ static int __perf_event_overflow(struct +@@ -9568,7 +9582,7 @@ static int __perf_event_overflow(struct * is processed. */ if (in_nmi()) @@ -124,7 +124,7 @@ Signed-off-by: Sebastian Andrzej Siewior } 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 +@@ -11908,6 +11922,7 @@ perf_event_alloc(struct perf_event_attr init_waitqueue_head(&event->waitq); init_irq_work(&event->pending_irq, perf_pending_irq); diff --git a/debian/patches-rt/0004-printk-Check-printk_deferred_enter-_exit-usage.patch b/debian/patches-rt/0004-printk-Check-printk_deferred_enter-_exit-usage.patch new file mode 100644 index 0000000000..4cde1a93e9 --- /dev/null +++ b/debian/patches-rt/0004-printk-Check-printk_deferred_enter-_exit-usage.patch @@ -0,0 +1,74 @@ +From: Sebastian Andrzej Siewior +Date: Fri, 22 Sep 2023 14:58:18 +0000 +Subject: [PATCH 04/46] printk: Check printk_deferred_enter()/_exit() usage +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Add validation that printk_deferred_enter()/_exit() are called in +non-migration contexts. + +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/printk.h | 9 +++++---- + kernel/printk/internal.h | 3 +++ + kernel/printk/printk_safe.c | 12 ++++++++++++ + 3 files changed, 20 insertions(+), 4 deletions(-) + +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -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_deferred_enter(void); ++extern void __printk_deferred_exit(void); ++ + /* + * The printk_deferred_enter/exit macros are available only as a hack for + * some code paths that need to defer all printk console printing. Interrupts + * must be disabled for the deferred duration. + */ +-#define printk_deferred_enter __printk_safe_enter +-#define printk_deferred_exit __printk_safe_exit ++#define printk_deferred_enter() __printk_deferred_enter() ++#define printk_deferred_exit() __printk_deferred_exit() + + /* + * 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) + this_cpu_dec(printk_context); + } + ++void __printk_deferred_enter(void) ++{ ++ cant_migrate(); ++ __printk_safe_enter(); ++} ++ ++void __printk_deferred_exit(void) ++{ ++ cant_migrate(); ++ __printk_safe_exit(); ++} ++ + asmlinkage int vprintk(const char *fmt, va_list args) + { + #ifdef CONFIG_KGDB_KDB 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 deleted file mode 100644 index d85b4e4333..0000000000 --- a/debian/patches-rt/0004-serial-meson-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,77 +0,0 @@ -From: Sebastian Andrzej Siewior -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 -Cc: Jerome Brunet -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 ---- - 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 d61e6d3cda..c985a8382f 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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-printk-nbcon-Add-detailed-doc-for-write_atomic.patch b/debian/patches-rt/0005-printk-nbcon-Add-detailed-doc-for-write_atomic.patch new file mode 100644 index 0000000000..7d6a606df3 --- /dev/null +++ b/debian/patches-rt/0005-printk-nbcon-Add-detailed-doc-for-write_atomic.patch @@ -0,0 +1,72 @@ +From: John Ogness +Date: Wed, 7 Feb 2024 18:38:14 +0000 +Subject: [PATCH 05/46] printk: nbcon: Add detailed doc for write_atomic() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/console.h | 33 +++++++++++++++++++++++++++++---- + 1 file changed, 29 insertions(+), 4 deletions(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -303,7 +303,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) +@@ -320,7 +320,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 +@@ -345,8 +344,34 @@ 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. However, ++ * a higher priority context is allowed to take it over by default. ++ * ++ * The callback must call nbcon_enter_unsafe() and nbcon_exit_unsafe() ++ * around any code where the takeover is not safe, for example, when ++ * manipulating the serial port registers. ++ * ++ * nbcon_enter_unsafe() will fail if the context has lost the console ++ * ownership in the meantime. In this case, the callback is no longer ++ * allowed to go forward. It must back out immediately and carefully. ++ * The buffer content is also no longer trusted since it no longer ++ * belongs to the context. ++ * ++ * The callback should allow the takeover whenever it is safe. It ++ * increases the chance to see messages when the system is in trouble. ++ * ++ * The 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/0005-serial-msm-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch deleted file mode 100644 index 75c822db47..0000000000 --- a/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,116 +0,0 @@ -From: Sebastian Andrzej Siewior -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 -Cc: Konrad Dybcio -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 ---- - 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 deleted file mode 100644 index 39bda39263..0000000000 --- a/debian/patches-rt/0006-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Sebastian Andrzej Siewior -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.8/older/patches-6.8.2-rt11.tar.xz - -Luca Abeni reported this: -| BUG: scheduling while atomic: kworker/u8:2/15203/0x00000003 -| CPU: 1 PID: 15203 Comm: kworker/u8:2 Not tainted 4.19.1-rt3 #10 -| Call Trace: -| rt_spin_lock+0x3f/0x50 -| gen6_read32+0x45/0x1d0 [i915] -| g4x_get_vblank_counter+0x36/0x40 [i915] -| trace_event_raw_event_i915_pipe_update_start+0x7d/0xf0 [i915] - -The tracing events use trace_i915_pipe_update_start() among other events -use functions acquire spinlock_t locks which are transformed into -sleeping locks on PREEMPT_RT. A few trace points use -intel_get_crtc_scanline(), others use ->get_vblank_counter() wich also -might acquire a sleeping locks on PREEMPT_RT. -At the time the arguments are evaluated within trace point, preemption -is disabled and so the locks must not be acquired on PREEMPT_RT. - -Based on this I don't see any other way than disable trace points on -PREMPT_RT. - -Reported-by: Luca Abeni -Cc: Steven Rostedt -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/gpu/drm/i915/i915_trace.h | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/gpu/drm/i915/i915_trace.h -+++ b/drivers/gpu/drm/i915/i915_trace.h -@@ -6,6 +6,10 @@ - #if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) - #define _I915_TRACE_H_ - -+#ifdef CONFIG_PREEMPT_RT -+#define NOTRACE -+#endif -+ - #include - #include - #include diff --git a/debian/patches-rt/0006-printk-Add-notation-to-console_srcu-locking.patch b/debian/patches-rt/0006-printk-Add-notation-to-console_srcu-locking.patch deleted file mode 100644 index 077a2d2a1a..0000000000 --- a/debian/patches-rt/0006-printk-Add-notation-to-console_srcu-locking.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: John Ogness -Date: Mon, 9 Oct 2023 13:55:19 +0000 -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 - -Fixes: 6c4afa79147e ("printk: Prepare for SRCU console list protection") -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/printk.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -282,6 +282,7 @@ EXPORT_SYMBOL(console_list_unlock); - * Return: A cookie to pass to console_srcu_read_unlock(). - */ - int console_srcu_read_lock(void) -+ __acquires(&console_srcu) - { - return srcu_read_lock_nmisafe(&console_srcu); - } -@@ -295,6 +296,7 @@ EXPORT_SYMBOL(console_srcu_read_lock); - * Counterpart to console_srcu_read_lock() - */ - void console_srcu_read_unlock(int cookie) -+ __releases(&console_srcu) - { - srcu_read_unlock_nmisafe(&console_srcu, cookie); - } diff --git a/debian/patches-rt/0006-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch b/debian/patches-rt/0006-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch new file mode 100644 index 0000000000..0323d580c4 --- /dev/null +++ b/debian/patches-rt/0006-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch @@ -0,0 +1,84 @@ +From: John Ogness +Date: Mon, 18 Mar 2024 10:11:56 +0000 +Subject: [PATCH 06/46] printk: nbcon: Add callbacks to synchronize with driver +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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. To provide the +necessary synchronization, usually some driver-specific locking +mechanism is used (for example, the port spinlock for uart +serial consoles). + +Until now, usage of this driver-specific locking has been hidden +from the printk-subsystem and implemented within the various +console callbacks. However, for nbcon consoles, it is necessary +that the printk-subsystem uses the driver-specific locking so +that nbcon console ownership can be acquired _after_ the +driver-specific locking has succeeded. This allows for lock +contention to exist on the more context-friendly driver-specific +locking rather than nbcon console ownership (for non-emergency +and non-panic cases). + +Require nbcon consoles to implement two new callbacks +(device_lock(), device_unlock()) that will use whatever +synchronization mechanism the driver is using for itself. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/console.h | 43 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -372,6 +372,49 @@ 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). ++ * ++ * The callback is always called from task context. It may use any ++ * synchronization method required by the driver. ++ * ++ * IMPORTANT: The callback MUST 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/0006-serial-omap-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0006-serial-omap-Use-uart_prepare_sysrq_char.patch deleted file mode 100644 index 58fe8b1323..0000000000 --- a/debian/patches-rt/0006-serial-omap-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,66 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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 deleted file mode 100644 index 2d5f24fde2..0000000000 --- a/debian/patches-rt/0007-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Sebastian Andrzej Siewior -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.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 -nop. Currently this happens for two .c files which use the tracepoitns -behind DRM_I915_LOW_LEVEL_TRACEPOINTS. - -Cc: Steven Rostedt -Signed-off-by: Sebastian Andrzej Siewior -Signed-off-by: Thomas Gleixner ---- - drivers/gpu/drm/i915/i915_trace.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/i915/i915_trace.h -+++ b/drivers/gpu/drm/i915/i915_trace.h -@@ -326,7 +326,7 @@ DEFINE_EVENT(i915_request, i915_request_ - TP_ARGS(rq) - ); - --#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) -+#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) && !defined(NOTRACE) - DEFINE_EVENT(i915_request, i915_request_guc_submit, - TP_PROTO(struct i915_request *rq), - TP_ARGS(rq) 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 deleted file mode 100644 index cc54d0652e..0000000000 --- a/debian/patches-rt/0007-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch +++ /dev/null @@ -1,116 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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-printk-nbcon-Use-driver-synchronization-while-un-reg.patch b/debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch new file mode 100644 index 0000000000..08e2d52852 --- /dev/null +++ b/debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch @@ -0,0 +1,109 @@ +From: John Ogness +Date: Fri, 15 Mar 2024 15:38:22 +0000 +Subject: [PATCH 07/46] printk: nbcon: Use driver synchronization while + (un)registering +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Console drivers typically have to deal with access to the +hardware via user input/output (such as an interactive login +shell) and output of kernel messages via printk() calls. + +They use some classic driver-specific locking mechanism in most +situations. But console->write_atomic() callbacks, used by nbcon +consoles, are synchronized only by acquiring the console +context. + +The synchronization via the console context ownership is possible +only when the console driver is registered. It is when a +particular device driver is connected with a particular console +driver. + +The two synchronization mechanisms must be synchronized between +each other. It is tricky because the console context ownership +is quite special. It might be taken over by a higher priority +context. Also CPU migration must be disabled. The most tricky +part is to (dis)connect these two mechanisms during the console +(un)registration. + +Use the driver-specific locking callbacks: device_lock(), +device_unlock(). They allow taking the device-specific lock +while the device is being (un)registered by the related console +driver. + +For example, these callbacks lock/unlock the port lock for +serial port drivers. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/printk.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -3466,6 +3466,7 @@ void register_console(struct console *ne + struct console *con; + bool bootcon_registered = false; + bool realcon_registered = false; ++ unsigned long flags; + u64 init_seq; + int err; + +@@ -3553,6 +3554,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. + */ +@@ -3576,6 +3590,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(); + + /* +@@ -3604,6 +3622,7 @@ EXPORT_SYMBOL(register_console); + /* Must be called under console_list_lock(). */ + static int unregister_console_locked(struct console *console) + { ++ unsigned long flags; + int res; + + lockdep_assert_console_list_lock_held(); +@@ -3622,8 +3641,18 @@ static int unregister_console_locked(str + if (!console_is_registered_locked(console)) + return -ENODEV; + ++ /* ++ * Use the driver synchronization to ensure that the hardware is not ++ * in use while this console transitions to being unregistered. ++ */ ++ if ((console->flags & CON_NBCON) && console->write_atomic) ++ console->device_lock(console, &flags); ++ + hlist_del_init_rcu(&console->node); + ++ if ((console->flags & CON_NBCON) && console->write_atomic) ++ console->device_unlock(console, flags); ++ + /* + * + * If this isn't the last console and it has CON_CONSDEV set, we 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 deleted file mode 100644 index ae76e25872..0000000000 --- a/debian/patches-rt/0007-serial-pxa-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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 deleted file mode 100644 index c7681ff217..0000000000 --- a/debian/patches-rt/0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Sebastian Andrzej Siewior -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.8/older/patches-6.8.2-rt11.tar.xz - -Disabling interrupts and invoking the irq_work function directly breaks -on PREEMPT_RT. -PREEMPT_RT does not invoke all irq_work from hardirq context because -some of the user have spinlock_t locking in the callback function. -These locks are then turned into a sleeping locks which can not be -acquired with disabled interrupts. - -Using irq_work_queue() has the benefit that the irqwork will be invoked -in the regular context. In general there is "no" delay between enqueuing -the callback and its invocation because the interrupt is raised right -away on architectures which support it (which includes x86). - -Use irq_work_queue() + irq_work_sync() instead invoking the callback -directly. - -Reported-by: Clark Williams -Signed-off-by: Sebastian Andrzej Siewior -Reviewed-by: Maarten Lankhorst ---- - drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c -+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c -@@ -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)) { -- local_irq_disable(); -- signal_irq_work(&b->irq_work); -- local_irq_enable(); -+ irq_work_queue(&b->irq_work); - cond_resched(); -+ irq_work_sync(&b->irq_work); - } - } - 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 deleted file mode 100644 index 73b0fe77fd..0000000000 --- a/debian/patches-rt/0008-printk-nbcon-Remove-return-value-for-write_atomic.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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-core-Provide-low-level-functions-to-lock-port.patch b/debian/patches-rt/0008-serial-core-Provide-low-level-functions-to-lock-port.patch new file mode 100644 index 0000000000..75761ae021 --- /dev/null +++ b/debian/patches-rt/0008-serial-core-Provide-low-level-functions-to-lock-port.patch @@ -0,0 +1,50 @@ +From: John Ogness +Date: Mon, 11 Dec 2023 09:19:18 +0000 +Subject: [PATCH 08/46] serial: core: Provide low-level functions to lock port +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Reviewed-by: Petr Mladek +Acked-by: Greg Kroah-Hartman +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/serial_core.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -591,6 +591,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/0008-serial-sunplus-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0008-serial-sunplus-Use-uart_prepare_sysrq_char.patch deleted file mode 100644 index fc7a5b7254..0000000000 --- a/debian/patches-rt/0008-serial-sunplus-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,67 +0,0 @@ -From: Sebastian Andrzej Siewior -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 -Link: https://lore.kernel.org/r/20240301215246.891055-9-bigeasy@linutronix.de -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 b5712afb62..290298aead 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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/0009-printk-Check-printk_deferred_enter-_exit-usage.patch b/debian/patches-rt/0009-printk-Check-printk_deferred_enter-_exit-usage.patch deleted file mode 100644 index b706ad35e4..0000000000 --- a/debian/patches-rt/0009-printk-Check-printk_deferred_enter-_exit-usage.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Sebastian Andrzej Siewior -Date: Fri, 22 Sep 2023 14:58:18 +0000 -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 -Signed-off-by: John Ogness -Reviewed-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/printk.h | 9 +++++---- - kernel/printk/internal.h | 3 +++ - kernel/printk/printk_safe.c | 12 ++++++++++++ - 3 files changed, 20 insertions(+), 4 deletions(-) - ---- a/include/linux/printk.h -+++ b/include/linux/printk.h -@@ -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_deferred_enter(void); -+extern void __printk_deferred_exit(void); -+ - /* - * The printk_deferred_enter/exit macros are available only as a hack for - * some code paths that need to defer all printk console printing. Interrupts - * must be disabled for the deferred duration. - */ --#define printk_deferred_enter __printk_safe_enter --#define printk_deferred_exit __printk_safe_exit -+#define printk_deferred_enter() __printk_deferred_enter() -+#define printk_deferred_exit() __printk_deferred_exit() - - /* - * 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) - this_cpu_dec(printk_context); - } - -+void __printk_deferred_enter(void) -+{ -+ cant_migrate(); -+ __printk_safe_enter(); -+} -+ -+void __printk_deferred_exit(void) -+{ -+ cant_migrate(); -+ __printk_safe_exit(); -+} -+ - asmlinkage int vprintk(const char *fmt, va_list args) - { - #ifdef CONFIG_KGDB_KDB diff --git a/debian/patches-rt/0009-serial-core-Introduce-wrapper-to-set-uart_port-cons.patch b/debian/patches-rt/0009-serial-core-Introduce-wrapper-to-set-uart_port-cons.patch new file mode 100644 index 0000000000..68106c6e89 --- /dev/null +++ b/debian/patches-rt/0009-serial-core-Introduce-wrapper-to-set-uart_port-cons.patch @@ -0,0 +1,116 @@ +From: John Ogness +Date: Wed, 17 Apr 2024 12:13:24 +0000 +Subject: [PATCH 09/46] serial: core: Introduce wrapper to set @uart_port->cons +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +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 is +holding the port lock. This is necessary for a follow-up +commit relating to the port lock wrappers, which rely on @cons +not changing between lock and unlock. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/tty/serial/8250/8250_core.c | 6 +++--- + drivers/tty/serial/amba-pl011.c | 2 +- + drivers/tty/serial/serial_core.c | 16 ++++++++-------- + include/linux/serial_core.h | 17 +++++++++++++++++ + 4 files changed, 29 insertions(+), 12 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 +@@ -3172,8 +3172,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); +@@ -3182,13 +3189,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/serial_core.h ++++ b/include/linux/serial_core.h +@@ -610,6 +610,23 @@ 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); ++} ++/** + * uart_port_lock - Lock the UART port + * @up: Pointer to UART port structure + */ 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 deleted file mode 100644 index e099cf8e60..0000000000 --- a/debian/patches-rt/0009-serial-lpc32xx_hs-Use-uart_prepare_sysrq_char-to-han.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Sebastian Andrzej Siewior -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 -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 ---- - 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-console-Improve-console_srcu_read_flags-comments.patch b/debian/patches-rt/0010-console-Improve-console_srcu_read_flags-comments.patch new file mode 100644 index 0000000000..ea346ac04c --- /dev/null +++ b/debian/patches-rt/0010-console-Improve-console_srcu_read_flags-comments.patch @@ -0,0 +1,72 @@ +From: John Ogness +Date: Wed, 17 Apr 2024 14:34:50 +0000 +Subject: [PATCH 10/46] console: Improve console_srcu_read_flags() comments +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +It was not clear when exactly console_srcu_read_flags() must be +used vs. directly reading @console->flags. + +Refactor and clarify that console_srcu_read_flags() is only +needed if the console is registered or the caller is in a +context where the registration status of the console may change +(due to another context). + +The function requires the caller holds @console_srcu, which will +ensure that the caller sees an appropriate @flags value for the +registered console and that exit/cleanup routines will not run +if the console is in the process of unregistration. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/console.h | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -446,28 +446,34 @@ 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. The purpose of holding console_srcu_read_lock is ++ * to guarantee that the console state is valid (CON_SUSPENDED/CON_ENABLED) ++ * and that no exit/cleanup routines will run if the console is currently ++ * undergoing unregistration. ++ * ++ * If the caller is holding the console_list_lock or it is _certain_ that ++ * @con is not and will not become 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)); + } 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 1cf736b273..a40ec9b965 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz The !irqs_disabled() check triggers on PREEMPT_RT even with i915_sched_engine::lock acquired. The reason is the lock is transformed @@ -21,7 +21,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c -@@ -609,7 +609,6 @@ bool __i915_request_submit(struct i915_r +@@ -608,7 +608,6 @@ bool __i915_request_submit(struct i915_r RQ_TRACE(request, "\n"); @@ -29,7 +29,7 @@ Signed-off-by: Sebastian Andrzej Siewior lockdep_assert_held(&engine->sched_engine->lock); /* -@@ -718,7 +717,6 @@ void __i915_request_unsubmit(struct i915 +@@ -717,7 +716,6 @@ void __i915_request_unsubmit(struct i915 */ RQ_TRACE(request, "\n"); 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 deleted file mode 100644 index 354e027bdb..0000000000 --- a/debian/patches-rt/0010-printk-nbcon-Add-detailed-doc-for-write_atomic.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: John Ogness -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 -Reviewed-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 deleted file mode 100644 index bec90c28e6..0000000000 --- a/debian/patches-rt/0010-serial-owl-Use-uart_prepare_sysrq_char-to-handle-sys.patch +++ /dev/null @@ -1,104 +0,0 @@ -From: Sebastian Andrzej Siewior -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 -Cc: Manivannan Sadhasivam -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 ---- - 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-nbcon-Provide-functions-for-drivers-to-acquire-conso.patch b/debian/patches-rt/0011-nbcon-Provide-functions-for-drivers-to-acquire-conso.patch new file mode 100644 index 0000000000..06cc991bff --- /dev/null +++ b/debian/patches-rt/0011-nbcon-Provide-functions-for-drivers-to-acquire-conso.patch @@ -0,0 +1,160 @@ +From: John Ogness +Date: Wed, 17 Apr 2024 12:42:46 +0000 +Subject: [PATCH 11/46] nbcon: Provide functions for drivers to acquire console + for non-printing +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Provide functions nbcon_driver_try_acquire() and +nbcon_driver_release() to allow drivers to acquire the nbcon +console and mark it unsafe for handover/takeover. + +These functions are to be used by nbcon drivers when performing +non-printing activities that should be synchronized with their +atomic_write() callback. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/console.h | 2 + + include/linux/printk.h | 14 ++++++++++++ + kernel/printk/nbcon.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 70 insertions(+), 1 deletion(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -322,6 +322,7 @@ struct nbcon_write_context { + * + * @nbcon_state: State for nbcon consoles + * @nbcon_seq: Sequence number of the next record for nbcon to print ++ * @nbcon_driver_ctxt: Context available for driver non-printing operations + * @pbufs: Pointer to nbcon private buffer + */ + struct console { +@@ -417,6 +418,7 @@ struct console { + + atomic_t __private nbcon_state; + atomic_long_t __private nbcon_seq; ++ struct nbcon_context __private nbcon_driver_ctxt; + struct printk_buffers *pbufs; + }; + +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -9,6 +9,8 @@ + #include + #include + ++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 bool nbcon_driver_try_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,16 @@ static inline void dump_stack(void) + static inline void printk_trigger_flush(void) + { + } ++ ++static inline bool nbcon_driver_try_acquire(struct console *con) ++{ ++ return false; ++} ++ ++static inline void nbcon_driver_release(struct console *con) ++{ ++} ++ + #endif + + bool this_cpu_in_panic(void); +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -5,7 +5,9 @@ + #include + #include + #include ++#include + #include ++#include + #include "internal.h" + /* + * Printk console printing implementation for consoles which does not depend +@@ -528,6 +530,7 @@ static struct printk_buffers panic_nbcon + * nbcon_context_try_acquire - Try to acquire nbcon console + * @ctxt: The context of the caller + * ++ * Context: Under @ctxt->con->device_lock() or local_irq_save(). + * Return: True if the console was acquired. False otherwise. + * + * If the caller allowed an unsafe hostile takeover, on success the +@@ -535,7 +538,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. + */ +-__maybe_unused + static bool nbcon_context_try_acquire(struct nbcon_context *ctxt) + { + unsigned int cpu = smp_processor_id(); +@@ -989,3 +991,54 @@ void nbcon_free(struct console *con) + + con->pbufs = NULL; + } ++ ++/** ++ * nbcon_driver_try_acquire - Try to acquire nbcon console and enter unsafe ++ * section ++ * @con: The nbcon console to acquire ++ * ++ * Context: Under the locking mechanism implemented in ++ * @con->device_lock() including disabling migration. ++ * ++ * 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 in order to synchronize against their ++ * atomic_write() callback. ++ * ++ * This function acquires the nbcon console using priority NBCON_PRIO_NORMAL ++ * and marks it unsafe for handover/takeover. ++ */ ++bool nbcon_driver_try_acquire(struct console *con) ++{ ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(con, nbcon_driver_ctxt); ++ ++ cant_migrate(); ++ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ctxt->console = con; ++ ctxt->prio = NBCON_PRIO_NORMAL; ++ ++ if (!nbcon_context_try_acquire(ctxt)) ++ return false; ++ ++ if (!nbcon_context_enter_unsafe(ctxt)) ++ return false; ++ ++ return true; ++} ++EXPORT_SYMBOL_GPL(nbcon_driver_try_acquire); ++ ++/** ++ * nbcon_driver_release - Exit unsafe section and release the nbcon console ++ * @con: The nbcon console acquired in nbcon_driver_try_acquire() ++ */ ++void nbcon_driver_release(struct console *con) ++{ ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(con, nbcon_driver_ctxt); ++ ++ if (nbcon_context_exit_unsafe(ctxt)) ++ nbcon_context_release(ctxt); ++} ++EXPORT_SYMBOL_GPL(nbcon_driver_release); 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 deleted file mode 100644 index d6239d704b..0000000000 --- a/debian/patches-rt/0011-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch +++ /dev/null @@ -1,72 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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-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 deleted file mode 100644 index 35d33ed2f9..0000000000 --- a/debian/patches-rt/0011-serial-rda-Use-uart_prepare_sysrq_char-to-handle-sys.patch +++ /dev/null @@ -1,91 +0,0 @@ -From: Sebastian Andrzej Siewior -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 -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 ---- - 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 deleted file mode 100644 index 71afdf6e29..0000000000 --- a/debian/patches-rt/0012-printk-nbcon-Use-driver-synchronization-while-regist.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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-core-Implement-processing-in-port-lock-wrappe.patch b/debian/patches-rt/0012-serial-core-Implement-processing-in-port-lock-wrappe.patch new file mode 100644 index 0000000000..1d136131f8 --- /dev/null +++ b/debian/patches-rt/0012-serial-core-Implement-processing-in-port-lock-wrappe.patch @@ -0,0 +1,180 @@ +From: John Ogness +Date: Wed, 17 Apr 2024 14:41:16 +0000 +Subject: [PATCH 12/46] serial: core: Implement processing in port->lock + wrapper +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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. + +Note that __uart_port_using_nbcon() relies on the port->lock +being held while a console is added and removed from the +console list (i.e. all uart nbcon drivers *must* take the +port->lock in their device_lock() callbacks). + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/serial_core.h | 82 ++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 80 insertions(+), 2 deletions(-) + +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -12,6 +12,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -626,6 +628,60 @@ static inline void uart_port_set_cons(st + up->cons = con; + __uart_port_unlock_irqrestore(up, flags); + } ++ ++/* Only for internal port lock wrapper usage. */ ++static inline bool __uart_port_using_nbcon(struct uart_port *up) ++{ ++ lockdep_assert_held_once(&up->lock); ++ ++ if (likely(!uart_console(up))) ++ return false; ++ ++ /* ++ * @up->cons is only modified under the port lock. Therefore it is ++ * certain that it cannot disappear here. ++ * ++ * @up->cons->node is added/removed from the console list under the ++ * port lock. Therefore it is certain that the registration status ++ * cannot change here, thus @up->cons->flags can be read directly. ++ */ ++ if (hlist_unhashed_lockless(&up->cons->node) || ++ !(up->cons->flags & CON_NBCON) || ++ !up->cons->write_atomic) { ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Only for internal port lock wrapper usage. */ ++static inline bool __uart_port_nbcon_try_acquire(struct uart_port *up) ++{ ++ if (!__uart_port_using_nbcon(up)) ++ return true; ++ ++ return nbcon_driver_try_acquire(up->cons); ++} ++ ++/* Only for internal port lock wrapper usage. */ ++static inline void __uart_port_nbcon_acquire(struct uart_port *up) ++{ ++ if (!__uart_port_using_nbcon(up)) ++ return; ++ ++ while (!nbcon_driver_try_acquire(up->cons)) ++ cpu_relax(); ++} ++ ++/* Only for internal port lock wrapper usage. */ ++static inline void __uart_port_nbcon_release(struct uart_port *up) ++{ ++ if (!__uart_port_using_nbcon(up)) ++ return; ++ ++ nbcon_driver_release(up->cons); ++} ++ + /** + * uart_port_lock - Lock the UART port + * @up: Pointer to UART port structure +@@ -633,6 +689,7 @@ static inline void uart_port_set_cons(st + static inline void uart_port_lock(struct uart_port *up) + { + spin_lock(&up->lock); ++ __uart_port_nbcon_acquire(up); + } + + /** +@@ -642,6 +699,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); + } + + /** +@@ -652,6 +710,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); + } + + /** +@@ -662,7 +721,15 @@ 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; ++ ++ if (!__uart_port_nbcon_try_acquire(up)) { ++ spin_unlock(&up->lock); ++ return false; ++ } ++ ++ return true; + } + + /** +@@ -674,7 +741,15 @@ 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; ++ ++ if (!__uart_port_nbcon_try_acquire(up)) { ++ spin_unlock_irqrestore(&up->lock, *flags); ++ return false; ++ } ++ ++ return true; + } + + /** +@@ -683,6 +758,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); + } + +@@ -692,6 +768,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); + } + +@@ -702,6 +779,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); + } + 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 deleted file mode 100644 index 5b82468e40..0000000000 --- a/debian/patches-rt/0012-serial-sifive-Use-uart_prepare_sysrq_char-to-handle-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: Sebastian Andrzej Siewior -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 -Cc: Paul Walmsley -Cc: linux-riscv@lists.infradead.org -Link: https://lore.kernel.org/r/20240301215246.891055-13-bigeasy@linutronix.de -Signed-off-by: Sebastian Andrzej Siewior ---- - 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-printk-nbcon-Do-not-rely-on-proxy-headers.patch b/debian/patches-rt/0013-printk-nbcon-Do-not-rely-on-proxy-headers.patch new file mode 100644 index 0000000000..4524b5dcf4 --- /dev/null +++ b/debian/patches-rt/0013-printk-nbcon-Do-not-rely-on-proxy-headers.patch @@ -0,0 +1,88 @@ +From: John Ogness +Date: Mon, 19 Feb 2024 17:35:49 +0000 +Subject: [PATCH 13/46] printk: nbcon: Do not rely on proxy headers +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Signed-off-by: John Ogness +Reviewed-by: Andy Shevchenko +Acked-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 8 ++++++-- + kernel/printk/nbcon.c | 13 ++++++++++++- + kernel/printk/printk_ringbuffer.h | 2 ++ + 3 files changed, 20 insertions(+), 3 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -2,11 +2,12 @@ + /* + * internal.h - printk internal definitions + */ +-#include + #include +-#include "printk_ringbuffer.h" ++#include ++#include + + #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,13 +2,24 @@ + // Copyright (C) 2022 Linutronix GmbH, John Ogness + // Copyright (C) 2022 Intel, Thomas Gleixner + +-#include ++#include ++#include + #include + #include ++#include + #include ++#include ++#include ++#include ++#include ++#include + #include ++#include ++#include + #include ++#include + #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 + #include ++#include ++#include + + /* + * Meta information about each stored message. 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 deleted file mode 100644 index c441b46257..0000000000 --- a/debian/patches-rt/0013-serial-core-Provide-low-level-functions-to-lock-port.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 deleted file mode 100644 index 436fb4e55c..0000000000 --- a/debian/patches-rt/0013-serial-pch-Invoke-handle_rx_to-directly.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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-printk-Make-console_is_usable-available-to-nbcon.patch b/debian/patches-rt/0014-printk-Make-console_is_usable-available-to-nbcon.patch new file mode 100644 index 0000000000..554a571639 --- /dev/null +++ b/debian/patches-rt/0014-printk-Make-console_is_usable-available-to-nbcon.patch @@ -0,0 +1,103 @@ +From: John Ogness +Date: Tue, 12 Sep 2023 13:25:41 +0000 +Subject: [PATCH 14/46] printk: Make console_is_usable() available to nbcon +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Move console_is_usable() as-is into internal.h so that it can +be used by nbcon printing functions as well. + +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 32 ++++++++++++++++++++++++++++++++ + kernel/printk/printk.c | 30 ------------------------------ + 2 files changed, 32 insertions(+), 30 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -85,6 +85,36 @@ bool nbcon_alloc(struct console *con); + void nbcon_init(struct console *con, u64 init_seq); + void nbcon_free(struct console *con); + ++/* ++ * Check if the given console is currently capable and allowed to print ++ * records. ++ * ++ * Requires the console_srcu_read_lock. ++ */ ++static inline bool console_is_usable(struct console *con) ++{ ++ short flags = console_srcu_read_flags(con); ++ ++ if (!(flags & CON_ENABLED)) ++ return false; ++ ++ if ((flags & CON_SUSPENDED)) ++ return false; ++ ++ if (!con->write) ++ return false; ++ ++ /* ++ * Console drivers may assume that per-cpu resources have been ++ * allocated. So unless they're explicitly marked as being able to ++ * cope (CON_ANYTIME) don't call them until this CPU is officially up. ++ */ ++ if (!cpu_online(raw_smp_processor_id()) && !(flags & CON_ANYTIME)) ++ return false; ++ ++ return true; ++} ++ + #else + + #define PRINTK_PREFIX_MAX 0 +@@ -106,6 +136,8 @@ static inline bool nbcon_alloc(struct co + static inline void nbcon_init(struct console *con, u64 init_seq) { } + static inline void nbcon_free(struct console *con) { } + ++static inline bool console_is_usable(struct console *con) { return false; } ++ + #endif /* CONFIG_PRINTK */ + + extern struct printk_buffers printk_shared_pbufs; +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2697,36 +2697,6 @@ int is_console_locked(void) + } + EXPORT_SYMBOL(is_console_locked); + +-/* +- * Check if the given console is currently capable and allowed to print +- * records. +- * +- * Requires the console_srcu_read_lock. +- */ +-static inline bool console_is_usable(struct console *con) +-{ +- short flags = console_srcu_read_flags(con); +- +- if (!(flags & CON_ENABLED)) +- return false; +- +- if ((flags & CON_SUSPENDED)) +- return false; +- +- if (!con->write) +- return false; +- +- /* +- * Console drivers may assume that per-cpu resources have been +- * allocated. So unless they're explicitly marked as being able to +- * cope (CON_ANYTIME) don't call them until this CPU is officially up. +- */ +- if (!cpu_online(raw_smp_processor_id()) && !(flags & CON_ANYTIME)) +- return false; +- +- return true; +-} +- + static void __console_unlock(void) + { + console_locked = 0; 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 deleted file mode 100644 index edf62ea414..0000000000 --- a/debian/patches-rt/0014-printk-nbcon-Implement-processing-in-port-lock-wrapp.patch +++ /dev/null @@ -1,478 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 - #include - -+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 -+#include - #include - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -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 -+#include - #include - #include -+#include - #include -+#include - #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 deleted file mode 100644 index 9ed4ea5abc..0000000000 --- a/debian/patches-rt/0014-serial-pch-Make-push_rx-return-void.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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-Let-console_is_usable-handle-nbcon.patch b/debian/patches-rt/0015-printk-Let-console_is_usable-handle-nbcon.patch new file mode 100644 index 0000000000..0172326b0c --- /dev/null +++ b/debian/patches-rt/0015-printk-Let-console_is_usable-handle-nbcon.patch @@ -0,0 +1,43 @@ +From: John Ogness +Date: Tue, 12 Sep 2023 13:53:21 +0000 +Subject: [PATCH 15/46] printk: Let console_is_usable() handle nbcon +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +The nbcon consoles use a different printing callback. For nbcon +consoles, check for the write_atomic() callback instead of +write(). + +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -87,6 +87,8 @@ void nbcon_free(struct console *con); + + /* + * Check if the given console is currently capable and allowed to print ++ * 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. + * + * Requires the console_srcu_read_lock. +@@ -101,8 +103,13 @@ static inline bool console_is_usable(str + if ((flags & CON_SUSPENDED)) + return false; + +- if (!con->write) +- return false; ++ if (flags & CON_NBCON) { ++ if (!con->write_atomic) ++ return false; ++ } else { ++ if (!con->write) ++ return false; ++ } + + /* + * Console drivers may assume that per-cpu resources have been 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 deleted file mode 100644 index 3ea3dd3d77..0000000000 --- a/debian/patches-rt/0015-printk-nbcon-Do-not-rely-on-proxy-headers.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: John Ogness -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 -Signed-off-by: John Ogness -Reviewed-by: Andy Shevchenko -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 - #include --#include "printk_ringbuffer.h" -+#include -+#include - - #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 -+#include - #include - #include - #include -+#include - #include -+#include -+#include -+#include -+#include -+#include - #include -+#include -+#include - #include -+#include - #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 - #include -+#include -+#include - - /* - * 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 deleted file mode 100644 index aad340f32c..0000000000 --- a/debian/patches-rt/0015-serial-pch-Don-t-disable-interrupts-while-acquiring-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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-Add-flags-argument-for-console_is_usable.patch b/debian/patches-rt/0016-printk-Add-flags-argument-for-console_is_usable.patch new file mode 100644 index 0000000000..86ab3528a3 --- /dev/null +++ b/debian/patches-rt/0016-printk-Add-flags-argument-for-console_is_usable.patch @@ -0,0 +1,67 @@ +From: John Ogness +Date: Tue, 12 Sep 2023 13:45:33 +0000 +Subject: [PATCH 16/46] printk: Add @flags argument for console_is_usable() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +The caller of console_is_usable() usually needs @console->flags +for its own checks. Rather than having console_is_usable() read +its own copy, make the caller pass in the @flags. This also +ensures that the caller saw the same @flags value. + +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 8 ++------ + kernel/printk/printk.c | 5 +++-- + 2 files changed, 5 insertions(+), 8 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -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. +- * +- * Requires the console_srcu_read_lock. + */ +-static inline bool console_is_usable(struct console *con) ++static inline bool console_is_usable(struct console *con, short flags) + { +- short flags = console_srcu_read_flags(con); +- + if (!(flags & CON_ENABLED)) + return false; + +@@ -143,7 +139,7 @@ static inline bool nbcon_alloc(struct co + static inline void nbcon_init(struct console *con, u64 init_seq) { } + static inline void nbcon_free(struct console *con) { } + +-static inline bool console_is_usable(struct console *con) { return false; } ++static inline bool console_is_usable(struct console *con, short flags) { return false; } + + #endif /* CONFIG_PRINTK */ + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2942,9 +2942,10 @@ 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); + bool progress; + +- if (!console_is_usable(con)) ++ if (!console_is_usable(con, flags)) + continue; + any_usable = true; + +@@ -3838,7 +3839,7 @@ static bool __pr_flush(struct console *c + * that they make forward progress, so only increment + * @diff for usable consoles. + */ +- if (!console_is_usable(c)) ++ if (!console_is_usable(c, flags)) + continue; + + if (flags & CON_NBCON) { 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 deleted file mode 100644 index 246deca24d..0000000000 --- a/debian/patches-rt/0016-printk-nbcon-Fix-kerneldoc-for-enums.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: John Ogness -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 -Reviewed-by: Randy Dunlap -Reviewed-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 deleted file mode 100644 index 4acdbb831f..0000000000 --- a/debian/patches-rt/0016-serial-pch-Don-t-initialize-uart_port-s-spin_lock.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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/0017-printk-Make-console_is_usable-available-to-nbcon.patch b/debian/patches-rt/0017-printk-Make-console_is_usable-available-to-nbcon.patch deleted file mode 100644 index 8334063ed5..0000000000 --- a/debian/patches-rt/0017-printk-Make-console_is_usable-available-to-nbcon.patch +++ /dev/null @@ -1,103 +0,0 @@ -From: John Ogness -Date: Tue, 12 Sep 2023 13:25:41 +0000 -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. - -Signed-off-by: John Ogness -Reviewed-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/internal.h | 32 ++++++++++++++++++++++++++++++++ - kernel/printk/printk.c | 30 ------------------------------ - 2 files changed, 32 insertions(+), 30 deletions(-) - ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -85,6 +85,36 @@ bool nbcon_alloc(struct console *con); - void nbcon_init(struct console *con); - void nbcon_free(struct console *con); - -+/* -+ * Check if the given console is currently capable and allowed to print -+ * records. -+ * -+ * Requires the console_srcu_read_lock. -+ */ -+static inline bool console_is_usable(struct console *con) -+{ -+ short flags = console_srcu_read_flags(con); -+ -+ if (!(flags & CON_ENABLED)) -+ return false; -+ -+ if ((flags & CON_SUSPENDED)) -+ return false; -+ -+ if (!con->write) -+ return false; -+ -+ /* -+ * Console drivers may assume that per-cpu resources have been -+ * allocated. So unless they're explicitly marked as being able to -+ * cope (CON_ANYTIME) don't call them until this CPU is officially up. -+ */ -+ if (!cpu_online(raw_smp_processor_id()) && !(flags & CON_ANYTIME)) -+ return false; -+ -+ return true; -+} -+ - #else - - #define PRINTK_PREFIX_MAX 0 -@@ -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) { } - -+static inline bool console_is_usable(struct console *con) { return false; } -+ - #endif /* CONFIG_PRINTK */ - - extern struct printk_buffers printk_shared_pbufs; ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -2702,36 +2702,6 @@ int is_console_locked(void) - } - EXPORT_SYMBOL(is_console_locked); - --/* -- * Check if the given console is currently capable and allowed to print -- * records. -- * -- * Requires the console_srcu_read_lock. -- */ --static inline bool console_is_usable(struct console *con) --{ -- short flags = console_srcu_read_flags(con); -- -- if (!(flags & CON_ENABLED)) -- return false; -- -- if ((flags & CON_SUSPENDED)) -- return false; -- -- if (!con->write) -- return false; -- -- /* -- * Console drivers may assume that per-cpu resources have been -- * allocated. So unless they're explicitly marked as being able to -- * cope (CON_ANYTIME) don't call them until this CPU is officially up. -- */ -- if (!cpu_online(raw_smp_processor_id()) && !(flags & CON_ANYTIME)) -- return false; -- -- return true; --} -- - static void __console_unlock(void) - { - console_locked = 0; diff --git a/debian/patches-rt/0017-printk-nbcon-Add-helper-to-assign-priority-based-on-.patch b/debian/patches-rt/0017-printk-nbcon-Add-helper-to-assign-priority-based-on-.patch new file mode 100644 index 0000000000..0fda8a8c5e --- /dev/null +++ b/debian/patches-rt/0017-printk-nbcon-Add-helper-to-assign-priority-based-on-.patch @@ -0,0 +1,67 @@ +From: John Ogness +Date: Thu, 14 Dec 2023 14:38:42 +0000 +Subject: [PATCH 17/46] printk: nbcon: Add helper to assign priority based on + CPU state +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Add a helper function to 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_try_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 +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 2 ++ + kernel/printk/nbcon.c | 16 ++++++++++++++++ + 2 files changed, 18 insertions(+) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -84,6 +84,7 @@ void nbcon_seq_force(struct console *con + bool nbcon_alloc(struct console *con); + void nbcon_init(struct console *con, u64 init_seq); + void nbcon_free(struct console *con); ++enum nbcon_prio nbcon_get_default_prio(void); + + /* + * Check if the given console is currently capable and allowed to print +@@ -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, u64 init_seq) { } + static inline void nbcon_free(struct console *con) { } ++static inline enum nbcon_prio nbcon_get_default_prio(void) { return NBCON_PRIO_NONE; } + + static inline bool console_is_usable(struct console *con, short flags) { return false; } + +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -938,6 +938,22 @@ static bool nbcon_emit_next_record(struc + } + + /** ++ * 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_alloc - Allocate buffers needed by the nbcon console + * @con: Console to allocate buffers for + * 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 deleted file mode 100644 index 9ca34a1034..0000000000 --- a/debian/patches-rt/0017-serial-pch-Remove-eg20t_port-lock.patch +++ /dev/null @@ -1,128 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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/0018-printk-Let-console_is_usable-handle-nbcon.patch b/debian/patches-rt/0018-printk-Let-console_is_usable-handle-nbcon.patch deleted file mode 100644 index 6d995e7020..0000000000 --- a/debian/patches-rt/0018-printk-Let-console_is_usable-handle-nbcon.patch +++ /dev/null @@ -1,43 +0,0 @@ -From: John Ogness -Date: Tue, 12 Sep 2023 13:53:21 +0000 -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 -write(). - -Signed-off-by: John Ogness -Reviewed-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/internal.h | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -87,6 +87,8 @@ void nbcon_free(struct console *con); - - /* - * Check if the given console is currently capable and allowed to print -+ * 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. - * - * Requires the console_srcu_read_lock. -@@ -101,8 +103,13 @@ static inline bool console_is_usable(str - if ((flags & CON_SUSPENDED)) - return false; - -- if (!con->write) -- return false; -+ if (flags & CON_NBCON) { -+ if (!con->write_atomic) -+ return false; -+ } else { -+ if (!con->write) -+ return false; -+ } - - /* - * Console drivers may assume that per-cpu resources have been diff --git a/debian/patches-rt/0018-printk-nbcon-Provide-function-to-flush-using-write_a.patch b/debian/patches-rt/0018-printk-nbcon-Provide-function-to-flush-using-write_a.patch new file mode 100644 index 0000000000..b42d8623bb --- /dev/null +++ b/debian/patches-rt/0018-printk-nbcon-Provide-function-to-flush-using-write_a.patch @@ -0,0 +1,260 @@ +From: Thomas Gleixner +Date: Tue, 12 Sep 2023 12:00:08 +0000 +Subject: [PATCH 18/46] printk: nbcon: Provide function to flush using + write_atomic() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Provide nbcon_atomic_flush_pending() to perform flushing of all +registered nbcon consoles using their write_atomic() callback. + +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. If new records are added while +flushing, it is expected that the dedicated printer threads +will print those records. If the printer thread is not +available (which is always the case at this point in the +rework), nbcon_atomic_flush_pending() _will_ flush all records +in the ringbuffer. + +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. + +Also use it in nbcon_driver_release() to flush records added +while the driver had the console locked to perform non-printing +operations. + +Co-developed-by: John Ogness +Signed-off-by: John Ogness +Signed-off-by: Thomas Gleixner (Intel) +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 2 + kernel/printk/nbcon.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++- + kernel/printk/printk.c | 2 + 3 files changed, 163 insertions(+), 3 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -85,6 +85,7 @@ bool nbcon_alloc(struct console *con); + void nbcon_init(struct console *con, u64 init_seq); + void nbcon_free(struct console *con); + enum nbcon_prio nbcon_get_default_prio(void); ++void nbcon_atomic_flush_pending(void); + + /* + * Check if the given console is currently capable and allowed to print +@@ -140,6 +141,7 @@ static inline bool nbcon_alloc(struct co + static inline void nbcon_init(struct console *con, u64 init_seq) { } + 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 console_is_usable(struct console *con, short flags) { return false; } + +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -850,7 +850,6 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); + * When true is returned, @wctxt->ctxt.backlog indicates whether there are + * still records pending in the ringbuffer, + */ +-__maybe_unused + static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt) + { + struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); +@@ -953,6 +952,148 @@ enum nbcon_prio nbcon_get_default_prio(v + return NBCON_PRIO_NORMAL; + } + ++/* ++ * __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: 0 if @con was flushed up to @stop_seq Otherwise, error code on ++ * failure. ++ * ++ * Errors: ++ * ++ * -EPERM: Unable to acquire console ownership. ++ * ++ * -EAGAIN: Another context took over ownership while printing. ++ * ++ * -ENOENT: A record before @stop_seq is not available. ++ * ++ * If flushing up to @stop_seq was not successful, it only makes sense for the ++ * caller to try again when -EAGAIN was returned. When -EPERM is returned, ++ * this context is not allowed to acquire the console. When -ENOENT is ++ * returned, it cannot be expected that the unfinalized record will become ++ * available. ++ */ ++static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) ++{ ++ struct nbcon_write_context wctxt = { }; ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); ++ int err = 0; ++ ++ ctxt->console = con; ++ ctxt->spinwait_max_us = 2000; ++ ctxt->prio = nbcon_get_default_prio(); ++ ++ if (!nbcon_context_try_acquire(ctxt)) ++ return -EPERM; ++ ++ 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 -EAGAIN; ++ ++ if (!ctxt->backlog) { ++ if (nbcon_seq_read(con) < stop_seq) ++ err = -ENOENT; ++ break; ++ } ++ } ++ ++ nbcon_context_release(ctxt); ++ return err; ++} ++ ++/** ++ * 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 ++ * ++ * This will stop flushing before @stop_seq if another context has ownership. ++ * That context is then responsible for the flushing. Likewise, if new records ++ * are added while this context was flushing and there is no other context ++ * to handle the printing, this context must also flush those records. ++ */ ++static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) ++{ ++ unsigned long flags; ++ int err; ++ ++again: ++ /* ++ * 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 to acquire console ownership. ++ */ ++ local_irq_save(flags); ++ ++ err = __nbcon_atomic_flush_pending_con(con, stop_seq); ++ ++ local_irq_restore(flags); ++ ++ /* ++ * If flushing was successful but more records are available, this ++ * context must flush those remaining records because there is no ++ * other context that will do it. ++ */ ++ if (!err && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { ++ stop_seq = prb_next_reserve_seq(prb); ++ goto again; ++ } ++ ++ /* ++ * If there was a new owner, that context is responsible for ++ * completing the flush. ++ */ ++} ++ ++/** ++ * __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_pending(u64 stop_seq) ++{ ++ struct console *con; ++ int cookie; ++ ++ cookie = console_srcu_read_lock(); ++ for_each_console_srcu(con) { ++ short flags = console_srcu_read_flags(con); ++ ++ if (!(flags & CON_NBCON)) ++ continue; ++ ++ if (!console_is_usable(con, flags)) ++ continue; ++ ++ if (nbcon_seq_read(con) >= stop_seq) ++ continue; ++ ++ nbcon_atomic_flush_pending_con(con, stop_seq); ++ } ++ console_srcu_read_unlock(cookie); ++} ++ ++/** ++ * 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_pending(void) ++{ ++ __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb)); ++} ++ + /** + * nbcon_alloc - Allocate buffers needed by the nbcon console + * @con: Console to allocate buffers for +@@ -1064,8 +1205,23 @@ EXPORT_SYMBOL_GPL(nbcon_driver_try_acqui + void nbcon_driver_release(struct console *con) + { + struct nbcon_context *ctxt = &ACCESS_PRIVATE(con, nbcon_driver_ctxt); ++ int cookie; + +- if (nbcon_context_exit_unsafe(ctxt)) +- nbcon_context_release(ctxt); ++ if (!nbcon_context_exit_unsafe(ctxt)) ++ return; ++ ++ nbcon_context_release(ctxt); ++ ++ /* ++ * This context must flush any new records added while the console ++ * was locked. The console_srcu_read_lock must be taken to ensure ++ * the console is usable throughout flushing. ++ */ ++ cookie = console_srcu_read_lock(); ++ if (console_is_usable(con, console_srcu_read_flags(con)) && ++ prb_read_valid(prb, nbcon_seq_read(con), NULL)) { ++ __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb)); ++ } ++ console_srcu_read_unlock(cookie); + } + EXPORT_SYMBOL_GPL(nbcon_driver_release); +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -3172,6 +3172,8 @@ void console_flush_on_panic(enum con_flu + console_srcu_read_unlock(cookie); + } + ++ nbcon_atomic_flush_pending(); ++ + console_flush_all(false, &next_seq, &handover); + } + 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 deleted file mode 100644 index 55e6615c9e..0000000000 --- a/debian/patches-rt/0018-serial-pch-Use-uart_prepare_sysrq_char.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: Sebastian Andrzej Siewior -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 ---- - 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/0019-printk-Add-flags-argument-for-console_is_usable.patch b/debian/patches-rt/0019-printk-Add-flags-argument-for-console_is_usable.patch deleted file mode 100644 index ed902938c0..0000000000 --- a/debian/patches-rt/0019-printk-Add-flags-argument-for-console_is_usable.patch +++ /dev/null @@ -1,67 +0,0 @@ -From: John Ogness -Date: Tue, 12 Sep 2023 13:45:33 +0000 -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 -its own copy, make the caller pass in the @flags. This also -ensures that the caller saw the same @flags value. - -Signed-off-by: John Ogness -Reviewed-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/internal.h | 8 ++------ - kernel/printk/printk.c | 5 +++-- - 2 files changed, 5 insertions(+), 8 deletions(-) - ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -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. -- * -- * Requires the console_srcu_read_lock. - */ --static inline bool console_is_usable(struct console *con) -+static inline bool console_is_usable(struct console *con, short flags) - { -- short flags = console_srcu_read_flags(con); -- - if (!(flags & CON_ENABLED)) - return false; - -@@ -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) { } - --static inline bool console_is_usable(struct console *con) { return false; } -+static inline bool console_is_usable(struct console *con, short flags) { return false; } - - #endif /* CONFIG_PRINTK */ - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -2947,9 +2947,10 @@ 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); - bool progress; - -- if (!console_is_usable(con)) -+ if (!console_is_usable(con, flags)) - continue; - any_usable = true; - -@@ -3819,7 +3820,7 @@ static bool __pr_flush(struct console *c - * that they make forward progress, so only increment - * @diff for usable consoles. - */ -- if (!console_is_usable(c)) -+ if (!console_is_usable(c, flags)) - continue; - - if (flags & CON_NBCON) { diff --git a/debian/patches-rt/0019-printk-Track-registered-boot-consoles.patch b/debian/patches-rt/0019-printk-Track-registered-boot-consoles.patch new file mode 100644 index 0000000000..f01676b13a --- /dev/null +++ b/debian/patches-rt/0019-printk-Track-registered-boot-consoles.patch @@ -0,0 +1,80 @@ +From: John Ogness +Date: Tue, 24 Oct 2023 14:13:14 +0000 +Subject: [PATCH 19/46] printk: Track registered boot consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +they must not be allowed to print simultaneously. + +For legacy consoles this is not an issue because they are +already synchronized with the boot consoles using the console +lock. However nbcon consoles can be triggered separately. + +Add a global flag @have_boot_console to identify if any boot +consoles are registered. This will be used in follow-up commits +to ensure that boot consoles and nbcon consoles cannot print +simultaneously. + +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/printk.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -463,6 +463,14 @@ static int console_msg_format = MSG_FORM + /* syslog_lock protects syslog_* variables and write access to clear_seq. */ + static DEFINE_MUTEX(syslog_lock); + ++/* ++ * 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 ++ * have mapped the same hardware. ++ */ ++static bool have_boot_console; ++ + #ifdef CONFIG_PRINTK + DECLARE_WAIT_QUEUE_HEAD(log_wait); + /* All 3 protected by @syslog_lock. */ +@@ -3526,6 +3534,9 @@ void register_console(struct console *ne + newcon->seq = init_seq; + } + ++ if (newcon->flags & CON_BOOT) ++ have_boot_console = true; ++ + /* + * If another context is actively using the hardware of this new + * console, it will not be aware of the nbcon synchronization. This +@@ -3595,7 +3606,9 @@ EXPORT_SYMBOL(register_console); + /* Must be called under console_list_lock(). */ + static int unregister_console_locked(struct console *console) + { ++ bool found_boot_con = false; + unsigned long flags; ++ struct console *c; + int res; + + lockdep_assert_console_list_lock_held(); +@@ -3653,6 +3666,17 @@ static int unregister_console_locked(str + if (console->exit) + res = console->exit(console); + ++ /* ++ * With this console gone, the global flags tracking registered ++ * console types may have changed. Update them. ++ */ ++ for_each_console(c) { ++ if (c->flags & CON_BOOT) ++ found_boot_con = true; ++ } ++ if (!found_boot_con) ++ have_boot_console = found_boot_con; ++ + return res; + } + diff --git a/debian/patches-rt/0020-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 deleted file mode 100644 index 26c68ed229..0000000000 --- a/debian/patches-rt/0020-printk-nbcon-Provide-function-to-flush-using-write_a.patch +++ /dev/null @@ -1,193 +0,0 @@ -From: Thomas Gleixner -Date: Tue, 12 Sep 2023 12:00:08 +0000 -Subject: [PATCH 20/48] printk: nbcon: Provide function to flush using - write_atomic() -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz - -Provide nbcon_atomic_flush_pending() to perform flushing of all -registered nbcon consoles using their write_atomic() callback. - -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. - -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 -Signed-off-by: John Ogness -Signed-off-by: Thomas Gleixner (Intel) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/internal.h | 2 - kernel/printk/nbcon.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++- - kernel/printk/printk.c | 2 - 3 files changed, 106 insertions(+), 2 deletions(-) - ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -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_pending(void); - - /* - * Check if the given console is currently capable and allowed to print -@@ -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_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 -@@ -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. - */ --__maybe_unused - static bool nbcon_context_try_acquire(struct nbcon_context *ctxt) - { - unsigned int cpu = smp_processor_id(); -@@ -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, - */ --__maybe_unused - static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt) - { - struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); -@@ -938,6 +936,108 @@ static bool nbcon_emit_next_record(struc - } - - /** -+ * __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: True if taken over while printing. Otherwise false. -+ * -+ * 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_flush_pending_con(struct console *con, u64 stop_seq) -+{ -+ 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; -+ -+ 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 false; -+} -+ -+/** -+ * __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_pending(u64 stop_seq) -+{ -+ struct console *con; -+ bool should_retry; -+ int cookie; -+ -+ do { -+ should_retry = false; -+ -+ cookie = console_srcu_read_lock(); -+ for_each_console_srcu(con) { -+ short flags = console_srcu_read_flags(con); -+ unsigned long irq_flags; -+ -+ if (!(flags & CON_NBCON)) -+ continue; -+ -+ if (!console_is_usable(con, flags)) -+ continue; -+ -+ if (nbcon_seq_read(con) >= stop_seq) -+ continue; -+ -+ /* -+ * 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 -+ * to acquire console ownership. -+ */ -+ local_irq_save(irq_flags); -+ -+ should_retry |= __nbcon_atomic_flush_pending_con(con, stop_seq); -+ -+ local_irq_restore(irq_flags); -+ } -+ console_srcu_read_unlock(cookie); -+ } while (should_retry); -+} -+ -+/** -+ * 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_pending(void) -+{ -+ __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb)); -+} -+ -+/** - * nbcon_alloc - Allocate buffers needed by the nbcon console - * @con: Console to allocate buffers for - * ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -3177,6 +3177,8 @@ void console_flush_on_panic(enum con_flu - console_srcu_read_unlock(cookie); - } - -+ nbcon_atomic_flush_pending(); -+ - console_flush_all(false, &next_seq, &handover); - } - diff --git a/debian/patches-rt/0020-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch b/debian/patches-rt/0020-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch new file mode 100644 index 0000000000..3507ff2aa2 --- /dev/null +++ b/debian/patches-rt/0020-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch @@ -0,0 +1,209 @@ +From: John Ogness +Date: Tue, 19 Sep 2023 14:33:27 +0000 +Subject: [PATCH 20/46] printk: nbcon: Use nbcon consoles in + console_flush_all() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +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_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 +record to print, this also must be appropriately handled in +console_flush_all(). + +Note that the legacy printing logic uses @handover to detect +handovers for printing all consoles. For nbcon consoles, +handovers/takeovers occur on a per-console basis and thus do +not cause the console_flush_all() loop to abort. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 6 +++ + kernel/printk/nbcon.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++ + kernel/printk/printk.c | 17 ++++++--- + 3 files changed, 105 insertions(+), 5 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -78,6 +78,8 @@ void defer_console_output(void); + + u16 printk_parse_prefix(const char *text, int *level, + enum printk_info_flags *flags); ++void console_lock_spinning_enable(void); ++int console_lock_spinning_disable_and_check(int cookie); + + u64 nbcon_seq_read(struct console *con); + void nbcon_seq_force(struct console *con, u64 seq); +@@ -86,6 +88,8 @@ void nbcon_init(struct console *con, u64 + 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); + + /* + * Check if the given console is currently capable and allowed to print +@@ -142,6 +146,8 @@ static inline void nbcon_init(struct 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; } + + static inline bool console_is_usable(struct console *con, short flags) { return false; } + +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -953,6 +953,93 @@ enum nbcon_prio nbcon_get_default_prio(v + } + + /* ++ * 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: True, when a record has been printed and there are still ++ * pending records. The caller might want to continue flushing. ++ * ++ * False, when there is no pending record, or when the console ++ * context cannot be acquired, or the ownership has been lost. ++ * The caller should give up. Either the job is done, cannot be ++ * done, or will be handled by the owning context. ++ * ++ * 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 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. ++ * ++ * The higher priority printing context takes over responsibility ++ * to print the pending records. ++ */ ++ if (!nbcon_emit_next_record(wctxt)) ++ return false; ++ ++ 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 ++ * both the console_lock and the SRCU read lock. Otherwise it ++ * is set to false. ++ * @cookie: The cookie from the SRCU read lock. ++ * ++ * Context: Any context except NMI. ++ * Return: True, when a record has been printed and there are still ++ * pending records. The caller might want to continue flushing. ++ * ++ * False, when there is no pending record, or when the console ++ * context cannot be acquired, or the ownership has been lost. ++ * The caller should give up. Either the job is done, cannot be ++ * done, or will be handled by the owning context. ++ * ++ * This function is meant to be called by console_flush_all() to print records ++ * on nbcon consoles from legacy context (printing via console unlocking). ++ * Essentially it is the nbcon version of console_emit_next_record(). ++ */ ++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 flags; ++ bool progress; ++ ++ /* Use the same procedure as console_emit_next_record(). */ ++ printk_safe_enter_irqsave(flags); ++ console_lock_spinning_enable(); ++ stop_critical_timings(); ++ ++ 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); ++ ++ return progress; ++} ++ ++/** + * __nbcon_atomic_flush_pending_con - Flush specified nbcon console using its + * write_atomic() callback + * @con: The nbcon console to flush +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -1860,7 +1860,7 @@ static bool console_waiter; + * there may be a waiter spinning (like a spinlock). Also it must be + * ready to hand over the lock at the end of the section. + */ +-static void console_lock_spinning_enable(void) ++void console_lock_spinning_enable(void) + { + /* + * Do not use spinning in panic(). The panic CPU wants to keep the lock. +@@ -1899,7 +1899,7 @@ static void console_lock_spinning_enable + * + * Return: 1 if the lock rights were passed, 0 otherwise. + */ +-static int console_lock_spinning_disable_and_check(int cookie) ++int console_lock_spinning_disable_and_check(int cookie) + { + int waiter; + +@@ -2951,13 +2951,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); ++ u64 printk_seq; + bool progress; + + if (!console_is_usable(con, flags)) + continue; + any_usable = true; + +- progress = console_emit_next_record(con, handover, cookie); ++ if (flags & CON_NBCON) { ++ 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 +@@ -2967,8 +2974,8 @@ static bool console_flush_all(bool do_co + return false; + + /* Track the next of the highest seq flushed. */ +- if (con->seq > *next_seq) +- *next_seq = con->seq; ++ if (printk_seq > *next_seq) ++ *next_seq = printk_seq; + + if (!progress) + continue; diff --git a/debian/patches-rt/0021-printk-Track-registered-boot-consoles.patch b/debian/patches-rt/0021-printk-Track-registered-boot-consoles.patch deleted file mode 100644 index 64ee0c4dbb..0000000000 --- a/debian/patches-rt/0021-printk-Track-registered-boot-consoles.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: John Ogness -Date: Tue, 24 Oct 2023 14:13:14 +0000 -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 -they must not be allowed to print simultaneously. - -For legacy consoles this is not an issue because they are -already synchronized with the boot consoles using the console -lock. However nbcon consoles can be triggered separately. - -Add a global flag @have_boot_console to identify if any boot -consoles are registered. This will be used in follow-up commits -to ensure that boot consoles and nbcon consoles cannot print -simultaneously. - -Signed-off-by: John Ogness -Reviewed-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/printk.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -463,6 +463,14 @@ static int console_msg_format = MSG_FORM - /* syslog_lock protects syslog_* variables and write access to clear_seq. */ - static DEFINE_MUTEX(syslog_lock); - -+/* -+ * 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 -+ * have mapped the same hardware. -+ */ -+static bool have_boot_console; -+ - #ifdef CONFIG_PRINTK - DECLARE_WAIT_QUEUE_HEAD(log_wait); - /* All 3 protected by @syslog_lock. */ -@@ -3518,6 +3526,9 @@ void register_console(struct console *ne - newcon->seq = 0; - } - -+ if (newcon->flags & CON_BOOT) -+ have_boot_console = true; -+ - /* - * 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) - { -+ bool found_boot_con = false; -+ struct console *c; - int res; - - lockdep_assert_console_list_lock_held(); -@@ -3634,6 +3647,17 @@ static int unregister_console_locked(str - if (console->exit) - res = console->exit(console); - -+ /* -+ * With this console gone, the global flags tracking registered -+ * console types may have changed. Update them. -+ */ -+ for_each_console(c) { -+ if (c->flags & CON_BOOT) -+ found_boot_con = true; -+ } -+ if (!found_boot_con) -+ have_boot_console = found_boot_con; -+ - return res; - } - diff --git a/debian/patches-rt/0021-printk-nbcon-Add-unsafe-flushing-on-panic.patch b/debian/patches-rt/0021-printk-nbcon-Add-unsafe-flushing-on-panic.patch new file mode 100644 index 0000000000..7b79f9d743 --- /dev/null +++ b/debian/patches-rt/0021-printk-nbcon-Add-unsafe-flushing-on-panic.patch @@ -0,0 +1,159 @@ +From: John Ogness +Date: Fri, 20 Oct 2023 10:03:42 +0000 +Subject: [PATCH 21/46] printk: nbcon: Add unsafe flushing on panic +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/printk.h | 5 +++++ + kernel/panic.c | 1 + + kernel/printk/nbcon.c | 32 +++++++++++++++++++++++++------- + 3 files changed, 31 insertions(+), 7 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 bool nbcon_driver_try_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) +@@ -286,6 +287,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 +@@ -457,6 +457,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 +@@ -1044,6 +1044,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: 0 if @con was flushed up to @stop_seq Otherwise, error code on + * failure. +@@ -1062,7 +1063,8 @@ bool nbcon_legacy_emit_next_record(struc + * returned, it cannot be expected that the unfinalized record will become + * available. + */ +-static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) ++static int __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); +@@ -1071,6 +1073,7 @@ static int __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 -EPERM; +@@ -1100,13 +1103,15 @@ static int __nbcon_atomic_flush_pending_ + * 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 + * + * This will stop flushing before @stop_seq if another context has ownership. + * That context is then responsible for the flushing. Likewise, if new records + * are added while this context was flushing and there is no other context + * to handle the printing, this context must also flush those records. + */ +-static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) ++static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq, ++ bool allow_unsafe_takeover) + { + unsigned long flags; + int err; +@@ -1120,7 +1125,7 @@ static void nbcon_atomic_flush_pending_c + */ + local_irq_save(flags); + +- err = __nbcon_atomic_flush_pending_con(con, stop_seq); ++ err = __nbcon_atomic_flush_pending_con(con, stop_seq, allow_unsafe_takeover); + + local_irq_restore(flags); + +@@ -1144,8 +1149,9 @@ static void nbcon_atomic_flush_pending_c + * __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; + int cookie; +@@ -1163,7 +1169,7 @@ static void __nbcon_atomic_flush_pending + if (nbcon_seq_read(con) >= stop_seq) + continue; + +- nbcon_atomic_flush_pending_con(con, stop_seq); ++ nbcon_atomic_flush_pending_con(con, stop_seq, allow_unsafe_takeover); + } + console_srcu_read_unlock(cookie); + } +@@ -1178,7 +1184,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); + } + + /** +@@ -1307,7 +1325,7 @@ void nbcon_driver_release(struct console + cookie = console_srcu_read_lock(); + if (console_is_usable(con, console_srcu_read_flags(con)) && + prb_read_valid(prb, nbcon_seq_read(con), NULL)) { +- __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb)); ++ __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb), false); + } + console_srcu_read_unlock(cookie); + } diff --git a/debian/patches-rt/0022-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch b/debian/patches-rt/0022-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch new file mode 100644 index 0000000000..1cfd27dd5d --- /dev/null +++ b/debian/patches-rt/0022-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch @@ -0,0 +1,207 @@ +From: John Ogness +Date: Tue, 26 Sep 2023 12:44:07 +0000 +Subject: [PATCH 22/46] printk: Avoid console_lock dance if no legacy or boot + consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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. + +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 +and no legacy consoles. + +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/printk.c | 78 +++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 63 insertions(+), 15 deletions(-) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -464,6 +464,13 @@ static int console_msg_format = MSG_FORM + static DEFINE_MUTEX(syslog_lock); + + /* ++ * Specifies if a legacy console is registered. If legacy consoles are ++ * present, it is necessary to perform the console lock/unlock dance ++ * whenever console flushing should occur. ++ */ ++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 +@@ -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. */ +@@ -2339,7 +2354,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(). */ +- if (!in_sched) { ++ if (!in_sched && printing_via_unlock) { + /* + * The caller may be holding system-critical or + * timing-sensitive locks. Disable preemption during +@@ -2648,7 +2663,7 @@ void resume_console(void) + */ + static int console_cpu_notify(unsigned int cpu) + { +- if (!cpuhp_tasks_frozen) { ++ if (!cpuhp_tasks_frozen && printing_via_unlock) { + /* If trylock fails, someone else is doing the printing */ + if (console_trylock()) + console_unlock(); +@@ -3189,7 +3204,8 @@ void console_flush_on_panic(enum con_flu + + nbcon_atomic_flush_pending(); + +- console_flush_all(false, &next_seq, &handover); ++ if (printing_via_unlock) ++ console_flush_all(false, &next_seq, &handover); + } + + /* +@@ -3538,6 +3554,7 @@ void register_console(struct console *ne + if (newcon->flags & CON_NBCON) { + nbcon_init(newcon, init_seq); + } else { ++ have_legacy_console = true; + newcon->seq = init_seq; + } + +@@ -3613,6 +3630,7 @@ EXPORT_SYMBOL(register_console); + /* Must be called under console_list_lock(). */ + static int unregister_console_locked(struct console *console) + { ++ bool found_legacy_con = false; + bool found_boot_con = false; + unsigned long flags; + struct console *c; +@@ -3680,9 +3698,13 @@ static int unregister_console_locked(str + for_each_console(c) { + if (c->flags & CON_BOOT) + found_boot_con = true; ++ if (!(c->flags & CON_NBCON)) ++ found_legacy_con = true; + } + if (!found_boot_con) + have_boot_console = found_boot_con; ++ if (!found_legacy_con) ++ have_legacy_console = found_legacy_con; + + return res; + } +@@ -3843,22 +3865,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. */ +- console_lock(); +- console_unlock(); ++ if (printing_via_unlock) { ++ console_lock(); ++ console_unlock(); ++ } + + for (;;) { + unsigned long begin_jiffies; + unsigned long slept_jiffies; +- +- diff = 0; ++ bool use_console_lock = printing_via_unlock; + + /* +- * 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(); ++ barrier(); ++ ++ diff = 0; ++ ++ if (use_console_lock) { ++ /* ++ * 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. ++ */ ++ console_lock(); ++ } + + cookie = console_srcu_read_lock(); + for_each_console_srcu(c) { +@@ -3878,6 +3912,7 @@ static bool __pr_flush(struct console *c + if (flags & CON_NBCON) { + printk_seq = nbcon_seq_read(c); + } else { ++ WARN_ON_ONCE(!use_console_lock); + printk_seq = c->seq; + } + +@@ -3889,7 +3924,8 @@ static bool __pr_flush(struct console *c + if (diff != last_diff && reset_on_progress) + remaining_jiffies = timeout_jiffies; + +- console_unlock(); ++ if (use_console_lock) ++ console_unlock(); + + /* Note: @diff is 0 if there are no usable consoles. */ + if (diff == 0 || remaining_jiffies == 0) +@@ -3959,6 +3995,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. +@@ -3970,11 +4007,22 @@ static void __wake_up_klogd(int val) + * + * This pairs with devkmsg_read:A and syslog_print:A. + */ +- 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; ++ ++ /* ++ * 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(); + } + diff --git a/debian/patches-rt/0022-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 deleted file mode 100644 index 02c868a001..0000000000 --- a/debian/patches-rt/0022-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch +++ /dev/null @@ -1,200 +0,0 @@ -From: John Ogness -Date: Tue, 19 Sep 2023 14:33:27 +0000 -Subject: [PATCH 22/48] printk: nbcon: Use nbcon consoles in - console_flush_all() -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 legacy printk() -caller context (printing via unlock) by integrating them into -console_flush_all(). The write_atomic() callback is used for -printing. - -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 -record to print, this also must be appropriately handled. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 -@@ -78,6 +78,8 @@ void defer_console_output(void); - - u16 printk_parse_prefix(const char *text, int *level, - enum printk_info_flags *flags); -+void console_lock_spinning_enable(void); -+int console_lock_spinning_disable_and_check(int cookie); - - u64 nbcon_seq_read(struct console *con); - void nbcon_seq_force(struct console *con, u64 seq); -@@ -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_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 -@@ -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_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 -@@ -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 - * -+ * Context: Any context which could not be migrated to another CPU. - * Return: True if the console was acquired. False otherwise. - * - * If the caller allowed an unsafe hostile takeover, on success the -@@ -936,6 +937,82 @@ 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 -+ * -+ * 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 -+ * both the console_lock and the SRCU read lock. Otherwise it -+ * is set to false. -+ * @cookie: The cookie from the SRCU read lock. -+ * -+ * 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 from legacy context (printing via console unlocking). -+ * Essentially it is the nbcon version of console_emit_next_record(). -+ */ -+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 flags; -+ bool progress; -+ -+ *handover = false; -+ -+ /* Use the same procedure as console_emit_next_record(). */ -+ printk_safe_enter_irqsave(flags); -+ console_lock_spinning_enable(); -+ stop_critical_timings(); -+ -+ ctxt->console = con; -+ ctxt->prio = NBCON_PRIO_NORMAL; -+ -+ progress = nbcon_atomic_emit_one(&wctxt); -+ -+ start_critical_timings(); -+ *handover = console_lock_spinning_disable_and_check(cookie); -+ printk_safe_exit_irqrestore(flags); -+ -+ return progress; -+} -+ -+/** - * __nbcon_atomic_flush_pending_con - Flush specified nbcon console using its - * write_atomic() callback - * @con: The nbcon console to flush ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -1871,7 +1871,7 @@ static bool console_waiter; - * there may be a waiter spinning (like a spinlock). Also it must be - * ready to hand over the lock at the end of the section. - */ --static void console_lock_spinning_enable(void) -+void console_lock_spinning_enable(void) - { - /* - * Do not use spinning in panic(). The panic CPU wants to keep the lock. -@@ -1910,7 +1910,7 @@ static void console_lock_spinning_enable - * - * Return: 1 if the lock rights were passed, 0 otherwise. - */ --static int console_lock_spinning_disable_and_check(int cookie) -+int console_lock_spinning_disable_and_check(int cookie) - { - int waiter; - -@@ -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); -+ u64 printk_seq; - bool progress; - - if (!console_is_usable(con, flags)) - continue; - any_usable = true; - -- progress = console_emit_next_record(con, handover, cookie); -+ if (flags & CON_NBCON) { -+ 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 +2979,8 @@ static bool console_flush_all(bool do_co - return false; - - /* Track the next of the highest seq flushed. */ -- if (con->seq > *next_seq) -- *next_seq = con->seq; -+ if (printk_seq > *next_seq) -+ *next_seq = printk_seq; - - if (!progress) - continue; diff --git a/debian/patches-rt/0023-printk-Track-nbcon-consoles.patch b/debian/patches-rt/0023-printk-Track-nbcon-consoles.patch new file mode 100644 index 0000000000..07220890af --- /dev/null +++ b/debian/patches-rt/0023-printk-Track-nbcon-consoles.patch @@ -0,0 +1,66 @@ +From: John Ogness +Date: Mon, 11 Dec 2023 09:36:52 +0000 +Subject: [PATCH 23/46] printk: Track nbcon consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +to preserve legacy behavior when no nbcon consoles are registered. + +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + 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,11 @@ static DEFINE_MUTEX(syslog_lock); + static bool have_legacy_console; + + /* ++ * Specifies if an nbcon console is registered. ++ */ ++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 +@@ -3552,6 +3557,7 @@ void register_console(struct console *ne + init_seq = get_init_console_seq(newcon, bootcon_registered); + + if (newcon->flags & CON_NBCON) { ++ have_nbcon_console = true; + nbcon_init(newcon, init_seq); + } else { + have_legacy_console = true; +@@ -3631,6 +3637,7 @@ EXPORT_SYMBOL(register_console); + static int unregister_console_locked(struct console *console) + { + bool found_legacy_con = false; ++ bool found_nbcon_con = false; + bool found_boot_con = false; + unsigned long flags; + struct console *c; +@@ -3698,13 +3705,18 @@ static int unregister_console_locked(str + for_each_console(c) { + if (c->flags & CON_BOOT) + found_boot_con = true; +- if (!(c->flags & CON_NBCON)) ++ ++ if (c->flags & CON_NBCON) ++ found_nbcon_con = true; ++ else + found_legacy_con = true; + } + if (!found_boot_con) + have_boot_console = found_boot_con; + if (!found_legacy_con) + have_legacy_console = found_legacy_con; ++ if (!found_nbcon_con) ++ have_nbcon_console = found_nbcon_con; + + return res; + } 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 deleted file mode 100644 index ff275e2ab9..0000000000 --- a/debian/patches-rt/0023-printk-nbcon-Assign-priority-based-on-CPU-state.patch +++ /dev/null @@ -1,84 +0,0 @@ -From: John Ogness -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 -Reviewed-by: Petr Mladek -Signed-off-by: Sebastian Andrzej Siewior ---- - 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-Coordinate-direct-printing-in-panic.patch b/debian/patches-rt/0024-printk-Coordinate-direct-printing-in-panic.patch new file mode 100644 index 0000000000..eb17ba5098 --- /dev/null +++ b/debian/patches-rt/0024-printk-Coordinate-direct-printing-in-panic.patch @@ -0,0 +1,164 @@ +From: John Ogness +Date: Wed, 22 Nov 2023 11:56:58 +0000 +Subject: [PATCH 24/46] printk: Coordinate direct printing in panic +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Perform printing by nbcon consoles on the panic CPU from the +printk() caller context in order to get panic messages printed +as soon as possible. + +If legacy and nbcon consoles are registered, the legacy consoles +will no longer perform direct printing on the panic CPU until +after the backtrace has been stored. This will give the safe +nbcon consoles a chance to print the panic messages before +allowing the unsafe legacy consoles to print. + +If no nbcon consoles are registered, there is no change in +behavior (i.e. legacy consoles will always attempt to print +from the printk() caller context). + +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/printk.h | 5 +++ + kernel/panic.c | 2 + + kernel/printk/printk.c | 62 ++++++++++++++++++++++++++++++++++++++++++------- + 3 files changed, 61 insertions(+), 8 deletions(-) + +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -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 bool nbcon_driver_try_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( + { + } + ++static inline void printk_legacy_allow_panic_sync(void) ++{ ++} ++ + static inline bool nbcon_driver_try_acquire(struct console *con) + { + return false; +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -368,6 +368,8 @@ void panic(const char *fmt, ...) + + panic_other_cpus_shutdown(_crash_kexec_post_notifiers); + ++ printk_legacy_allow_panic_sync(); ++ + /* + * 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 +@@ -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; + +@@ -2330,12 +2332,29 @@ int vprintk_store(int facility, int leve + return ret; + } + ++static bool legacy_allow_panic_sync; ++ ++/* ++ * This acts as a one-way switch to allow legacy consoles to print from ++ * 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, + const struct dev_printk_info *dev_info, + const char *fmt, va_list args) + { ++ bool do_trylock_unlock = printing_via_unlock; + int printed_len; +- bool in_sched = false; + + /* Suppress unimportant messages after panic happens */ + if (unlikely(suppress_printk)) +@@ -2351,15 +2370,42 @@ asmlinkage int vprintk_emit(int facility + + if (level == LOGLEVEL_SCHED) { + level = LOGLEVEL_DEFAULT; +- in_sched = true; ++ /* If called from the scheduler, we can not call up(). */ ++ do_trylock_unlock = false; + } + + printk_delay(level); + + printed_len = vprintk_store(facility, level, dev_info, fmt, args); + +- /* If called from the scheduler, we can not call up(). */ +- if (!in_sched && printing_via_unlock) { ++ if (have_nbcon_console && !have_boot_console) { ++ bool is_panic_context = this_cpu_in_panic(); ++ ++ /* ++ * In panic, the legacy consoles are not allowed to print from ++ * the printk calling context unless explicitly allowed. This ++ * gives the safe nbcon consoles a chance to print out all the ++ * panic messages first. This restriction only applies if ++ * there are nbcon consoles registered. ++ */ ++ if (is_panic_context) ++ do_trylock_unlock &= legacy_allow_panic_sync; ++ ++ /* ++ * There are situations where nbcon atomic printing should ++ * happen in the printk() caller context: ++ * ++ * - When this CPU is in panic. ++ * ++ * 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_pending(); ++ } ++ ++ if (do_trylock_unlock) { + /* + * The caller may be holding system-critical or + * timing-sensitive locks. Disable preemption during +@@ -2379,10 +2425,10 @@ asmlinkage int vprintk_emit(int facility + preempt_enable(); + } + +- if (in_sched) +- defer_console_output(); +- else ++ if (do_trylock_unlock) + wake_up_klogd(); ++ else ++ defer_console_output(); + + return printed_len; + } 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 deleted file mode 100644 index a63a8ac515..0000000000 --- a/debian/patches-rt/0024-printk-nbcon-Add-unsafe-flushing-on-panic.patch +++ /dev/null @@ -1,125 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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/0025-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 deleted file mode 100644 index 8156ae1d14..0000000000 --- a/debian/patches-rt/0025-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch +++ /dev/null @@ -1,207 +0,0 @@ -From: John Ogness -Date: Tue, 26 Sep 2023 12:44:07 +0000 -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.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. - -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 -and no legacy consoles. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/printk.c | 79 +++++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 64 insertions(+), 15 deletions(-) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -464,6 +464,13 @@ static int console_msg_format = MSG_FORM - static DEFINE_MUTEX(syslog_lock); - - /* -+ * Specifies if a legacy console is registered. If legacy consoles are -+ * present, it is necessary to perform the console lock/unlock dance -+ * whenever console flushing should occur. -+ */ -+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 -@@ -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(). */ -- if (!in_sched) { -+ if (!in_sched && printing_via_unlock) { - /* - * The caller may be holding system-critical or - * timing-sensitive locks. Disable preemption during -@@ -2653,7 +2668,7 @@ void resume_console(void) - */ - static int console_cpu_notify(unsigned int cpu) - { -- if (!cpuhp_tasks_frozen) { -+ if (!cpuhp_tasks_frozen && printing_via_unlock) { - /* If trylock fails, someone else is doing the printing */ - if (console_trylock()) - console_unlock(); -@@ -3194,7 +3209,8 @@ void console_flush_on_panic(enum con_flu - - nbcon_atomic_flush_pending(); - -- console_flush_all(false, &next_seq, &handover); -+ if (printing_via_unlock) -+ console_flush_all(false, &next_seq, &handover); - } - - /* -@@ -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) -@@ -3605,6 +3623,7 @@ EXPORT_SYMBOL(register_console); - /* Must be called under console_list_lock(). */ - static int unregister_console_locked(struct console *console) - { -+ bool found_legacy_con = false; - bool found_boot_con = false; - struct console *c; - int res; -@@ -3661,9 +3680,13 @@ static int unregister_console_locked(str - for_each_console(c) { - if (c->flags & CON_BOOT) - found_boot_con = true; -+ if (!(c->flags & CON_NBCON)) -+ found_legacy_con = true; - } - if (!found_boot_con) - have_boot_console = found_boot_con; -+ if (!found_legacy_con) -+ have_legacy_console = found_legacy_con; - - return res; - } -@@ -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. */ -- console_lock(); -- console_unlock(); -+ if (printing_via_unlock) { -+ console_lock(); -+ console_unlock(); -+ } - - for (;;) { - unsigned long begin_jiffies; - unsigned long slept_jiffies; -- -- diff = 0; -+ bool use_console_lock = printing_via_unlock; - - /* -- * 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(); -+ barrier(); -+ -+ diff = 0; -+ -+ if (use_console_lock) { -+ /* -+ * 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. -+ */ -+ console_lock(); -+ } - - cookie = console_srcu_read_lock(); - for_each_console_srcu(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(!use_console_lock); - printk_seq = c->seq; - } - -@@ -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 (use_console_lock) -+ console_unlock(); - - /* Note: @diff is 0 if there are no usable consoles. */ - if (diff == 0 || remaining_jiffies == 0) -@@ -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. - */ -- 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; -+ -+ /* -+ * 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(); - } - diff --git a/debian/patches-rt/0025-printk-nbcon-Implement-emergency-sections.patch b/debian/patches-rt/0025-printk-nbcon-Implement-emergency-sections.patch new file mode 100644 index 0000000000..44327c280a --- /dev/null +++ b/debian/patches-rt/0025-printk-nbcon-Implement-emergency-sections.patch @@ -0,0 +1,283 @@ +From: Thomas Gleixner +Date: Mon, 11 Sep 2023 15:21:57 +0000 +Subject: [PATCH 25/46] printk: nbcon: Implement emergency sections +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +In emergency situations (something has gone wrong but the +system continues to operate), usually important information +(such as a backtrace) is generated via printk(). Each +individual printk record has little meaning. It is the +collection of printk messages that is most often needed by +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. 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. + +Add functions to mark the beginning and end of emergency +sections where the urgent messages are generated. + +Do not print if the current CPU is in an emergency state. + +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 +console messages. + +Co-developed-by: John Ogness +Signed-off-by: John Ogness +Signed-off-by: Thomas Gleixner (Intel) +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/console.h | 6 ++ + kernel/printk/internal.h | 11 ++++ + kernel/printk/nbcon.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++ + kernel/printk/printk.c | 25 +++++----- + 4 files changed, 146 insertions(+), 12 deletions(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -553,10 +553,16 @@ static inline bool console_is_registered + hlist_for_each_entry(con, &console_list, node) + + #ifdef CONFIG_PRINTK ++extern void nbcon_cpu_emergency_enter(void); ++extern void nbcon_cpu_emergency_exit(void); ++extern void nbcon_cpu_emergency_flush(void); + 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); + #else ++static inline void nbcon_cpu_emergency_enter(void) { } ++static inline void nbcon_cpu_emergency_exit(void) { } ++static inline void nbcon_cpu_emergency_flush(void) { } + 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/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -153,6 +153,17 @@ 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 +@@ -936,6 +936,29 @@ static bool nbcon_emit_next_record(struc + return nbcon_context_exit_unsafe(ctxt); + } + ++/* 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; ++ ++/** ++ * nbcon_get_cpu_emergency_nesting - Get the per CPU emergency nesting pointer ++ * ++ * Return: Either a pointer to the per CPU emergency nesting counter of ++ * the current CPU or to the init data during early boot. ++ */ ++static __ref unsigned int *nbcon_get_cpu_emergency_nesting(void) ++{ ++ /* ++ * The value of __printk_percpu_data_ready gets set in normal ++ * context and before SMP initialization. As a result it could ++ * never change while inside an nbcon emergency section. ++ */ ++ if (!printk_percpu_data_ready()) ++ return &early_nbcon_pcpu_emergency_nesting; ++ ++ return this_cpu_ptr(&nbcon_pcpu_emergency_nesting); ++} ++ + /** + * nbcon_get_default_prio - The appropriate nbcon priority to use for nbcon + * printing on the current CPU +@@ -946,9 +969,15 @@ static bool nbcon_emit_next_record(struc + */ + enum nbcon_prio nbcon_get_default_prio(void) + { ++ unsigned int *cpu_emergency_nesting; ++ + if (this_cpu_in_panic()) + return NBCON_PRIO_PANIC; + ++ cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting(); ++ if (*cpu_emergency_nesting) ++ return NBCON_PRIO_EMERGENCY; ++ + return NBCON_PRIO_NORMAL; + } + +@@ -1200,6 +1229,93 @@ void nbcon_atomic_flush_unsafe(void) + } + + /** ++ * nbcon_cpu_emergency_enter - Enter an emergency section where printk() ++ * messages for that CPU are only stored ++ * ++ * Upon exiting the emergency section, all stored messages are flushed. ++ * ++ * Context: Any context. Disables preemption. ++ * ++ * When within an emergency section, no printing occurs on that CPU. This ++ * is to allow all emergency messages to be dumped into the ringbuffer before ++ * flushing the ringbuffer. The actual printing occurs when exiting the ++ * outermost emergency section. ++ */ ++void nbcon_cpu_emergency_enter(void) ++{ ++ unsigned int *cpu_emergency_nesting; ++ ++ preempt_disable(); ++ ++ cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting(); ++ (*cpu_emergency_nesting)++; ++} ++ ++/** ++ * nbcon_cpu_emergency_exit - Exit an emergency section and flush the ++ * stored messages ++ * ++ * Flushing only occurs when exiting all nesting for the CPU. ++ * ++ * Context: Any context. Enables preemption. ++ */ ++void nbcon_cpu_emergency_exit(void) ++{ ++ unsigned int *cpu_emergency_nesting; ++ bool do_trigger_flush = false; ++ ++ cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting(); ++ ++ /* ++ * Flush the messages before enabling preemtion to see them ASAP. ++ * ++ * Reduce the risk of potential softlockup by using the ++ * flush_pending() variant which ignores messages added later. It is ++ * called before decrementing the counter so that the printing context ++ * for the emergency messages is NBCON_PRIO_EMERGENCY. ++ */ ++ if (*cpu_emergency_nesting == 1) { ++ nbcon_atomic_flush_pending(); ++ do_trigger_flush = true; ++ } ++ ++ (*cpu_emergency_nesting)--; ++ ++ if (WARN_ON_ONCE(*cpu_emergency_nesting < 0)) ++ *cpu_emergency_nesting = 0; ++ ++ preempt_enable(); ++ ++ if (do_trigger_flush) ++ printk_trigger_flush(); ++} ++ ++/** ++ * nbcon_cpu_emergency_flush - Explicitly flush consoles while ++ * within emergency context ++ * ++ * Both nbcon and legacy consoles are flushed. ++ * ++ * It should be used only when there are too many messages printed ++ * in emergency context, for example, printing backtraces of all ++ * CPUs or processes. It is typically needed when the watchdogs ++ * need to be touched as well. ++ */ ++void nbcon_cpu_emergency_flush(void) ++{ ++ /* The explicit flush is needed only in the emergency context. */ ++ if (*(nbcon_get_cpu_emergency_nesting()) == 0) ++ return; ++ ++ nbcon_atomic_flush_pending(); ++ ++ if (printing_via_unlock && !in_nmi()) { ++ if (console_trylock()) ++ console_unlock(); ++ } ++} ++ ++/** + * nbcon_alloc - Allocate buffers needed by the nbcon console + * @con: Console to allocate buffers for + * +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -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, +@@ -483,15 +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; +- +-/* +- * 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) ++bool have_boot_console; + + #ifdef CONFIG_PRINTK + DECLARE_WAIT_QUEUE_HEAD(log_wait); +@@ -2412,16 +2404,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. ++ * ++ * Also, nbcon_get_default_prio() requires migration disabled. + */ + 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. ++ * ++ * 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) { ++ if (console_trylock_spinning()) ++ console_unlock(); ++ } ++ + preempt_enable(); + } + diff --git a/debian/patches-rt/0026-panic-Mark-emergency-section-in-warn.patch b/debian/patches-rt/0026-panic-Mark-emergency-section-in-warn.patch new file mode 100644 index 0000000000..37bf7b8fab --- /dev/null +++ b/debian/patches-rt/0026-panic-Mark-emergency-section-in-warn.patch @@ -0,0 +1,39 @@ +From: Thomas Gleixner +Date: Mon, 11 Sep 2023 15:53:04 +0000 +Subject: [PATCH 26/46] panic: Mark emergency section in warn +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 is +triggered when exiting the emergency section. + +Co-developed-by: John Ogness +Signed-off-by: John Ogness +Signed-off-by: Thomas Gleixner (Intel) +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/panic.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -671,6 +671,8 @@ struct warn_args { + void __warn(const char *file, int line, void *caller, unsigned taint, + struct pt_regs *regs, struct warn_args *args) + { ++ nbcon_cpu_emergency_enter(); ++ + disable_trace_on_warning(); + + if (file) +@@ -706,6 +708,8 @@ void __warn(const char *file, int line, + + /* Just a warning, don't kill lockdep. */ + add_taint(taint, LOCKDEP_STILL_OK); ++ ++ nbcon_cpu_emergency_exit(); + } + + #ifdef CONFIG_BUG diff --git a/debian/patches-rt/0026-printk-Track-nbcon-consoles.patch b/debian/patches-rt/0026-printk-Track-nbcon-consoles.patch deleted file mode 100644 index 7c54a03775..0000000000 --- a/debian/patches-rt/0026-printk-Track-nbcon-consoles.patch +++ /dev/null @@ -1,65 +0,0 @@ -From: John Ogness -Date: Mon, 11 Dec 2023 09:36:52 +0000 -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 -to preserve legacy behavior when no nbcon consoles are registered. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - 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,11 @@ static DEFINE_MUTEX(syslog_lock); - static bool have_legacy_console; - - /* -+ * Specifies if an nbcon console is registered. -+ */ -+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 -@@ -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); - - /* -@@ -3624,6 +3630,7 @@ EXPORT_SYMBOL(register_console); - static int unregister_console_locked(struct console *console) - { - bool found_legacy_con = false; -+ bool found_nbcon_con = false; - bool found_boot_con = false; - struct console *c; - int res; -@@ -3680,13 +3687,18 @@ static int unregister_console_locked(str - for_each_console(c) { - if (c->flags & CON_BOOT) - found_boot_con = true; -- if (!(c->flags & CON_NBCON)) -+ -+ if (c->flags & CON_NBCON) -+ found_nbcon_con = true; -+ else - found_legacy_con = true; - } - if (!found_boot_con) - have_boot_console = found_boot_con; - if (!found_legacy_con) - have_legacy_console = found_legacy_con; -+ if (!found_nbcon_con) -+ have_nbcon_console = found_nbcon_con; - - return res; - } diff --git a/debian/patches-rt/0027-panic-Mark-emergency-section-in-oops.patch b/debian/patches-rt/0027-panic-Mark-emergency-section-in-oops.patch new file mode 100644 index 0000000000..4c382ac927 --- /dev/null +++ b/debian/patches-rt/0027-panic-Mark-emergency-section-in-oops.patch @@ -0,0 +1,40 @@ +From: John Ogness +Date: Tue, 19 Sep 2023 17:07:34 +0000 +Subject: [PATCH 27/46] panic: Mark emergency section in oops +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 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 +flushing mechanism that should occur after the consoles have +been triggered to flush. + +Signed-off-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/panic.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -638,6 +638,7 @@ bool oops_may_print(void) + */ + void oops_enter(void) + { ++ nbcon_cpu_emergency_enter(); + tracing_off(); + /* can't trust the integrity of the kernel anymore: */ + debug_locks_off(); +@@ -660,6 +661,7 @@ void oops_exit(void) + { + do_oops_enter_exit(); + print_oops_end_marker(); ++ nbcon_cpu_emergency_exit(); + kmsg_dump(KMSG_DUMP_OOPS); + } + diff --git a/debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch b/debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch deleted file mode 100644 index 4893dd463f..0000000000 --- a/debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch +++ /dev/null @@ -1,163 +0,0 @@ -From: John Ogness -Date: Wed, 22 Nov 2023 11:56:58 +0000 -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 -as soon as possible. - -If legacy and nbcon consoles are registered, the legacy consoles -will no longer perform direct printing on the panic CPU until -after the backtrace has been stored. This will give the safe -nbcon consoles a chance to print the panic messages before -allowing the unsafe legacy consoles to print. - -If no nbcon consoles are registered, there is no change in -behavior (i.e. legacy consoles will always attempt to print -from the printk() caller context). - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/printk.h | 5 +++ - kernel/panic.c | 2 + - kernel/printk/printk.c | 62 ++++++++++++++++++++++++++++++++++++++++++------- - 3 files changed, 61 insertions(+), 8 deletions(-) - ---- a/include/linux/printk.h -+++ b/include/linux/printk.h -@@ -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( - { - } - -+static inline void printk_legacy_allow_panic_sync(void) -+{ -+} -+ - static inline void nbcon_driver_acquire(struct console *con) - { - } ---- a/kernel/panic.c -+++ b/kernel/panic.c -@@ -364,6 +364,8 @@ void panic(const char *fmt, ...) - - panic_other_cpus_shutdown(_crash_kexec_post_notifiers); - -+ printk_legacy_allow_panic_sync(); -+ - /* - * 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 -@@ -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; - } - -+static bool legacy_allow_panic_sync; -+ -+/* -+ * This acts as a one-way switch to allow legacy consoles to print from -+ * 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, - const struct dev_printk_info *dev_info, - const char *fmt, va_list args) - { -+ bool do_trylock_unlock = printing_via_unlock; - int printed_len; -- bool in_sched = false; - - /* Suppress unimportant messages after panic happens */ - if (unlikely(suppress_printk)) -@@ -2356,15 +2375,42 @@ asmlinkage int vprintk_emit(int facility - - if (level == LOGLEVEL_SCHED) { - level = LOGLEVEL_DEFAULT; -- in_sched = true; -+ /* If called from the scheduler, we can not call up(). */ -+ do_trylock_unlock = false; - } - - printk_delay(level); - - printed_len = vprintk_store(facility, level, dev_info, fmt, args); - -- /* If called from the scheduler, we can not call up(). */ -- if (!in_sched && printing_via_unlock) { -+ if (have_nbcon_console && !have_boot_console) { -+ bool is_panic_context = this_cpu_in_panic(); -+ -+ /* -+ * In panic, the legacy consoles are not allowed to print from -+ * the printk calling context unless explicitly allowed. This -+ * gives the safe nbcon consoles a chance to print out all the -+ * panic messages first. This restriction only applies if -+ * there are nbcon consoles registered. -+ */ -+ if (is_panic_context) -+ do_trylock_unlock &= legacy_allow_panic_sync; -+ -+ /* -+ * There are situations where nbcon atomic printing should -+ * happen in the printk() caller context: -+ * -+ * - When this CPU is in panic. -+ * -+ * 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_pending(); -+ } -+ -+ if (do_trylock_unlock) { - /* - * The caller may be holding system-critical or - * timing-sensitive locks. Disable preemption during -@@ -2384,10 +2430,10 @@ asmlinkage int vprintk_emit(int facility - preempt_enable(); - } - -- if (in_sched) -- defer_console_output(); -- else -+ if (do_trylock_unlock) - wake_up_klogd(); -+ else -+ defer_console_output(); - - return printed_len; - } diff --git a/debian/patches-rt/0028-printk-nbcon-Implement-emergency-sections.patch b/debian/patches-rt/0028-printk-nbcon-Implement-emergency-sections.patch deleted file mode 100644 index f3a05868e7..0000000000 --- a/debian/patches-rt/0028-printk-nbcon-Implement-emergency-sections.patch +++ /dev/null @@ -1,201 +0,0 @@ -From: Thomas Gleixner -Date: Mon, 11 Sep 2023 15:21:57 +0000 -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 -(such as a backtrace) is generated via printk(). Each -individual printk record has little meaning. It is the -collection of printk messages that is most often needed by -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. 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. - -Add functions to mark the beginning and end of emergency -sections where the urgent messages are generated. - -Do not print if the current CPU is in an emergency state. - -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 -console messages. - -Co-developed-by: John Ogness -Signed-off-by: John Ogness -Signed-off-by: Thomas Gleixner (Intel) -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/console.h | 4 ++ - 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 -@@ -559,10 +559,14 @@ static inline bool console_is_registered - hlist_for_each_entry(con, &console_list, node) - - #ifdef CONFIG_PRINTK -+extern void nbcon_cpu_emergency_enter(void); -+extern void nbcon_cpu_emergency_exit(void); - 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); - #else -+static inline void nbcon_cpu_emergency_enter(void) { } -+static inline void nbcon_cpu_emergency_exit(void) { } - 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/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -936,6 +936,29 @@ static bool nbcon_emit_next_record(struc - return nbcon_context_exit_unsafe(ctxt); - } - -+/* 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; -+ -+/** -+ * nbcon_get_cpu_emergency_nesting - Get the per CPU emergency nesting pointer -+ * -+ * Return: Either a pointer to the per CPU emergency nesting counter of -+ * the current CPU or to the init data during early boot. -+ */ -+static __ref unsigned int *nbcon_get_cpu_emergency_nesting(void) -+{ -+ /* -+ * The value of __printk_percpu_data_ready gets set in normal -+ * context and before SMP initialization. As a result it could -+ * never change while inside an nbcon emergency section. -+ */ -+ if (!printk_percpu_data_ready()) -+ return &early_nbcon_pcpu_emergency_nesting; -+ -+ return this_cpu_ptr(&nbcon_pcpu_emergency_nesting); -+} -+ - /** - * nbcon_atomic_emit_one - Print one record for an nbcon console using the - * write_atomic() callback -@@ -977,9 +1000,15 @@ static bool nbcon_atomic_emit_one(struct - */ - enum nbcon_prio nbcon_get_default_prio(void) - { -+ unsigned int *cpu_emergency_nesting; -+ - if (this_cpu_in_panic()) - return NBCON_PRIO_PANIC; - -+ cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting(); -+ if (*cpu_emergency_nesting) -+ return NBCON_PRIO_EMERGENCY; -+ - return NBCON_PRIO_NORMAL; - } - -@@ -1147,6 +1176,60 @@ void nbcon_atomic_flush_unsafe(void) - } - - /** -+ * nbcon_cpu_emergency_enter - Enter an emergency section where printk() -+ * messages for that CPU are only stored -+ * -+ * Upon exiting the emergency section, all stored messages are flushed. -+ * -+ * Context: Any context. Disables preemption. -+ * -+ * When within an emergency section, no printing occurs on that CPU. This -+ * is to allow all emergency messages to be dumped into the ringbuffer before -+ * flushing the ringbuffer. The actual printing occurs when exiting the -+ * outermost emergency section. -+ */ -+void nbcon_cpu_emergency_enter(void) -+{ -+ unsigned int *cpu_emergency_nesting; -+ -+ preempt_disable(); -+ -+ cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting(); -+ (*cpu_emergency_nesting)++; -+} -+ -+/** -+ * nbcon_cpu_emergency_exit - Exit an emergency section and flush the -+ * stored messages -+ * -+ * Flushing only occurs when exiting all nesting for the CPU. -+ * -+ * Context: Any context. Enables preemption. -+ */ -+void nbcon_cpu_emergency_exit(void) -+{ -+ unsigned int *cpu_emergency_nesting; -+ bool do_trigger_flush = false; -+ -+ cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting(); -+ -+ WARN_ON_ONCE(*cpu_emergency_nesting == 0); -+ -+ 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)--; -+ -+ preempt_enable(); -+ -+ if (do_trigger_flush) -+ printk_trigger_flush(); -+} -+ -+/** - * nbcon_alloc - Allocate buffers needed by the nbcon console - * @con: Console to allocate buffers for - * ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -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. -+ * -+ * Also, nbcon_get_default_prio() requires migration disabled. - */ - 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. -+ * -+ * 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) { -+ if (console_trylock_spinning()) -+ console_unlock(); -+ } -+ - preempt_enable(); - } - diff --git a/debian/patches-rt/0028-rcu-Mark-emergency-sections-in-rcu-stalls.patch b/debian/patches-rt/0028-rcu-Mark-emergency-sections-in-rcu-stalls.patch new file mode 100644 index 0000000000..7a13ac0042 --- /dev/null +++ b/debian/patches-rt/0028-rcu-Mark-emergency-sections-in-rcu-stalls.patch @@ -0,0 +1,128 @@ +From: John Ogness +Date: Mon, 11 Sep 2023 15:53:39 +0000 +Subject: [PATCH 28/46] rcu: Mark emergency sections in rcu stalls +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/rcu/tree_exp.h | 9 +++++++++ + kernel/rcu/tree_stall.h | 11 +++++++++++ + 2 files changed, 20 insertions(+) + +--- a/kernel/rcu/tree_exp.h ++++ b/kernel/rcu/tree_exp.h +@@ -7,6 +7,7 @@ + * Authors: Paul E. McKenney + */ + ++#include + #include + + static void rcu_exp_handler(void *unused); +@@ -571,6 +572,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")); +@@ -612,6 +616,7 @@ static void synchronize_rcu_expedited_wa + } + pr_cont("\n"); + } ++ nbcon_cpu_emergency_flush(); + rcu_for_each_leaf_node(rnp) { + for_each_leaf_node_possible_cpu(rnp, cpu) { + mask = leaf_node_cpu_bit(rnp, cpu); +@@ -624,6 +629,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(); + } + } +@@ -792,6 +800,7 @@ static void rcu_exp_print_detail_task_st + */ + touch_nmi_watchdog(); + sched_show_task(t); ++ nbcon_cpu_emergency_flush(); + } + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); + } +--- a/kernel/rcu/tree_stall.h ++++ b/kernel/rcu/tree_stall.h +@@ -7,6 +7,7 @@ + * Author: Paul E. McKenney + */ + ++#include + #include + #include + +@@ -260,6 +261,7 @@ static void rcu_print_detail_task_stall_ + */ + touch_nmi_watchdog(); + sched_show_task(t); ++ nbcon_cpu_emergency_flush(); + } + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); + } +@@ -522,6 +524,7 @@ static void print_cpu_stall_info(int cpu + falsepositive ? " (false positive?)" : ""); + + print_cpu_stat_info(cpu); ++ nbcon_cpu_emergency_flush(); + } + + /* Complain about starvation of grace-period kthread. */ +@@ -604,6 +607,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 +660,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 +682,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 +712,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/0029-lockdep-Mark-emergency-sections-in-lockdep-splats.patch b/debian/patches-rt/0029-lockdep-Mark-emergency-sections-in-lockdep-splats.patch new file mode 100644 index 0000000000..1f3ab33c45 --- /dev/null +++ b/debian/patches-rt/0029-lockdep-Mark-emergency-sections-in-lockdep-splats.patch @@ -0,0 +1,461 @@ +From: John Ogness +Date: Mon, 18 Sep 2023 20:27:41 +0000 +Subject: [PATCH 29/46] lockdep: Mark emergency sections in lockdep splats +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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. + +Note that debug_show_all_locks() and +lockdep_print_held_locks() rely on their callers to +enter the emergency section. This is because these +functions can also be called in non-emergency +situations (such as sysrq). + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/locking/lockdep.c | 84 +++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 82 insertions(+), 2 deletions(-) + +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -56,6 +56,7 @@ + #include + #include + #include ++#include + + #include + +@@ -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; + } +@@ -888,11 +891,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 +974,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 +1324,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 +1359,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 +1404,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 +2053,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 +2073,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 +2587,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 +2638,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 +3009,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 +3033,8 @@ print_deadlock_bug(struct task_struct *c + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + /* +@@ -3607,6 +3632,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 +3650,8 @@ static void print_collision(struct task_ + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + #endif + +@@ -3713,8 +3742,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 +3762,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 +4004,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 +4034,8 @@ print_usage_bug(struct task_struct *curr + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + /* +@@ -4033,6 +4070,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 +4112,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 +4195,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 +4210,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 +4732,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 +4778,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 +4799,8 @@ print_lock_invalid_wait_context(struct t + pr_warn("stack backtrace:\n"); + dump_stack(); + ++ nbcon_cpu_emergency_exit(); ++ + return 0; + } + +@@ -4954,6 +5005,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 +5027,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 +5074,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 +5207,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 +5215,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 +5235,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 +5253,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 +5958,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 +5976,8 @@ static void print_lock_contention_bug(st + + pr_warn("\nstack backtrace:\n"); + dump_stack(); ++ ++ nbcon_cpu_emergency_exit(); + } + + static void +@@ -6524,6 +6591,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 +6605,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 +6653,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 +6664,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) +@@ -6616,6 +6691,7 @@ void debug_show_all_locks(void) + if (!p->lockdep_depth) + continue; + lockdep_print_held_locks(p); ++ nbcon_cpu_emergency_flush(); + touch_nmi_watchdog(); + touch_all_softlockup_watchdogs(); + } +@@ -6648,6 +6724,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 +6733,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 +6750,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 +6789,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/0029-panic-Mark-emergency-section-in-warn.patch b/debian/patches-rt/0029-panic-Mark-emergency-section-in-warn.patch deleted file mode 100644 index 35c04773c5..0000000000 --- a/debian/patches-rt/0029-panic-Mark-emergency-section-in-warn.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Thomas Gleixner -Date: Mon, 11 Sep 2023 15:53:04 +0000 -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 is -triggered when exiting the emergency section. - -Co-developed-by: John Ogness -Signed-off-by: John Ogness -Signed-off-by: Thomas Gleixner (Intel) -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/panic.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/kernel/panic.c -+++ b/kernel/panic.c -@@ -667,6 +667,8 @@ struct warn_args { - void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, struct warn_args *args) - { -+ nbcon_cpu_emergency_enter(); -+ - disable_trace_on_warning(); - - if (file) -@@ -697,6 +699,8 @@ void __warn(const char *file, int line, - - /* Just a warning, don't kill lockdep. */ - add_taint(taint, LOCKDEP_STILL_OK); -+ -+ nbcon_cpu_emergency_exit(); - } - - #ifdef CONFIG_BUG diff --git a/debian/patches-rt/0030-panic-Mark-emergency-section-in-oops.patch b/debian/patches-rt/0030-panic-Mark-emergency-section-in-oops.patch deleted file mode 100644 index cd3d80fe60..0000000000 --- a/debian/patches-rt/0030-panic-Mark-emergency-section-in-oops.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: John Ogness -Date: Tue, 19 Sep 2023 17:07:34 +0000 -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 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 -flushing mechanism that should occur after the consoles have -been triggered to flush. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/panic.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/kernel/panic.c -+++ b/kernel/panic.c -@@ -634,6 +634,7 @@ bool oops_may_print(void) - */ - void oops_enter(void) - { -+ nbcon_cpu_emergency_enter(); - tracing_off(); - /* can't trust the integrity of the kernel anymore: */ - debug_locks_off(); -@@ -656,6 +657,7 @@ void oops_exit(void) - { - do_oops_enter_exit(); - print_oops_end_marker(); -+ nbcon_cpu_emergency_exit(); - kmsg_dump(KMSG_DUMP_OOPS); - } - diff --git a/debian/patches-rt/0030-printk-nbcon-Introduce-printing-kthreads.patch b/debian/patches-rt/0030-printk-nbcon-Introduce-printing-kthreads.patch new file mode 100644 index 0000000000..85792a75e2 --- /dev/null +++ b/debian/patches-rt/0030-printk-nbcon-Introduce-printing-kthreads.patch @@ -0,0 +1,478 @@ +From: Thomas Gleixner +Date: Fri, 22 Sep 2023 14:12:21 +0000 +Subject: [PATCH 30/46] printk: nbcon: Introduce printing kthreads +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Provide the main implementation for running a printer kthread +per nbcon console that is takeover/handover aware. + +Co-developed-by: John Ogness +Signed-off-by: John Ogness +Signed-off-by: Thomas Gleixner (Intel) +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/console.h | 26 ++++++ + kernel/printk/internal.h | 26 ++++++ + kernel/printk/nbcon.c | 196 +++++++++++++++++++++++++++++++++++++++++++++-- + kernel/printk/printk.c | 31 +++++++ + 4 files changed, 271 insertions(+), 8 deletions(-) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -324,6 +325,8 @@ struct nbcon_write_context { + * @nbcon_seq: Sequence number of the next record for nbcon to print + * @nbcon_driver_ctxt: Context available for driver non-printing operations + * @pbufs: Pointer to nbcon private buffer ++ * @kthread: Printer kthread for this console ++ * @rcuwait: RCU-safe wait object for @kthread waking + */ + struct console { + char name[16]; +@@ -374,6 +377,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. +@@ -420,6 +444,8 @@ struct console { + atomic_long_t __private nbcon_seq; + struct nbcon_context __private nbcon_driver_ctxt; + struct printk_buffers *pbufs; ++ struct task_struct *kthread; ++ struct rcuwait rcuwait; + }; + + #ifdef CONFIG_LOCKDEP +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -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 +@@ -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) ++ return false; + } else { + if (!con->write) + return false; +@@ -124,12 +127,35 @@ static inline bool console_is_usable(str + return true; + } + ++/** ++ * nbcon_kthread_wake - Wake up a printk thread ++ * @con: Console to operate on ++ */ ++static inline void nbcon_kthread_wake(struct console *con) ++{ ++ /* ++ * Guarantee any new records can be seen by tasks preparing to wait ++ * before this context checks if the rcuwait is empty. ++ * ++ * The full memory barrier in rcuwait_wake_up() pairs with the full ++ * memory barrier within set_current_state() of ++ * ___rcuwait_wait_event(), which is called after prepare_to_rcuwait() ++ * adds the waiter but before it has checked the wait condition. ++ * ++ * This pairs with nbcon_kthread_func:A. ++ */ ++ rcuwait_wake_up(&con->rcuwait); /* LMM(nbcon_kthread_wake:A) */ ++} ++ + #else + + #define PRINTK_PREFIX_MAX 0 + #define PRINTK_MESSAGE_MAX 0 + #define PRINTKRB_RECORD_MAX 0 + ++static inline void nbcon_kthread_wake(struct console *con) { } ++static inline void nbcon_kthread_create(struct console *con) { } ++ + /* + * In !PRINTK builds we still export console_sem + * semaphore and some of console functions (console_unlock()/etc.), so +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -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 ++ * @use_atomic: True if the write_atomic callback is to be used + * + * Return: True if this context still owns the console. False if + * ownership was handed over or taken. +@@ -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, + */ +-static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt) ++static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt, bool use_atomic) + { + struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); + struct console *con = ctxt->console; +@@ -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 (use_atomic && ++ con->write_atomic) { + con->write_atomic(con, wctxt); ++ ++ } else if (!use_atomic && ++ con->write_thread) { ++ con->write_thread(con, wctxt); ++ + } else { + /* + * 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); + } + ++/** ++ * nbcon_kthread_should_wakeup - Check whether a printer thread should wakeup ++ * @con: Console to operate on ++ * @ctxt: The acquire context that contains the state ++ * at console_acquire() ++ * ++ * Return: True if the thread should shutdown or if the console is ++ * allowed to print and a record is available. False otherwise. ++ * ++ * After the thread wakes up, it must first check if it should shutdown before ++ * attempting any printing. ++ */ ++static bool nbcon_kthread_should_wakeup(struct console *con, struct nbcon_context *ctxt) ++{ ++ bool ret = false; ++ short flags; ++ int cookie; ++ ++ if (kthread_should_stop()) ++ return true; ++ ++ cookie = console_srcu_read_lock(); ++ ++ 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); ++ ++ ret = prb_read_valid(prb, ctxt->seq, NULL); ++ } ++ ++ console_srcu_read_unlock(cookie); ++ return ret; ++} ++ ++/** ++ * nbcon_kthread_func - The printer thread function ++ * @__console: Console to operate on ++ */ ++static int nbcon_kthread_func(void *__console) ++{ ++ struct console *con = __console; ++ struct nbcon_write_context wctxt = { ++ .ctxt.console = con, ++ .ctxt.prio = NBCON_PRIO_NORMAL, ++ }; ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); ++ unsigned long flags; ++ short con_flags; ++ bool backlog; ++ int cookie; ++ int ret; ++ ++wait_for_event: ++ /* ++ * Guarantee this task is visible on the rcuwait before ++ * checking the wake condition. ++ * ++ * The full memory barrier within set_current_state() of ++ * ___rcuwait_wait_event() pairs with the full memory ++ * barrier within rcuwait_has_sleeper(). ++ * ++ * This pairs with rcuwait_has_sleeper:A and nbcon_kthread_wake:A. ++ */ ++ ret = rcuwait_wait_event(&con->rcuwait, ++ nbcon_kthread_should_wakeup(con, ctxt), ++ TASK_INTERRUPTIBLE); /* LMM(nbcon_kthread_func:A) */ ++ ++ if (kthread_should_stop()) ++ return 0; ++ ++ /* Wait was interrupted by a spurious signal, go back to sleep. */ ++ if (ret) ++ goto wait_for_event; ++ ++ do { ++ backlog = false; ++ ++ cookie = console_srcu_read_lock(); ++ ++ con_flags = console_srcu_read_flags(con); ++ ++ if (console_is_usable(con, con_flags)) { ++ con->device_lock(con, &flags); ++ ++ /* ++ * Ensure this stays on the CPU to make handover and ++ * takeover possible. ++ */ ++ cant_migrate(); ++ ++ if (nbcon_context_try_acquire(ctxt)) { ++ /* ++ * If the emit fails, this context is no ++ * longer the owner. ++ */ ++ if (nbcon_emit_next_record(&wctxt, false)) { ++ nbcon_context_release(ctxt); ++ backlog = ctxt->backlog; ++ } ++ } ++ ++ con->device_unlock(con, flags); ++ } ++ ++ console_srcu_read_unlock(cookie); ++ ++ } while (backlog); ++ ++ goto wait_for_event; ++} ++ + /* 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; +@@ -1012,7 +1132,7 @@ static bool nbcon_atomic_emit_one(struct + * The higher priority printing context takes over responsibility + * to print the pending records. + */ +- if (!nbcon_emit_next_record(wctxt)) ++ if (!nbcon_emit_next_record(wctxt, true)) + return false; + + nbcon_context_release(ctxt); +@@ -1113,7 +1233,7 @@ static int __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 -EAGAIN; + + if (!ctxt->backlog) { +@@ -1159,11 +1279,11 @@ static void nbcon_atomic_flush_pending_c + local_irq_restore(flags); + + /* +- * If flushing was successful but more records are available, this +- * context must flush those remaining records because there is no +- * other context that will do it. ++ * If flushing was successful but more records are available this ++ * context must flush those remaining records if the printer thread ++ * is not available to do it. + */ +- if (!err && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { ++ if (!err && !con->kthread && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { + stop_seq = prb_next_reserve_seq(prb); + goto again; + } +@@ -1315,6 +1435,63 @@ void nbcon_cpu_emergency_flush(void) + } + } + ++/* ++ * nbcon_kthread_stop - Stop a printer thread ++ * @con: Console to operate on ++ */ ++static void nbcon_kthread_stop(struct console *con) ++{ ++ lockdep_assert_console_list_lock_held(); ++ ++ if (!con->kthread) ++ return; ++ ++ kthread_stop(con->kthread); ++ con->kthread = NULL; ++} ++ ++/** ++ * nbcon_kthread_create - Create a printer thread ++ * @con: Console to operate on ++ * ++ * If it fails, let the console proceed. The atomic part might ++ * be usable and useful. ++ */ ++void nbcon_kthread_create(struct console *con) ++{ ++ struct task_struct *kt; ++ ++ lockdep_assert_console_list_lock_held(); ++ ++ if (!(con->flags & CON_NBCON) || !con->write_thread) ++ return; ++ ++ if (con->kthread) ++ return; ++ ++ /* ++ * Printer threads cannot be started as long as any boot console is ++ * registered because there is no way to synchronize the hardware ++ * registers between boot console code and regular console code. ++ */ ++ if (have_boot_console) ++ return; ++ ++ kt = kthread_run(nbcon_kthread_func, con, "pr/%s%d", con->name, con->index); ++ if (IS_ERR(kt)) { ++ con_printk(KERN_ERR, con, "failed to start printing thread\n"); ++ return; ++ } ++ ++ con->kthread = kt; ++ ++ /* ++ * It is important that console printing threads are scheduled ++ * shortly after a printk call and with generous runtime budgets. ++ */ ++ sched_set_normal(con->kthread, -20); ++} ++ + /** + * nbcon_alloc - Allocate buffers needed by the nbcon console + * @con: Console to allocate buffers for +@@ -1360,6 +1537,7 @@ void nbcon_init(struct console *con, u64 + /* nbcon_alloc() must have been called and successful! */ + BUG_ON(!con->pbufs); + ++ rcuwait_init(&con->rcuwait); + nbcon_seq_force(con, init_seq); + nbcon_state_set(con, &state); + } +@@ -1372,6 +1550,7 @@ void nbcon_free(struct console *con) + { + struct nbcon_state state = { }; + ++ nbcon_kthread_stop(con); + nbcon_state_set(con, &state); + + /* Boot consoles share global printk buffers. */ +@@ -1440,6 +1619,7 @@ void nbcon_driver_release(struct console + */ + cookie = console_srcu_read_lock(); + if (console_is_usable(con, console_srcu_read_flags(con)) && ++ !con->kthread && + prb_read_valid(prb, nbcon_seq_read(con), NULL)) { + __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb), false); + } +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2685,6 +2685,8 @@ void suspend_console(void) + void resume_console(void) + { + struct console *con; ++ short flags; ++ int cookie; + + if (!console_suspend_enabled) + return; +@@ -2701,6 +2703,14 @@ void resume_console(void) + */ + synchronize_srcu(&console_srcu); + ++ cookie = console_srcu_read_lock(); ++ for_each_console_srcu(con) { ++ flags = console_srcu_read_flags(con); ++ if (flags & CON_NBCON) ++ nbcon_kthread_wake(con); ++ } ++ console_srcu_read_unlock(cookie); ++ + pr_flush(1000, true); + } + +@@ -3021,6 +3031,13 @@ static bool console_flush_all(bool do_co + u64 printk_seq; + bool progress; + ++ /* ++ * console_flush_all() is only for legacy consoles, ++ * unless the nbcon console has no kthread printer. ++ */ ++ if ((flags & CON_NBCON) && con->kthread) ++ continue; ++ + if (!console_is_usable(con, flags)) + continue; + any_usable = true; +@@ -3314,9 +3331,23 @@ EXPORT_SYMBOL(console_stop); + + void console_start(struct console *console) + { ++ short flags; ++ + console_list_lock(); + console_srcu_write_flags(console, console->flags | CON_ENABLED); ++ flags = console->flags; + console_list_unlock(); ++ ++ /* ++ * Ensure that all SRCU list walks have completed. The related ++ * printing context must be able to see it is enabled so that ++ * it is guaranteed to wake up and resume printing. ++ */ ++ synchronize_srcu(&console_srcu); ++ ++ if (flags & CON_NBCON) ++ nbcon_kthread_wake(console); ++ + __pr_flush(console, 1000, true); + } + EXPORT_SYMBOL(console_start); diff --git a/debian/patches-rt/0031-printk-Atomic-print-in-printk-context-on-shutdown.patch b/debian/patches-rt/0031-printk-Atomic-print-in-printk-context-on-shutdown.patch new file mode 100644 index 0000000000..7c515605a7 --- /dev/null +++ b/debian/patches-rt/0031-printk-Atomic-print-in-printk-context-on-shutdown.patch @@ -0,0 +1,40 @@ +From: John Ogness +Date: Mon, 23 Oct 2023 17:43:48 +0000 +Subject: [PATCH 31/46] printk: Atomic print in printk context on shutdown +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +For nbcon consoles, normally the printing is handled by the +dedicated console printing threads. However, on shutdown the +printing threads may not get a chance to print the final +messages. + +When shutting down or rebooting (system_state > SYSTEM_RUNNING), +perform atomic printing from the printk() caller context. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/printk.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2389,12 +2389,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/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_pending(); ++ } + } + + if (do_trylock_unlock) { 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 deleted file mode 100644 index 0cca134a21..0000000000 --- a/debian/patches-rt/0031-rcu-Mark-emergency-sections-in-rcu-stalls.patch +++ /dev/null @@ -1,96 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 - */ - -+#include - #include - - 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 - */ - -+#include - #include - #include - -@@ -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 deleted file mode 100644 index 64cf39b672..0000000000 --- a/debian/patches-rt/0032-lockdep-Mark-emergency-sections-in-lockdep-splats.patch +++ /dev/null @@ -1,487 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 - #include - #include -+#include - - #include - -@@ -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/0032-printk-nbcon-Add-context-to-console_is_usable.patch b/debian/patches-rt/0032-printk-nbcon-Add-context-to-console_is_usable.patch new file mode 100644 index 0000000000..6c74d8e079 --- /dev/null +++ b/debian/patches-rt/0032-printk-nbcon-Add-context-to-console_is_usable.patch @@ -0,0 +1,120 @@ +From: John Ogness +Date: Tue, 26 Sep 2023 14:43:30 +0000 +Subject: [PATCH 32/46] printk: nbcon: Add context to console_is_usable() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +The nbcon consoles have two callbacks to be used for different +contexts. In order to determine if an nbcon console is usable, +console_is_usable() needs to know if it is a context that will +use the write_atomic() callback or the write_thread() callback. + +Add an extra parameter @use_atomic to specify this. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 16 ++++++++++------ + kernel/printk/nbcon.c | 8 ++++---- + kernel/printk/printk.c | 6 ++++-- + 3 files changed, 18 insertions(+), 12 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -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. + */ +-static inline bool console_is_usable(struct console *con, short flags) ++static inline bool console_is_usable(struct console *con, short flags, bool use_atomic) + { + if (!(flags & CON_ENABLED)) + return false; +@@ -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) +- return false; ++ if (use_atomic) { ++ if (!con->write_atomic) ++ return false; ++ } else { ++ if (!con->write_thread) ++ return false; ++ } + } else { + if (!con->write) + return false; +@@ -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; } ++static inline bool console_is_usable(struct console *con, short flags, ++ bool use_atomic) { return false; } + + #endif /* CONFIG_PRINTK */ + +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -968,7 +968,7 @@ static bool nbcon_kthread_should_wakeup( + cookie = console_srcu_read_lock(); + + flags = console_srcu_read_flags(con); +- 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); + +@@ -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->device_lock(con, &flags); + + /* +@@ -1312,7 +1312,7 @@ static void __nbcon_atomic_flush_pending + if (!(flags & CON_NBCON)) + continue; + +- if (!console_is_usable(con, flags)) ++ if (!console_is_usable(con, flags, true)) + continue; + + if (nbcon_seq_read(con) >= stop_seq) +@@ -1618,7 +1618,7 @@ void nbcon_driver_release(struct console + * the console is usable throughout flushing. + */ + cookie = console_srcu_read_lock(); +- if (console_is_usable(con, console_srcu_read_flags(con)) && ++ if (console_is_usable(con, console_srcu_read_flags(con), true) && + !con->kthread && + prb_read_valid(prb, nbcon_seq_read(con), NULL)) { + __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb), false); +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -3043,7 +3043,7 @@ static bool console_flush_all(bool do_co + if ((flags & CON_NBCON) && con->kthread) + continue; + +- if (!console_is_usable(con, flags)) ++ if (!console_is_usable(con, flags, true)) + continue; + any_usable = true; + +@@ -4001,8 +4001,10 @@ static bool __pr_flush(struct console *c + * that they make forward progress, so only increment + * @diff for usable consoles. + */ +- if (!console_is_usable(c, flags)) ++ if (!console_is_usable(c, flags, true) && ++ !console_is_usable(c, flags, false)) { + continue; ++ } + + if (flags & CON_NBCON) { + printk_seq = nbcon_seq_read(c); diff --git a/debian/patches-rt/0033-printk-nbcon-Add-printer-thread-wakeups.patch b/debian/patches-rt/0033-printk-nbcon-Add-printer-thread-wakeups.patch new file mode 100644 index 0000000000..d560b6b7cf --- /dev/null +++ b/debian/patches-rt/0033-printk-nbcon-Add-printer-thread-wakeups.patch @@ -0,0 +1,164 @@ +From: Thomas Gleixner +Date: Tue, 26 Sep 2023 13:03:52 +0000 +Subject: [PATCH 33/46] printk: nbcon: Add printer thread wakeups +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Add a function to wakeup the printer threads. Use the new function +when: + + - records are added to the printk ringbuffer + - consoles are resumed + - triggered via printk_trigger_flush() + +The actual waking is performed via irq_work so that the wakeup can +be triggered from any context. + +Co-developed-by: John Ogness +Signed-off-by: John Ogness +Signed-off-by: Thomas Gleixner (Intel) +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/console.h | 3 ++ + kernel/printk/internal.h | 1 + kernel/printk/nbcon.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ + kernel/printk/printk.c | 7 +++++ + 4 files changed, 67 insertions(+) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -16,6 +16,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -327,6 +328,7 @@ struct nbcon_write_context { + * @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]; +@@ -446,6 +448,7 @@ struct console { + struct printk_buffers *pbufs; + struct task_struct *kthread; + struct rcuwait rcuwait; ++ struct irq_work irq_work; + }; + + #ifdef CONFIG_LOCKDEP +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -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); + + /* + * Check if the given console is currently capable and allowed to print +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -1056,6 +1056,61 @@ static int nbcon_kthread_func(void *__co + goto wait_for_event; + } + ++/** ++ * nbcon_irq_work - irq work to wake printk thread ++ * @irq_work: The irq work to operate on ++ */ ++static void nbcon_irq_work(struct irq_work *irq_work) ++{ ++ struct console *con = container_of(irq_work, struct console, irq_work); ++ ++ nbcon_kthread_wake(con); ++} ++ ++static inline bool rcuwait_has_sleeper(struct rcuwait *w) ++{ ++ bool has_sleeper; ++ ++ rcu_read_lock(); ++ /* ++ * Guarantee any new records can be seen by tasks preparing to wait ++ * before this context checks if the rcuwait is empty. ++ * ++ * This full memory barrier pairs with the full memory barrier within ++ * set_current_state() of ___rcuwait_wait_event(), which is called ++ * after prepare_to_rcuwait() adds the waiter but before it has ++ * checked the wait condition. ++ * ++ * This pairs with nbcon_kthread_func:A. ++ */ ++ smp_mb(); /* LMM(rcuwait_has_sleeper:A) */ ++ has_sleeper = !!rcu_dereference(w->task); ++ rcu_read_unlock(); ++ ++ return has_sleeper; ++} ++ ++/** ++ * nbcon_wake_threads - Wake up printing threads using irq_work ++ */ ++void nbcon_wake_threads(void) ++{ ++ struct console *con; ++ int cookie; ++ ++ cookie = console_srcu_read_lock(); ++ for_each_console_srcu(con) { ++ /* ++ * Only schedule irq_work if the printing thread is ++ * actively waiting. If not waiting, the thread will ++ * notice by itself that it has work to do. ++ */ ++ if (con->kthread && rcuwait_has_sleeper(&con->rcuwait)) ++ irq_work_queue(&con->irq_work); ++ } ++ console_srcu_read_unlock(cookie); ++} ++ + /* 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; +@@ -1538,6 +1593,7 @@ void nbcon_init(struct console *con, u64 + BUG_ON(!con->pbufs); + + rcuwait_init(&con->rcuwait); ++ init_irq_work(&con->irq_work, nbcon_irq_work); + nbcon_seq_force(con, init_seq); + 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 + } + } + ++ nbcon_wake_threads(); ++ + if (do_trylock_unlock) { + /* + * The caller may be holding system-critical or +@@ -2708,6 +2710,10 @@ void resume_console(void) + */ + synchronize_srcu(&console_srcu); + ++ /* ++ * Since this runs in task context, wake the threaded printers ++ * directly rather than scheduling irq_work to do it. ++ */ + cookie = console_srcu_read_lock(); + for_each_console_srcu(con) { + flags = console_srcu_read_flags(con); +@@ -4161,6 +4167,7 @@ void defer_console_output(void) + + void printk_trigger_flush(void) + { ++ nbcon_wake_threads(); + defer_console_output(); + } + diff --git a/debian/patches-rt/0033-printk-nbcon-Introduce-printing-kthreads.patch b/debian/patches-rt/0033-printk-nbcon-Introduce-printing-kthreads.patch deleted file mode 100644 index 12f69b52fc..0000000000 --- a/debian/patches-rt/0033-printk-nbcon-Introduce-printing-kthreads.patch +++ /dev/null @@ -1,472 +0,0 @@ -From: Thomas Gleixner -Date: Fri, 22 Sep 2023 14:12:21 +0000 -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. - -Co-developed-by: John Ogness -Signed-off-by: John Ogness -Signed-off-by: Thomas Gleixner (Intel) -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - - struct vc_data; -@@ -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 -+ * @kthread: Printer kthread for this console -+ * @rcuwait: RCU-safe wait object for @kthread waking - */ - struct console { - char name[16]; -@@ -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; -+ struct task_struct *kthread; -+ struct rcuwait rcuwait; - }; - - #ifdef CONFIG_LOCKDEP ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -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 -@@ -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) -+ return false; - } else { - if (!con->write) - return false; -@@ -124,12 +127,35 @@ static inline bool console_is_usable(str - return true; - } - -+/** -+ * nbcon_kthread_wake - Wake up a printk thread -+ * @con: Console to operate on -+ */ -+static inline void nbcon_kthread_wake(struct console *con) -+{ -+ /* -+ * Guarantee any new records can be seen by tasks preparing to wait -+ * before this context checks if the rcuwait is empty. -+ * -+ * The full memory barrier in rcuwait_wake_up() pairs with the full -+ * memory barrier within set_current_state() of -+ * ___rcuwait_wait_event(), which is called after prepare_to_rcuwait() -+ * adds the waiter but before it has checked the wait condition. -+ * -+ * This pairs with nbcon_kthread_func:A. -+ */ -+ rcuwait_wake_up(&con->rcuwait); /* LMM(nbcon_kthread_wake:A) */ -+} -+ - #else - - #define PRINTK_PREFIX_MAX 0 - #define PRINTK_MESSAGE_MAX 0 - #define PRINTKRB_RECORD_MAX 0 - -+static inline void nbcon_kthread_wake(struct console *con) { } -+static inline void nbcon_kthread_create(struct console *con) { } -+ - /* - * 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 -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -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 -+ * @use_atomic: True if the write_atomic callback is to be used - * - * Return: True if this context still owns the console. False if - * ownership was handed over or taken. -@@ -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, - */ --static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt) -+static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt, bool use_atomic) - { - struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); - struct console *con = ctxt->console; -@@ -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 (use_atomic && -+ con->write_atomic) { - con->write_atomic(con, wctxt); -+ -+ } else if (!use_atomic && -+ con->write_thread) { -+ con->write_thread(con, wctxt); -+ - } else { - /* - * 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); - } - -+/** -+ * nbcon_kthread_should_wakeup - Check whether a printer thread should wakeup -+ * @con: Console to operate on -+ * @ctxt: The acquire context that contains the state -+ * at console_acquire() -+ * -+ * Return: True if the thread should shutdown or if the console is -+ * allowed to print and a record is available. False otherwise. -+ * -+ * After the thread wakes up, it must first check if it should shutdown before -+ * attempting any printing. -+ */ -+static bool nbcon_kthread_should_wakeup(struct console *con, struct nbcon_context *ctxt) -+{ -+ bool ret = false; -+ short flags; -+ int cookie; -+ -+ if (kthread_should_stop()) -+ return true; -+ -+ cookie = console_srcu_read_lock(); -+ -+ 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); -+ -+ ret = prb_read_valid(prb, ctxt->seq, NULL); -+ } -+ -+ console_srcu_read_unlock(cookie); -+ return ret; -+} -+ -+/** -+ * nbcon_kthread_func - The printer thread function -+ * @__console: Console to operate on -+ */ -+static int nbcon_kthread_func(void *__console) -+{ -+ struct console *con = __console; -+ struct nbcon_write_context wctxt = { -+ .ctxt.console = con, -+ .ctxt.prio = NBCON_PRIO_NORMAL, -+ }; -+ struct nbcon_context *ctxt = &ACCESS_PRIVATE(&wctxt, ctxt); -+ unsigned long flags; -+ short con_flags; -+ bool backlog; -+ int cookie; -+ int ret; -+ -+wait_for_event: -+ /* -+ * Guarantee this task is visible on the rcuwait before -+ * checking the wake condition. -+ * -+ * The full memory barrier within set_current_state() of -+ * ___rcuwait_wait_event() pairs with the full memory -+ * barrier within rcuwait_has_sleeper(). -+ * -+ * This pairs with rcuwait_has_sleeper:A and nbcon_kthread_wake:A. -+ */ -+ ret = rcuwait_wait_event(&con->rcuwait, -+ nbcon_kthread_should_wakeup(con, ctxt), -+ TASK_INTERRUPTIBLE); /* LMM(nbcon_kthread_func:A) */ -+ -+ if (kthread_should_stop()) -+ return 0; -+ -+ /* Wait was interrupted by a spurious signal, go back to sleep. */ -+ if (ret) -+ goto wait_for_event; -+ -+ do { -+ backlog = false; -+ -+ cookie = console_srcu_read_lock(); -+ -+ con_flags = console_srcu_read_flags(con); -+ -+ if (console_is_usable(con, con_flags)) { -+ con->device_lock(con, &flags); -+ -+ /* -+ * Ensure this stays on the CPU to make handover and -+ * takeover possible. -+ */ -+ cant_migrate(); -+ -+ if (nbcon_context_try_acquire(ctxt)) { -+ /* -+ * If the emit fails, this context is no -+ * longer the owner. -+ */ -+ if (nbcon_emit_next_record(&wctxt, false)) { -+ nbcon_context_release(ctxt); -+ backlog = ctxt->backlog; -+ } -+ } -+ -+ con->device_unlock(con, flags); -+ } -+ -+ console_srcu_read_unlock(cookie); -+ -+ } while (backlog); -+ -+ goto wait_for_event; -+} -+ - /* 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; -@@ -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 true; - - nbcon_context_release(ctxt); -@@ -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) - } - - /** -+ * nbcon_kthread_stop - Stop a printer thread -+ * @con: Console to operate on -+ */ -+static void nbcon_kthread_stop(struct console *con) -+{ -+ lockdep_assert_console_list_lock_held(); -+ -+ if (!con->kthread) -+ return; -+ -+ kthread_stop(con->kthread); -+ con->kthread = NULL; -+} -+ -+/** -+ * nbcon_kthread_create - Create a printer thread -+ * @con: Console to operate on -+ * -+ * If it fails, let the console proceed. The atomic part might -+ * be usable and useful. -+ */ -+void nbcon_kthread_create(struct console *con) -+{ -+ struct task_struct *kt; -+ -+ lockdep_assert_console_list_lock_held(); -+ -+ if (!(con->flags & CON_NBCON) || !con->write_thread) -+ return; -+ -+ if (con->kthread) -+ return; -+ -+ /* -+ * Printer threads cannot be started as long as any boot console is -+ * registered because there is no way to synchronize the hardware -+ * registers between boot console code and regular console code. -+ */ -+ if (have_boot_console) -+ return; -+ -+ kt = kthread_run(nbcon_kthread_func, con, "pr/%s%d", con->name, con->index); -+ if (IS_ERR(kt)) { -+ con_printk(KERN_ERR, con, "failed to start printing thread\n"); -+ return; -+ } -+ -+ con->kthread = kt; -+ -+ /* -+ * It is important that console printing threads are scheduled -+ * shortly after a printk call and with generous runtime budgets. -+ */ -+ sched_set_normal(con->kthread, -20); -+} -+ -+/** - * nbcon_alloc - Allocate buffers needed by the nbcon console - * @con: Console to allocate buffers for - * -@@ -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, 0); - nbcon_state_set(con, &state); - } -@@ -1285,6 +1463,7 @@ void nbcon_free(struct console *con) - { - struct nbcon_state state = { }; - -+ nbcon_kthread_stop(con); - nbcon_state_set(con, &state); - - /* Boot consoles share global printk buffers. */ ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -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; -+ short flags; -+ int cookie; - - if (!console_suspend_enabled) - return; -@@ -2714,6 +2716,14 @@ void resume_console(void) - */ - synchronize_srcu(&console_srcu); - -+ cookie = console_srcu_read_lock(); -+ for_each_console_srcu(con) { -+ flags = console_srcu_read_flags(con); -+ if (flags & CON_NBCON) -+ nbcon_kthread_wake(con); -+ } -+ console_srcu_read_unlock(cookie); -+ - pr_flush(1000, true); - } - -@@ -3034,6 +3044,13 @@ static bool console_flush_all(bool do_co - u64 printk_seq; - bool progress; - -+ /* -+ * console_flush_all() is only for legacy consoles, -+ * unless the nbcon console has no kthread printer. -+ */ -+ if ((flags & CON_NBCON) && con->kthread) -+ continue; -+ - if (!console_is_usable(con, flags)) - continue; - any_usable = true; -@@ -3327,9 +3344,23 @@ EXPORT_SYMBOL(console_stop); - - void console_start(struct console *console) - { -+ short flags; -+ - console_list_lock(); - console_srcu_write_flags(console, console->flags | CON_ENABLED); -+ flags = console->flags; - console_list_unlock(); -+ -+ /* -+ * Ensure that all SRCU list walks have completed. The related -+ * printing context must be able to see it is enabled so that -+ * it is guaranteed to wake up and resume printing. -+ */ -+ synchronize_srcu(&console_srcu); -+ -+ if (flags & CON_NBCON) -+ nbcon_kthread_wake(console); -+ - __pr_flush(console, 1000, true); - } - EXPORT_SYMBOL(console_start); diff --git a/debian/patches-rt/0034-printk-Atomic-print-in-printk-context-on-shutdown.patch b/debian/patches-rt/0034-printk-Atomic-print-in-printk-context-on-shutdown.patch deleted file mode 100644 index 68b58b5f41..0000000000 --- a/debian/patches-rt/0034-printk-Atomic-print-in-printk-context-on-shutdown.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: John Ogness -Date: Mon, 23 Oct 2023 17:43:48 +0000 -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 -printing threads may not get a chance to print the final -messages. - -When shutting down or rebooting (system_state > SYSTEM_RUNNING), -perform atomic printing from the printk() caller context. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/printk.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -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/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_pending(); -+ } - } - - if (do_trylock_unlock) { diff --git a/debian/patches-rt/0034-printk-nbcon-Stop-threads-on-shutdown-reboot.patch b/debian/patches-rt/0034-printk-nbcon-Stop-threads-on-shutdown-reboot.patch new file mode 100644 index 0000000000..83876c8f29 --- /dev/null +++ b/debian/patches-rt/0034-printk-nbcon-Stop-threads-on-shutdown-reboot.patch @@ -0,0 +1,60 @@ +From: John Ogness +Date: Tue, 26 Sep 2023 13:04:15 +0000 +Subject: [PATCH 34/46] printk: nbcon: Stop threads on shutdown/reboot +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Register a syscore_ops shutdown function to stop all threaded +printers on shutdown/reboot. This allows printk to transition back +to atomic printing in order to provide a robust mechanism for +outputting the final messages. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/nbcon.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include "internal.h" + #include "printk_ringbuffer.h" +@@ -1682,3 +1683,33 @@ void nbcon_driver_release(struct console + console_srcu_read_unlock(cookie); + } + EXPORT_SYMBOL_GPL(nbcon_driver_release); ++ ++/** ++ * printk_kthread_shutdown - shutdown all threaded printers ++ * ++ * On system shutdown all threaded printers are stopped. This allows printk ++ * to transition back to atomic printing, thus providing a robust mechanism ++ * for the final shutdown/reboot messages to be output. ++ */ ++static void printk_kthread_shutdown(void) ++{ ++ struct console *con; ++ ++ console_list_lock(); ++ for_each_console(con) { ++ if (con->flags & CON_NBCON) ++ nbcon_kthread_stop(con); ++ } ++ console_list_unlock(); ++} ++ ++static struct syscore_ops printk_syscore_ops = { ++ .shutdown = printk_kthread_shutdown, ++}; ++ ++static int __init printk_init_ops(void) ++{ ++ register_syscore_ops(&printk_syscore_ops); ++ return 0; ++} ++device_initcall(printk_init_ops); diff --git a/debian/patches-rt/0035-printk-nbcon-Add-context-to-console_is_usable.patch b/debian/patches-rt/0035-printk-nbcon-Add-context-to-console_is_usable.patch deleted file mode 100644 index bd434ec326..0000000000 --- a/debian/patches-rt/0035-printk-nbcon-Add-context-to-console_is_usable.patch +++ /dev/null @@ -1,111 +0,0 @@ -From: John Ogness -Date: Tue, 26 Sep 2023 14:43:30 +0000 -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, -console_is_usable() needs to know if it is a context that will -use the write_atomic() callback or the write_thread() callback. - -Add an extra parameter @use_atomic to specify this. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/internal.h | 16 ++++++++++------ - kernel/printk/nbcon.c | 6 +++--- - kernel/printk/printk.c | 6 ++++-- - 3 files changed, 17 insertions(+), 11 deletions(-) - ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -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. - */ --static inline bool console_is_usable(struct console *con, short flags) -+static inline bool console_is_usable(struct console *con, short flags, bool use_atomic) - { - if (!(flags & CON_ENABLED)) - return false; -@@ -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) -- return false; -+ if (use_atomic) { -+ if (!con->write_atomic) -+ return false; -+ } else { -+ if (!con->write_thread) -+ return false; -+ } - } else { - if (!con->write) - return false; -@@ -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; } -+static inline bool console_is_usable(struct console *con, short flags, -+ bool use_atomic) { return false; } - - #endif /* CONFIG_PRINTK */ - ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -968,7 +968,7 @@ static bool nbcon_kthread_should_wakeup( - cookie = console_srcu_read_lock(); - - flags = console_srcu_read_flags(con); -- 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); - -@@ -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->device_lock(con, &flags); - - /* -@@ -1246,7 +1246,7 @@ static void __nbcon_atomic_flush_pending - if (!(flags & CON_NBCON)) - continue; - -- if (!console_is_usable(con, flags)) -+ if (!console_is_usable(con, flags, true)) - continue; - - if (nbcon_seq_read(con) >= stop_seq) ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -3056,7 +3056,7 @@ static bool console_flush_all(bool do_co - if ((flags & CON_NBCON) && con->kthread) - continue; - -- if (!console_is_usable(con, flags)) -+ if (!console_is_usable(con, flags, true)) - continue; - any_usable = true; - -@@ -3991,8 +3991,10 @@ static bool __pr_flush(struct console *c - * that they make forward progress, so only increment - * @diff for usable consoles. - */ -- if (!console_is_usable(c, flags)) -+ if (!console_is_usable(c, flags, true) && -+ !console_is_usable(c, flags, false)) { - continue; -+ } - - if (flags & CON_NBCON) { - printk_seq = nbcon_seq_read(c); diff --git a/debian/patches-rt/0035-printk-nbcon-Start-printing-threads.patch b/debian/patches-rt/0035-printk-nbcon-Start-printing-threads.patch new file mode 100644 index 0000000000..c475c1f51c --- /dev/null +++ b/debian/patches-rt/0035-printk-nbcon-Start-printing-threads.patch @@ -0,0 +1,135 @@ +From: John Ogness +Date: Tue, 5 Dec 2023 14:09:31 +0000 +Subject: [PATCH 35/46] printk: nbcon: Start printing threads +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +If there are no boot consoles, the printing threads are started +in early_initcall. + +If there are boot consoles, the printing threads are started +after the last boot console has unregistered. The printing +threads do not need to be concerned about boot consoles because +boot consoles cannot register once a non-boot console has +registered. + +Until a printing thread of a console has started, that console +will print using atomic_write() in the printk() caller context. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 2 ++ + kernel/printk/nbcon.c | 18 +++++++++++++++++- + kernel/printk/printk.c | 14 ++++++++++++++ + 3 files changed, 33 insertions(+), 1 deletion(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -48,6 +48,7 @@ struct printk_ringbuffer; + struct dev_printk_info; + + extern struct printk_ringbuffer *prb; ++extern bool printk_threads_enabled; + + __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) + + /* + * In !PRINTK builds we still export console_sem +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -213,6 +213,8 @@ static void nbcon_seq_try_update(struct + } + } + ++bool printk_threads_enabled __ro_after_init; ++ + /** + * nbcon_context_try_acquire_direct - Try to acquire directly + * @ctxt: The context of the caller +@@ -1522,7 +1524,7 @@ void nbcon_kthread_create(struct console + if (!(con->flags & CON_NBCON) || !con->write_thread) + return; + +- if (con->kthread) ++ if (!printk_threads_enabled || con->kthread) + return; + + /* +@@ -1548,6 +1550,19 @@ void nbcon_kthread_create(struct console + sched_set_normal(con->kthread, -20); + } + ++static int __init printk_setup_threads(void) ++{ ++ struct console *con; ++ ++ console_list_lock(); ++ printk_threads_enabled = true; ++ for_each_console(con) ++ nbcon_kthread_create(con); ++ console_list_unlock(); ++ return 0; ++} ++early_initcall(printk_setup_threads); ++ + /** + * nbcon_alloc - Allocate buffers needed by the nbcon console + * @con: Console to allocate buffers for +@@ -1597,6 +1612,7 @@ void nbcon_init(struct console *con, u64 + init_irq_work(&con->irq_work, nbcon_irq_work); + nbcon_seq_force(con, init_seq); + nbcon_state_set(con, &state); ++ nbcon_kthread_create(con); + } + + /** +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2389,6 +2389,9 @@ asmlinkage int vprintk_emit(int facility + * + * - When this CPU is in panic. + * ++ * - When booting, before the printing threads have been ++ * started. ++ * + * - 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 + * consoles cannot print simultaneously with boot consoles. + */ + if (is_panic_context || ++ !printk_threads_enabled || + (system_state > SYSTEM_RUNNING)) { + nbcon_atomic_flush_pending(); + } +@@ -3725,6 +3729,7 @@ EXPORT_SYMBOL(register_console); + /* Must be called under console_list_lock(). */ + static int unregister_console_locked(struct console *console) + { ++ bool is_boot_con = (console->flags & CON_BOOT); + bool found_legacy_con = false; + bool found_nbcon_con = false; + bool found_boot_con = false; +@@ -3807,6 +3812,15 @@ static int unregister_console_locked(str + if (!found_nbcon_con) + have_nbcon_console = found_nbcon_con; + ++ /* ++ * When the last boot console unregisters, start up the ++ * printing threads. ++ */ ++ if (is_boot_con && !have_boot_console) { ++ for_each_console(c) ++ nbcon_kthread_create(c); ++ } ++ + return res; + } + diff --git a/debian/patches-rt/0036-printk-Provide-helper-for-message-prepending.patch b/debian/patches-rt/0036-printk-Provide-helper-for-message-prepending.patch new file mode 100644 index 0000000000..97530d96f9 --- /dev/null +++ b/debian/patches-rt/0036-printk-Provide-helper-for-message-prepending.patch @@ -0,0 +1,82 @@ +From: John Ogness +Date: Thu, 28 Mar 2024 13:29:10 +0000 +Subject: [PATCH 36/46] printk: Provide helper for message prepending +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/printk.c | 38 +++++++++++++++++++++++++++----------- + 1 file changed, 27 insertions(+), 11 deletions(-) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2806,30 +2806,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. +@@ -2852,6 +2847,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/0036-printk-nbcon-Add-printer-thread-wakeups.patch b/debian/patches-rt/0036-printk-nbcon-Add-printer-thread-wakeups.patch deleted file mode 100644 index 81701b90f0..0000000000 --- a/debian/patches-rt/0036-printk-nbcon-Add-printer-thread-wakeups.patch +++ /dev/null @@ -1,164 +0,0 @@ -From: Thomas Gleixner -Date: Tue, 26 Sep 2023 13:03:52 +0000 -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: - - - records are added to the printk ringbuffer - - consoles are resumed - - triggered via printk_trigger_flush() - -The actual waking is performed via irq_work so that the wakeup can -be triggered from any context. - -Co-developed-by: John Ogness -Signed-off-by: John Ogness -Signed-off-by: Thomas Gleixner (Intel) -Signed-off-by: Sebastian Andrzej Siewior ---- - include/linux/console.h | 3 ++ - kernel/printk/internal.h | 1 - kernel/printk/nbcon.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ - kernel/printk/printk.c | 7 +++++ - 4 files changed, 67 insertions(+) - ---- a/include/linux/console.h -+++ b/include/linux/console.h -@@ -16,6 +16,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -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]; -@@ -457,6 +459,7 @@ struct console { - struct printk_buffers *pbufs; - struct task_struct *kthread; - struct rcuwait rcuwait; -+ struct irq_work irq_work; - }; - - #ifdef CONFIG_LOCKDEP ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -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); - - /* - * Check if the given console is currently capable and allowed to print ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -1056,6 +1056,61 @@ static int nbcon_kthread_func(void *__co - goto wait_for_event; - } - -+/** -+ * nbcon_irq_work - irq work to wake printk thread -+ * @irq_work: The irq work to operate on -+ */ -+static void nbcon_irq_work(struct irq_work *irq_work) -+{ -+ struct console *con = container_of(irq_work, struct console, irq_work); -+ -+ nbcon_kthread_wake(con); -+} -+ -+static inline bool rcuwait_has_sleeper(struct rcuwait *w) -+{ -+ bool has_sleeper; -+ -+ rcu_read_lock(); -+ /* -+ * Guarantee any new records can be seen by tasks preparing to wait -+ * before this context checks if the rcuwait is empty. -+ * -+ * This full memory barrier pairs with the full memory barrier within -+ * set_current_state() of ___rcuwait_wait_event(), which is called -+ * after prepare_to_rcuwait() adds the waiter but before it has -+ * checked the wait condition. -+ * -+ * This pairs with nbcon_kthread_func:A. -+ */ -+ smp_mb(); /* LMM(rcuwait_has_sleeper:A) */ -+ has_sleeper = !!rcu_dereference(w->task); -+ rcu_read_unlock(); -+ -+ return has_sleeper; -+} -+ -+/** -+ * nbcon_wake_threads - Wake up printing threads using irq_work -+ */ -+void nbcon_wake_threads(void) -+{ -+ struct console *con; -+ int cookie; -+ -+ cookie = console_srcu_read_lock(); -+ for_each_console_srcu(con) { -+ /* -+ * Only schedule irq_work if the printing thread is -+ * actively waiting. If not waiting, the thread will -+ * notice by itself that it has work to do. -+ */ -+ if (con->kthread && rcuwait_has_sleeper(&con->rcuwait)) -+ irq_work_queue(&con->irq_work); -+ } -+ console_srcu_read_unlock(cookie); -+} -+ - /* 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; -@@ -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, 0); - nbcon_state_set(con, &state); - } ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -2415,6 +2415,8 @@ asmlinkage int vprintk_emit(int facility - } - } - -+ nbcon_wake_threads(); -+ - if (do_trylock_unlock) { - /* - * The caller may be holding system-critical or -@@ -2721,6 +2723,10 @@ void resume_console(void) - */ - synchronize_srcu(&console_srcu); - -+ /* -+ * Since this runs in task context, wake the threaded printers -+ * directly rather than scheduling irq_work to do it. -+ */ - cookie = console_srcu_read_lock(); - for_each_console_srcu(con) { - flags = console_srcu_read_flags(con); -@@ -4151,6 +4157,7 @@ void defer_console_output(void) - - void printk_trigger_flush(void) - { -+ nbcon_wake_threads(); - defer_console_output(); - } - diff --git a/debian/patches-rt/0037-printk-nbcon-Show-replay-message-on-takeover.patch b/debian/patches-rt/0037-printk-nbcon-Show-replay-message-on-takeover.patch new file mode 100644 index 0000000000..87b2799c12 --- /dev/null +++ b/debian/patches-rt/0037-printk-nbcon-Show-replay-message-on-takeover.patch @@ -0,0 +1,136 @@ +From: John Ogness +Date: Mon, 25 Mar 2024 21:00:40 +0000 +Subject: [PATCH 37/46] printk: nbcon: Show replay message on takeover +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Signed-off-by: Sebastian Andrzej Siewior +--- + include/linux/console.h | 3 +++ + kernel/printk/internal.h | 1 + + kernel/printk/nbcon.c | 24 ++++++++++++++++++++++++ + kernel/printk/printk.c | 19 +++++++++++++++++++ + 4 files changed, 47 insertions(+) + +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -325,6 +325,7 @@ struct nbcon_write_context { + * @nbcon_state: State for nbcon consoles + * @nbcon_seq: Sequence number of the next record for nbcon to print + * @nbcon_driver_ctxt: Context available for driver non-printing operations ++ * @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 +@@ -445,6 +446,8 @@ struct console { + atomic_t __private nbcon_state; + atomic_long_t __private nbcon_seq; + struct nbcon_context __private nbcon_driver_ctxt; ++ atomic_long_t __private nbcon_prev_seq; ++ + struct printk_buffers *pbufs; + struct task_struct *kthread; + struct rcuwait rcuwait; +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -231,4 +231,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; + +@@ -1611,6 +1634,7 @@ void nbcon_init(struct console *con, u64 + rcuwait_init(&con->rcuwait); + init_irq_work(&con->irq_work, nbcon_irq_work); + nbcon_seq_force(con, init_seq); ++ 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 +@@ -2868,6 +2868,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/0037-printk-nbcon-Stop-threads-on-shutdown-reboot.patch b/debian/patches-rt/0037-printk-nbcon-Stop-threads-on-shutdown-reboot.patch deleted file mode 100644 index 28fccd7fc7..0000000000 --- a/debian/patches-rt/0037-printk-nbcon-Stop-threads-on-shutdown-reboot.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: John Ogness -Date: Tue, 26 Sep 2023 13:04:15 +0000 -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 -to atomic printing in order to provide a robust mechanism for -outputting the final messages. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/nbcon.c | 31 +++++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include "internal.h" - #include "printk_ringbuffer.h" -@@ -1577,3 +1578,33 @@ void nbcon_driver_release(struct console - nbcon_context_release(ctxt); - } - EXPORT_SYMBOL_GPL(nbcon_driver_release); -+ -+/** -+ * printk_kthread_shutdown - shutdown all threaded printers -+ * -+ * On system shutdown all threaded printers are stopped. This allows printk -+ * to transition back to atomic printing, thus providing a robust mechanism -+ * for the final shutdown/reboot messages to be output. -+ */ -+static void printk_kthread_shutdown(void) -+{ -+ struct console *con; -+ -+ console_list_lock(); -+ for_each_console(con) { -+ if (con->flags & CON_NBCON) -+ nbcon_kthread_stop(con); -+ } -+ console_list_unlock(); -+} -+ -+static struct syscore_ops printk_syscore_ops = { -+ .shutdown = printk_kthread_shutdown, -+}; -+ -+static int __init printk_init_ops(void) -+{ -+ register_syscore_ops(&printk_syscore_ops); -+ return 0; -+} -+device_initcall(printk_init_ops); diff --git a/debian/patches-rt/0038-printk-nbcon-Start-printing-threads.patch b/debian/patches-rt/0038-printk-nbcon-Start-printing-threads.patch deleted file mode 100644 index 63aae75ebb..0000000000 --- a/debian/patches-rt/0038-printk-nbcon-Start-printing-threads.patch +++ /dev/null @@ -1,135 +0,0 @@ -From: John Ogness -Date: Tue, 5 Dec 2023 14:09:31 +0000 -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. - -If there are boot consoles, the printing threads are started -after the last boot console has unregistered. The printing -threads do not need to be concerned about boot consoles because -boot consoles cannot register once a non-boot console has -registered. - -Until a printing thread of a console has started, that console -will print using atomic_write() in the printk() caller context. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - kernel/printk/internal.h | 2 ++ - kernel/printk/nbcon.c | 18 +++++++++++++++++- - kernel/printk/printk.c | 14 ++++++++++++++ - 3 files changed, 33 insertions(+), 1 deletion(-) - ---- a/kernel/printk/internal.h -+++ b/kernel/printk/internal.h -@@ -48,6 +48,7 @@ struct printk_ringbuffer; - struct dev_printk_info; - - extern struct printk_ringbuffer *prb; -+extern bool printk_threads_enabled; - - __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) - - /* - * In !PRINTK builds we still export console_sem ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -213,6 +213,8 @@ static void nbcon_seq_try_update(struct - } - } - -+bool printk_threads_enabled __ro_after_init; -+ - /** - * nbcon_context_try_acquire_direct - Try to acquire directly - * @ctxt: The context of the caller -@@ -1436,7 +1438,7 @@ void nbcon_kthread_create(struct console - if (!(con->flags & CON_NBCON) || !con->write_thread) - return; - -- if (con->kthread) -+ if (!printk_threads_enabled || con->kthread) - return; - - /* -@@ -1462,6 +1464,19 @@ void nbcon_kthread_create(struct console - sched_set_normal(con->kthread, -20); - } - -+static int __init printk_setup_threads(void) -+{ -+ struct console *con; -+ -+ console_list_lock(); -+ printk_threads_enabled = true; -+ for_each_console(con) -+ nbcon_kthread_create(con); -+ console_list_unlock(); -+ return 0; -+} -+early_initcall(printk_setup_threads); -+ - /** - * nbcon_alloc - Allocate buffers needed by the nbcon console - * @con: Console to allocate buffers for -@@ -1510,6 +1525,7 @@ void nbcon_init(struct console *con) - init_irq_work(&con->irq_work, nbcon_irq_work); - nbcon_seq_force(con, 0); - nbcon_state_set(con, &state); -+ nbcon_kthread_create(con); - } - - /** ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -2402,6 +2402,9 @@ asmlinkage int vprintk_emit(int facility - * - * - When this CPU is in panic. - * -+ * - When booting, before the printing threads have been -+ * started. -+ * - * - During shutdown, since the printing threads may not get - * a chance to print the final messages. - * -@@ -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_pending(); - } -@@ -3726,6 +3730,7 @@ EXPORT_SYMBOL(register_console); - /* Must be called under console_list_lock(). */ - static int unregister_console_locked(struct console *console) - { -+ bool is_boot_con = (console->flags & CON_BOOT); - bool found_legacy_con = false; - bool found_nbcon_con = false; - bool found_boot_con = false; -@@ -3797,6 +3802,15 @@ static int unregister_console_locked(str - if (!found_nbcon_con) - have_nbcon_console = found_nbcon_con; - -+ /* -+ * When the last boot console unregisters, start up the -+ * printing threads. -+ */ -+ if (is_boot_con && !have_boot_console) { -+ for_each_console(c) -+ nbcon_kthread_create(c); -+ } -+ - return res; - } - diff --git a/debian/patches-rt/0038-proc-consoles-Add-notation-to-c_start-c_stop.patch b/debian/patches-rt/0038-proc-consoles-Add-notation-to-c_start-c_stop.patch new file mode 100644 index 0000000000..691c1a2b80 --- /dev/null +++ b/debian/patches-rt/0038-proc-consoles-Add-notation-to-c_start-c_stop.patch @@ -0,0 +1,34 @@ +From: John Ogness +Date: Thu, 2 May 2024 08:02:58 +0000 +Subject: [PATCH 38/46] proc: consoles: Add notation to c_start/c_stop +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +fs/proc/consoles.c:78:13: warning: context imbalance in 'c_start' + - wrong count at exit +fs/proc/consoles.c:104:13: warning: context imbalance in 'c_stop' + - unexpected unlock + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + fs/proc/consoles.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/proc/consoles.c ++++ b/fs/proc/consoles.c +@@ -68,6 +68,7 @@ static int show_console_dev(struct seq_f + } + + static void *c_start(struct seq_file *m, loff_t *pos) ++ __acquires(&console_mutex) + { + struct console *con; + loff_t off = 0; +@@ -94,6 +95,7 @@ static void *c_next(struct seq_file *m, + } + + static void c_stop(struct seq_file *m, void *v) ++ __releases(&console_mutex) + { + console_list_unlock(); + } 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 deleted file mode 100644 index 35bfe33e7a..0000000000 --- a/debian/patches-rt/0039-printk-Provide-helper-for-message-prepending.patch +++ /dev/null @@ -1,82 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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/0039-proc-Add-nbcon-support-for-proc-consoles.patch b/debian/patches-rt/0039-proc-Add-nbcon-support-for-proc-consoles.patch new file mode 100644 index 0000000000..68a1df972d --- /dev/null +++ b/debian/patches-rt/0039-proc-Add-nbcon-support-for-proc-consoles.patch @@ -0,0 +1,53 @@ +From: John Ogness +Date: Tue, 26 Sep 2023 13:31:00 +0000 +Subject: [PATCH 39/46] proc: Add nbcon support for /proc/consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Update /proc/consoles output to show 'W' if an nbcon write +callback is implemented (write_atomic or write_thread). + +Also update /proc/consoles output to show 'N' if it is an +nbcon console. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + fs/proc/consoles.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/fs/proc/consoles.c ++++ b/fs/proc/consoles.c +@@ -21,12 +21,14 @@ static int show_console_dev(struct seq_f + { CON_ENABLED, 'E' }, + { CON_CONSDEV, 'C' }, + { CON_BOOT, 'B' }, ++ { CON_NBCON, 'N' }, + { CON_PRINTBUFFER, 'p' }, + { CON_BRL, 'b' }, + { CON_ANYTIME, 'a' }, + }; + char flags[ARRAY_SIZE(con_flags) + 1]; + struct console *con = v; ++ char con_write = '-'; + unsigned int a; + dev_t dev = 0; + +@@ -57,9 +59,15 @@ static int show_console_dev(struct seq_f + seq_setwidth(m, 21 - 1); + seq_printf(m, "%s%d", con->name, con->index); + seq_pad(m, ' '); +- seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-', +- con->write ? 'W' : '-', con->unblank ? 'U' : '-', +- flags); ++ if (con->flags & CON_NBCON) { ++ if (con->write_atomic || con->write_thread) ++ con_write = 'W'; ++ } else { ++ if (con->write) ++ con_write = 'W'; ++ } ++ seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-', con_write, ++ con->unblank ? 'U' : '-', flags); + if (dev) + seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev)); + 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 deleted file mode 100644 index ab1046954b..0000000000 --- a/debian/patches-rt/0040-printk-nbcon-Show-replay-message-on-takeover.patch +++ /dev/null @@ -1,135 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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/0040-tty-sysfs-Add-nbcon-support-for-active.patch b/debian/patches-rt/0040-tty-sysfs-Add-nbcon-support-for-active.patch new file mode 100644 index 0000000000..2f90024cc8 --- /dev/null +++ b/debian/patches-rt/0040-tty-sysfs-Add-nbcon-support-for-active.patch @@ -0,0 +1,31 @@ +From: John Ogness +Date: Fri, 22 Sep 2023 14:31:09 +0000 +Subject: [PATCH 40/46] tty: sysfs: Add nbcon support for 'active' +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Allow the 'active' attribute to list nbcon consoles. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + 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 +@@ -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) ++ continue; ++ } else { ++ if (!c->write) ++ continue; ++ } + if ((c->flags & CON_ENABLED) == 0) + continue; + cs[i++] = c; diff --git a/debian/patches-rt/0041-printk-nbcon-Provide-function-to-reacquire-ownership.patch b/debian/patches-rt/0041-printk-nbcon-Provide-function-to-reacquire-ownership.patch new file mode 100644 index 0000000000..a9fb9f35cc --- /dev/null +++ b/debian/patches-rt/0041-printk-nbcon-Provide-function-to-reacquire-ownership.patch @@ -0,0 +1,120 @@ +From: John Ogness +Date: Fri, 20 Oct 2023 10:01:58 +0000 +Subject: [PATCH 41/46] printk: nbcon: Provide function to reacquire ownership +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Contexts may become nbcon owners for various reasons, not just +for printing. Indeed, the port->lock wrapper takes ownership +for anything relating to the hardware. + +Since ownership can be lost at any time due to handover or +takeover, a context _should_ be prepared to back out +immediately and carefully. However, there are many scenarios +where the context _must_ reacquire ownership in order to +finalize or revert hardware changes. + +One such example is when interrupts are disabled by a context. +No other context will automagically re-enable the interrupts. +For this case, the disabling context _must_ reacquire nbcon +ownership so that it can re-enable the interrupts. + +Provide nbcon_reacquire() for exactly this purpose. + +Note that for printing contexts, after a successful reacquire +the context will have no output buffer because that has been +lost. nbcon_reacquire() cannot be used to resume printing. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + 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 +@@ -373,6 +373,11 @@ struct console { + * The callback should allow the takeover whenever it is safe. It + * increases the chance to see messages when the system is in trouble. + * ++ * 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. ++ * + * The 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. +@@ -591,6 +596,7 @@ extern void nbcon_cpu_emergency_flush(vo + 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); ++extern void nbcon_reacquire(struct nbcon_write_context *wctxt); + #else + static inline void nbcon_cpu_emergency_enter(void) { } + static inline void nbcon_cpu_emergency_exit(void) { } +@@ -598,6 +604,7 @@ static inline void nbcon_cpu_emergency_f + 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; } ++static inline void nbcon_reacquire(struct nbcon_write_context *wctxt) { } + #endif + + extern int console_set_on_cmdline; +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -839,6 +839,38 @@ bool nbcon_exit_unsafe(struct nbcon_writ + EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); + + /** ++ * nbcon_reacquire - Reacquire a console after losing ownership ++ * @wctxt: The write context that was handed to the write function ++ * ++ * Since ownership can be lost at any time due to handover or takeover, a ++ * printing context _should_ be prepared to back out immediately and ++ * carefully. However, there are many scenarios where the context _must_ ++ * reacquire ownership in order to finalize or revert hardware changes. ++ * ++ * This function allows a context to reacquire ownership using the same ++ * priority as its previous ownership. ++ * ++ * Note that for printing contexts, after a successful reacquire the ++ * context will have no output buffer because that has been lost. This ++ * function cannot be used to resume printing. ++ */ ++void nbcon_reacquire(struct nbcon_write_context *wctxt) ++{ ++ struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); ++ struct console *con = ctxt->console; ++ struct nbcon_state cur; ++ ++ while (!nbcon_context_try_acquire(ctxt)) ++ cpu_relax(); ++ ++ wctxt->outbuf = NULL; ++ wctxt->len = 0; ++ nbcon_state_read(con, &cur); ++ wctxt->unsafe_takeover = cur.unsafe_takeover; ++} ++EXPORT_SYMBOL_GPL(nbcon_reacquire); ++ ++/** + * 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/0041-proc-Add-nbcon-support-for-proc-consoles.patch b/debian/patches-rt/0041-proc-Add-nbcon-support-for-proc-consoles.patch deleted file mode 100644 index edae68d991..0000000000 --- a/debian/patches-rt/0041-proc-Add-nbcon-support-for-proc-consoles.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: John Ogness -Date: Tue, 26 Sep 2023 13:31:00 +0000 -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). - -Also update /proc/consoles output to show 'N' if it is an -nbcon console. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - fs/proc/consoles.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - ---- a/fs/proc/consoles.c -+++ b/fs/proc/consoles.c -@@ -21,12 +21,14 @@ static int show_console_dev(struct seq_f - { CON_ENABLED, 'E' }, - { CON_CONSDEV, 'C' }, - { CON_BOOT, 'B' }, -+ { CON_NBCON, 'N' }, - { CON_PRINTBUFFER, 'p' }, - { CON_BRL, 'b' }, - { CON_ANYTIME, 'a' }, - }; - char flags[ARRAY_SIZE(con_flags) + 1]; - struct console *con = v; -+ char con_write = '-'; - unsigned int a; - dev_t dev = 0; - -@@ -57,9 +59,15 @@ static int show_console_dev(struct seq_f - seq_setwidth(m, 21 - 1); - seq_printf(m, "%s%d", con->name, con->index); - seq_pad(m, ' '); -- seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-', -- con->write ? 'W' : '-', con->unblank ? 'U' : '-', -- flags); -+ if (con->flags & CON_NBCON) { -+ if (con->write_atomic || con->write_thread) -+ con_write = 'W'; -+ } else { -+ if (con->write) -+ con_write = 'W'; -+ } -+ seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-', con_write, -+ con->unblank ? 'U' : '-', flags); - if (dev) - seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev)); - diff --git a/debian/patches-rt/0042-serial-8250-Switch-to-nbcon-console.patch b/debian/patches-rt/0042-serial-8250-Switch-to-nbcon-console.patch new file mode 100644 index 0000000000..5f9d30af5d --- /dev/null +++ b/debian/patches-rt/0042-serial-8250-Switch-to-nbcon-console.patch @@ -0,0 +1,334 @@ +From: John Ogness +Date: Wed, 13 Sep 2023 15:30:36 +0000 +Subject: [PATCH 42/46] serial: 8250: Switch to nbcon console +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Implement the necessary callbacks to switch the 8250 console driver +to perform as an nbcon console. + +Add implementations for the nbcon console callbacks (write_atomic, +write_thread, device_lock, device_unlock) 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. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/tty/serial/8250/8250_core.c | 42 +++++++++ + drivers/tty/serial/8250/8250_port.c | 154 +++++++++++++++++++++++++++++++++++- + include/linux/serial_8250.h | 6 + + 3 files changed, 199 insertions(+), 3 deletions(-) + +--- a/drivers/tty/serial/8250/8250_core.c ++++ b/drivers/tty/serial/8250/8250_core.c +@@ -592,6 +592,7 @@ serial8250_register_ports(struct uart_dr + + #ifdef CONFIG_SERIAL_8250_CONSOLE + ++#ifdef CONFIG_SERIAL_8250_LEGACY_CONSOLE + static void univ8250_console_write(struct console *co, const char *s, + unsigned int count) + { +@@ -599,6 +600,37 @@ static void univ8250_console_write(struc + + serial8250_console_write(up, s, count); + } ++#else ++static void univ8250_console_write_atomic(struct console *co, ++ struct nbcon_write_context *wctxt) ++{ ++ struct uart_8250_port *up = &serial8250_ports[co->index]; ++ ++ serial8250_console_write_atomic(up, wctxt); ++} ++ ++static void univ8250_console_write_thread(struct console *co, ++ struct nbcon_write_context *wctxt) ++{ ++ struct uart_8250_port *up = &serial8250_ports[co->index]; ++ ++ serial8250_console_write_thread(up, wctxt); ++} ++ ++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_device_unlock(struct console *con, unsigned long flags) ++{ ++ struct uart_port *up = &serial8250_ports[con->index].port; ++ ++ __uart_port_unlock_irqrestore(up, flags); ++} ++#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 + + static struct console univ8250_console = { + .name = "ttyS", ++#ifdef CONFIG_SERIAL_8250_LEGACY_CONSOLE + .write = univ8250_console_write, ++ .flags = CON_PRINTBUFFER | CON_ANYTIME, ++#else ++ .write_atomic = univ8250_console_write_atomic, ++ .write_thread = univ8250_console_write_thread, ++ .device_lock = univ8250_console_device_lock, ++ .device_unlock = univ8250_console_device_unlock, ++ .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON, ++#endif + .device = uart_console_device, + .setup = univ8250_console_setup, + .exit = univ8250_console_exit, + .match = univ8250_console_match, +- .flags = CON_PRINTBUFFER | CON_ANYTIME, + .index = -1, + .data = &serial8250_reg, + }; +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -546,6 +546,13 @@ static int serial8250_em485_init(struct + if (!p->em485) + return -ENOMEM; + ++#ifndef CONFIG_SERIAL_8250_LEGACY_CONSOLE ++ 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, +@@ -698,7 +705,11 @@ static void serial8250_set_sleep(struct + serial8250_rpm_put(p); + } + +-static void serial8250_clear_IER(struct uart_8250_port *up) ++/* ++ * Only to be used by write_atomic() and the legacy write(), which do not ++ * require port lock. ++ */ ++static void __serial8250_clear_IER(struct uart_8250_port *up) + { + if (up->capabilities & UART_CAP_UUE) + serial_out(up, UART_IER, UART_IER_UUE); +@@ -706,6 +717,11 @@ static void serial8250_clear_IER(struct + serial_out(up, UART_IER, 0); + } + ++static inline void serial8250_clear_IER(struct uart_8250_port *up) ++{ ++ __serial8250_clear_IER(up); ++} ++ + #ifdef CONFIG_SERIAL_8250_RSA + /* + * Attempts to turn on the RSA FIFO. Returns zero on failure. +@@ -3272,6 +3288,11 @@ static void serial8250_console_putchar(s + + wait_for_xmitr(up, UART_LSR_THRE); + serial_port_out(port, UART_TX, ch); ++ ++ if (ch == '\n') ++ up->console_newline_needed = false; ++ else ++ up->console_newline_needed = true; + } + + /* +@@ -3300,6 +3321,7 @@ static void serial8250_console_restore(s + serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); + } + ++#ifdef CONFIG_SERIAL_8250_LEGACY_CONSOLE + /* + * Print a string to the serial port using the device FIFO + * +@@ -3358,7 +3380,7 @@ void serial8250_console_write(struct uar + * First save the IER then disable the interrupts + */ + ier = serial_port_in(port, UART_IER); +- serial8250_clear_IER(up); ++ __serial8250_clear_IER(up); + + /* check scratch reg to see if port powered off during system sleep */ + if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { +@@ -3424,6 +3446,131 @@ void serial8250_console_write(struct uar + if (locked) + uart_port_unlock_irqrestore(port, flags); + } ++#else ++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; ++ unsigned int ier; ++ ++ touch_nmi_watchdog(); ++ ++ if (!nbcon_enter_unsafe(wctxt)) ++ return; ++ ++ /* First save IER then disable the interrupts. */ ++ ier = serial_port_in(port, UART_IER); ++ serial8250_clear_IER(up); ++ ++ /* Check scratch reg if port powered off during system sleep. */ ++ if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { ++ serial8250_console_restore(up); ++ up->canary = 0; ++ } ++ ++ if (em485) { ++ if (em485->tx_stopped) ++ up->rs485_start_tx(up); ++ mdelay(port->rs485.delay_rts_before_send); ++ } ++ ++ if (nbcon_exit_unsafe(wctxt)) { ++ int len = READ_ONCE(wctxt->len); ++ int i; ++ ++ /* ++ * Write out the message. Toggle unsafe for each byte in order ++ * to give another (higher priority) context the opportunity ++ * for a friendly takeover. If such a takeover occurs, this ++ * context must reacquire ownership in order to perform final ++ * actions (such as re-enabling the interrupts). ++ * ++ * IMPORTANT: wctxt->outbuf and wctxt->len are no longer valid ++ * after a reacquire so writing the message must be ++ * aborted. ++ */ ++ for (i = 0; i < len; i++) { ++ if (!nbcon_enter_unsafe(wctxt)) { ++ nbcon_reacquire(wctxt); ++ break; ++ } ++ ++ uart_console_write(port, wctxt->outbuf + i, 1, serial8250_console_putchar); ++ ++ if (!nbcon_exit_unsafe(wctxt)) { ++ nbcon_reacquire(wctxt); ++ break; ++ } ++ } ++ } else { ++ nbcon_reacquire(wctxt); ++ } ++ ++ while (!nbcon_enter_unsafe(wctxt)) ++ nbcon_reacquire(wctxt); ++ ++ /* Finally, wait for transmitter to become empty and restore IER. */ ++ wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); ++ if (em485) { ++ mdelay(port->rs485.delay_rts_after_send); ++ if (em485->tx_stopped) ++ up->rs485_stop_tx(up); ++ } ++ serial_port_out(port, UART_IER, ier); ++ ++ /* ++ * The receive handling will happen properly because the receive ready ++ * bit will still be set; it is not cleared on read. However, modem ++ * control will not, we must call it if we have saved something in the ++ * saved flags while processing with interrupts off. ++ */ ++ if (up->msr_saved_flags) ++ serial8250_modem_status(up); ++ ++ nbcon_exit_unsafe(wctxt); ++} ++ ++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 (WARN_ON_ONCE(up->em485)) ++ return; ++ ++ touch_nmi_watchdog(); ++ ++ if (!nbcon_enter_unsafe(wctxt)) ++ return; ++ ++ /* ++ * First save IER then disable the interrupts. The special variant to ++ * clear IER is used because atomic printing may occur without holding ++ * the port lock. ++ */ ++ ier = serial_port_in(port, UART_IER); ++ __serial8250_clear_IER(up); ++ ++ /* Check scratch reg if port powered off during system sleep. */ ++ if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { ++ serial8250_console_restore(up); ++ up->canary = 0; ++ } ++ ++ if (up->console_newline_needed) ++ uart_console_write(port, "\n", 1, serial8250_console_putchar); ++ uart_console_write(port, wctxt->outbuf, wctxt->len, serial8250_console_putchar); ++ ++ /* Finally, wait for transmitter to become empty and restore IER. */ ++ wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); ++ serial_port_out(port, UART_IER, ier); ++ ++ nbcon_exit_unsafe(wctxt); ++} ++#endif /* CONFIG_SERIAL_8250_LEGACY_CONSOLE */ + + static unsigned int probe_baud(struct uart_port *port) + { +@@ -3442,6 +3589,7 @@ static unsigned int probe_baud(struct ua + + int serial8250_console_setup(struct uart_port *port, char *options, bool probe) + { ++ struct uart_8250_port *up = up_to_u8250p(port); + int baud = 9600; + int bits = 8; + int parity = 'n'; +@@ -3451,6 +3599,8 @@ int serial8250_console_setup(struct uart + if (!port->iobase && !port->membase) + return -ENODEV; + ++ up->console_newline_needed = false; ++ + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + else if (probe) +--- a/include/linux/serial_8250.h ++++ b/include/linux/serial_8250.h +@@ -153,6 +153,8 @@ struct uart_8250_port { + #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA + unsigned char msr_saved_flags; + ++ bool console_newline_needed; ++ + struct uart_8250_dma *dma; + const struct uart_8250_ops *ops; + +@@ -204,6 +206,10 @@ void serial8250_init_port(struct uart_82 + void serial8250_set_defaults(struct uart_8250_port *up); + void serial8250_console_write(struct uart_8250_port *up, const char *s, + unsigned int count); ++void serial8250_console_write_atomic(struct uart_8250_port *up, ++ struct nbcon_write_context *wctxt); ++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/0042-tty-sysfs-Add-nbcon-support-for-active.patch b/debian/patches-rt/0042-tty-sysfs-Add-nbcon-support-for-active.patch deleted file mode 100644 index 0c5dc15561..0000000000 --- a/debian/patches-rt/0042-tty-sysfs-Add-nbcon-support-for-active.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: John Ogness -Date: Fri, 22 Sep 2023 14:31:09 +0000 -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 -@@ -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) -+ continue; -+ } else { -+ if (!c->write) -+ continue; -+ } - if ((c->flags & CON_ENABLED) == 0) - continue; - cs[i++] = c; diff --git a/debian/patches-rt/0043-printk-nbcon-Provide-function-to-reacquire-ownership.patch b/debian/patches-rt/0043-printk-nbcon-Provide-function-to-reacquire-ownership.patch deleted file mode 100644 index 5dd9fe97d7..0000000000 --- a/debian/patches-rt/0043-printk-nbcon-Provide-function-to-reacquire-ownership.patch +++ /dev/null @@ -1,119 +0,0 @@ -From: John Ogness -Date: Fri, 20 Oct 2023 10:01:58 +0000 -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 -for anything relating to the hardware. - -Since ownership can be lost at any time due to handover or -takeover, a context _should_ be prepared to back out -immediately and carefully. However, there are many scenarios -where the context _must_ reacquire ownership in order to -finalize or revert hardware changes. - -One such example is when interrupts are disabled by a context. -No other context will automagically re-enable the interrupts. -For this case, the disabling context _must_ reacquire nbcon -ownership so that it can re-enable the interrupts. - -Provide nbcon_reacquire() for exactly this purpose. - -Note that for printing contexts, after a successful reacquire -the context will have no output buffer because that has been -lost. nbcon_reacquire() cannot be used to resume printing. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 -@@ -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); -+extern void nbcon_reacquire(struct nbcon_write_context *wctxt); - #else - static inline void nbcon_cpu_emergency_enter(void) { } - static inline void nbcon_cpu_emergency_exit(void) { } - 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; } -+static inline void nbcon_reacquire(struct nbcon_write_context *wctxt) { } - #endif - - extern int console_set_on_cmdline; ---- a/kernel/printk/nbcon.c -+++ b/kernel/printk/nbcon.c -@@ -839,6 +839,38 @@ bool nbcon_exit_unsafe(struct nbcon_writ - EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); - - /** -+ * nbcon_reacquire - Reacquire a console after losing ownership -+ * @wctxt: The write context that was handed to the write function -+ * -+ * Since ownership can be lost at any time due to handover or takeover, a -+ * printing context _should_ be prepared to back out immediately and -+ * carefully. However, there are many scenarios where the context _must_ -+ * reacquire ownership in order to finalize or revert hardware changes. -+ * -+ * This function allows a context to reacquire ownership using the same -+ * priority as its previous ownership. -+ * -+ * Note that for printing contexts, after a successful reacquire the -+ * context will have no output buffer because that has been lost. This -+ * function cannot be used to resume printing. -+ */ -+void nbcon_reacquire(struct nbcon_write_context *wctxt) -+{ -+ struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); -+ struct console *con = ctxt->console; -+ struct nbcon_state cur; -+ -+ while (!nbcon_context_try_acquire(ctxt)) -+ cpu_relax(); -+ -+ wctxt->outbuf = NULL; -+ wctxt->len = 0; -+ nbcon_state_read(con, &cur); -+ wctxt->unsafe_takeover = cur.unsafe_takeover; -+} -+EXPORT_SYMBOL_GPL(nbcon_reacquire); -+ -+/** - * 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/0043-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch b/debian/patches-rt/0043-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch new file mode 100644 index 0000000000..a8e54a590a --- /dev/null +++ b/debian/patches-rt/0043-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch @@ -0,0 +1,29 @@ +From: John Ogness +Date: Mon, 2 Oct 2023 15:30:43 +0000 +Subject: [PATCH 43/46] serial: 8250: Revert "drop lockdep annotation from + serial8250_clear_IER()" +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +The 8250 driver no longer depends on @oops_in_progress and +will no longer violate the port->lock locking constraints. + +This reverts commit 3d9e6f556e235ddcdc9f73600fdd46fe1736b090. + +Signed-off-by: John Ogness +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/tty/serial/8250/8250_port.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -719,6 +719,9 @@ static void __serial8250_clear_IER(struc + + static inline void serial8250_clear_IER(struct uart_8250_port *up) + { ++ /* Port locked to synchronize UART_IER access against the console. */ ++ lockdep_assert_held_once(&up->port.lock); ++ + __serial8250_clear_IER(up); + } + diff --git a/debian/patches-rt/0044-printk-Add-kthread-for-all-legacy-consoles.patch b/debian/patches-rt/0044-printk-Add-kthread-for-all-legacy-consoles.patch new file mode 100644 index 0000000000..edcfbb989d --- /dev/null +++ b/debian/patches-rt/0044-printk-Add-kthread-for-all-legacy-consoles.patch @@ -0,0 +1,532 @@ +From: John Ogness +Date: Fri, 22 Sep 2023 17:35:04 +0000 +Subject: [PATCH 44/46] printk: Add kthread for all legacy consoles +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +The write callback of legacy consoles makes use of spinlocks. +This is not permitted with PREEMPT_RT in atomic contexts. + +For PREEMPT_RT, create a new kthread to handle printing of all +the legacy consoles (and nbcon consoles if boot consoles are +registered). + +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. + +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 +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/internal.h | 11 +- + kernel/printk/nbcon.c | 52 ++++++---- + kernel/printk/printk.c | 242 ++++++++++++++++++++++++++++++++++++++--------- + 3 files changed, 243 insertions(+), 62 deletions(-) + +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -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; } +--- a/kernel/printk/nbcon.c ++++ b/kernel/printk/nbcon.c +@@ -1224,9 +1224,10 @@ enum nbcon_prio nbcon_get_default_prio(v + } + + /* +- * 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: True, when a record has been printed and there are still + * pending records. The caller might want to continue flushing. +@@ -1239,7 +1240,7 @@ enum nbcon_prio nbcon_get_default_prio(v + * 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); + +@@ -1254,7 +1255,7 @@ static bool nbcon_atomic_emit_one(struct + * The higher priority printing context takes over responsibility + * to print the pending records. + */ +- if (!nbcon_emit_next_record(wctxt, true)) ++ if (!nbcon_emit_next_record(wctxt, use_atomic)) + return false; + + nbcon_context_release(ctxt); +@@ -1271,6 +1272,7 @@ static bool nbcon_atomic_emit_one(struct + * 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: True, when a record has been printed and there are still +@@ -1286,26 +1288,38 @@ static bool nbcon_atomic_emit_one(struct + * 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); + unsigned long flags; + bool progress; + +- /* Use the same procedure as console_emit_next_record(). */ +- printk_safe_enter_irqsave(flags); +- console_lock_spinning_enable(); +- stop_critical_timings(); +- +- 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); ++ 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 { ++ *handover = false; ++ ++ 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; + } +@@ -1622,6 +1636,8 @@ static int __init printk_setup_threads(v + printk_threads_enabled = true; + for_each_console(con) + nbcon_kthread_create(con); ++ 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; + + #ifdef CONFIG_PRINTK + DECLARE_WAIT_QUEUE_HEAD(log_wait); ++ ++static DECLARE_WAIT_QUEUE_HEAD(legacy_wait); ++ + /* All 3 protected by @syslog_lock. */ + /* the next printk record to read by syslog(READ) or /proc/kmsg */ + static u64 syslog_seq; +@@ -2345,7 +2348,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 && ++ !force_printkthreads(); + int printed_len; + + /* Suppress unimportant messages after panic happens */ +@@ -2468,6 +2472,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); + ++static struct task_struct *nbcon_legacy_kthread; ++ ++static inline void wake_up_legacy_kthread(void) ++{ ++ if (nbcon_legacy_kthread) ++ wake_up_interruptible(&legacy_wait); ++} ++ + #else /* CONFIG_PRINTK */ + + #define printk_time false +@@ -2481,6 +2493,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; } + ++static inline void nbcon_legacy_kthread_create(void) { } ++static inline void wake_up_legacy_kthread(void) { } + #endif /* CONFIG_PRINTK */ + + #ifdef CONFIG_EARLY_PRINTK +@@ -2726,6 +2740,8 @@ void resume_console(void) + } + console_srcu_read_unlock(cookie); + ++ wake_up_legacy_kthread(); ++ + pr_flush(1000, true); + } + +@@ -2740,7 +2756,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 && ++ !force_printkthreads()) { + /* If trylock fails, someone else is doing the printing */ + if (console_trylock()) + console_unlock(); +@@ -3000,31 +3017,43 @@ static bool console_emit_next_record(str + con->dropped = 0; + } + +- /* +- * While actively printing out messages, if another printk() +- * were to occur on another CPU, it may wait for this one to +- * finish. This task can not be preempted if there is a +- * waiter waiting to take over. +- * +- * Interrupts are disabled because the hand over to a waiter +- * must not be interrupted until the hand over is completed +- * (@console_waiter is cleared). +- */ +- printk_safe_enter_irqsave(flags); +- console_lock_spinning_enable(); ++ /* Write everything out to the hardware. */ + +- /* Do not trace print latency. */ +- stop_critical_timings(); ++ if (force_printkthreads()) { ++ /* ++ * 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); ++ con->write(con, outbuf, pmsg.outbuf_len); ++ con->seq = pmsg.seq + 1; ++ } else { ++ /* ++ * While actively printing out messages, if another printk() ++ * were to occur on another CPU, it may wait for this one to ++ * finish. This task can not be preempted if there is a ++ * waiter waiting to take over. ++ * ++ * Interrupts are disabled because the hand over to a waiter ++ * must not be interrupted until the hand over is completed ++ * (@console_waiter is cleared). ++ */ ++ printk_safe_enter_irqsave(flags); ++ console_lock_spinning_enable(); + +- start_critical_timings(); ++ /* Do not trace print latency. */ ++ stop_critical_timings(); + +- con->seq = pmsg.seq + 1; ++ con->write(con, outbuf, pmsg.outbuf_len); + +- *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); ++ printk_safe_exit_irqrestore(flags); ++ } + skip: + return true; + } +@@ -3088,12 +3117,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); +@@ -3132,19 +3162,7 @@ static bool console_flush_all(bool do_co + return false; + } + +-/** +- * console_unlock - unblock the console subsystem from printing +- * +- * Releases the console_lock which the caller holds to block printing of +- * the console subsystem. +- * +- * While the console_lock was held, console output may have been buffered +- * by printk(). If this is the case, console_unlock(); emits +- * the output prior to releasing the lock. +- * +- * console_unlock(); may be called from any context. +- */ +-void console_unlock(void) ++static void console_flush_and_unlock(void) + { + bool do_cond_resched; + bool handover; +@@ -3188,6 +3206,32 @@ void console_unlock(void) + */ + } while (prb_read_valid(prb, next_seq, NULL) && console_trylock()); + } ++ ++/** ++ * console_unlock - unblock the console subsystem from printing ++ * ++ * Releases the console_lock which the caller holds to block printing of ++ * the console subsystem. ++ * ++ * While the console_lock was held, console output may have been buffered ++ * by printk(). If this is the case, console_unlock(); emits ++ * the output prior to releasing the lock. ++ * ++ * console_unlock(); may be called from any context. ++ */ ++void console_unlock(void) ++{ ++ /* ++ * Forced threading relies on kthread and atomic consoles for ++ * printing. It never attempts to print from console_unlock(). ++ */ ++ if (force_printkthreads()) { ++ __console_unlock(); ++ return; ++ } ++ ++ console_flush_and_unlock(); ++} + EXPORT_SYMBOL(console_unlock); + + /** +@@ -3397,11 +3441,106 @@ void console_start(struct console *conso + + if (flags & CON_NBCON) + nbcon_kthread_wake(console); ++ else ++ wake_up_legacy_kthread(); + + __pr_flush(console, 1000, true); + } + EXPORT_SYMBOL(console_start); + ++#ifdef CONFIG_PRINTK ++static bool printer_should_wake(void) ++{ ++ bool available = false; ++ struct console *con; ++ int cookie; ++ ++ if (kthread_should_stop()) ++ return true; ++ ++ cookie = console_srcu_read_lock(); ++ for_each_console_srcu(con) { ++ short flags = console_srcu_read_flags(con); ++ u64 printk_seq; ++ ++ /* ++ * The legacy printer thread is only for legacy consoles, ++ * unless the nbcon console has no kthread printer. ++ */ ++ if ((flags & CON_NBCON) && con->kthread) ++ continue; ++ ++ if (!console_is_usable(con, flags, true)) ++ continue; ++ ++ if (flags & CON_NBCON) { ++ printk_seq = nbcon_seq_read(con); ++ } else { ++ /* ++ * It is safe to read @seq because only this ++ * thread context updates @seq. ++ */ ++ printk_seq = con->seq; ++ } ++ ++ if (prb_read_valid(prb, printk_seq, NULL)) { ++ available = true; ++ break; ++ } ++ } ++ console_srcu_read_unlock(cookie); ++ ++ return available; ++} ++ ++static int nbcon_legacy_kthread_func(void *unused) ++{ ++ int error; ++ ++ for (;;) { ++ error = wait_event_interruptible(legacy_wait, printer_should_wake()); ++ ++ if (kthread_should_stop()) ++ break; ++ ++ if (error) ++ continue; ++ ++ console_lock(); ++ console_flush_and_unlock(); ++ } ++ ++ return 0; ++} ++ ++void nbcon_legacy_kthread_create(void) ++{ ++ struct task_struct *kt; ++ ++ lockdep_assert_held(&console_mutex); ++ ++ if (!force_printkthreads()) ++ return; ++ ++ if (!printk_threads_enabled || nbcon_legacy_kthread) ++ return; ++ ++ kt = kthread_run(nbcon_legacy_kthread_func, NULL, "pr/legacy"); ++ if (IS_ERR(kt)) { ++ pr_err("unable to start legacy printing thread\n"); ++ return; ++ } ++ ++ nbcon_legacy_kthread = kt; ++ ++ /* ++ * It is important that console printing threads are scheduled ++ * shortly after a printk call and with generous runtime budgets. ++ */ ++ sched_set_normal(nbcon_legacy_kthread, -20); ++} ++#endif /* CONFIG_PRINTK */ ++ + static int __read_mostly keep_bootcon; + + static int __init keep_bootcon_setup(char *str) +@@ -3690,6 +3829,7 @@ void register_console(struct console *ne + } else { + have_legacy_console = true; + newcon->seq = init_seq; ++ nbcon_legacy_kthread_create(); + } + + if (newcon->flags & CON_BOOT) +@@ -3856,6 +3996,13 @@ static int unregister_console_locked(str + nbcon_kthread_create(c); + } + ++#ifdef CONFIG_PRINTK ++ if (!printing_via_unlock && nbcon_legacy_kthread) { ++ kthread_stop(nbcon_legacy_kthread); ++ nbcon_legacy_kthread = NULL; ++ } ++#endif ++ + return res; + } + +@@ -4014,8 +4161,12 @@ static bool __pr_flush(struct console *c + + seq = prb_next_reserve_seq(prb); + +- /* Flush the consoles so that records up to @seq are printed. */ +- if (printing_via_unlock) { ++ /* ++ * Flush the consoles so that records up to @seq are printed. ++ * Otherwise this function will just wait for the threaded printers ++ * to print up to @seq. ++ */ ++ if (printing_via_unlock && !force_printkthreads()) { + console_lock(); + console_unlock(); + } +@@ -4129,9 +4280,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 (force_printkthreads()) { ++ wake_up_legacy_kthread(); ++ } else { ++ /* ++ * If trylock fails, some other context ++ * will do the printing. ++ */ ++ if (console_trylock()) ++ console_unlock(); ++ } + } + + if (pending & PRINTK_PENDING_WAKEUP) diff --git a/debian/patches-rt/0044-serial-8250-Switch-to-nbcon-console.patch b/debian/patches-rt/0044-serial-8250-Switch-to-nbcon-console.patch deleted file mode 100644 index 22edc18426..0000000000 --- a/debian/patches-rt/0044-serial-8250-Switch-to-nbcon-console.patch +++ /dev/null @@ -1,337 +0,0 @@ -From: John Ogness -Date: Wed, 13 Sep 2023 15:30:36 +0000 -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 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. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - 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, 202 insertions(+), 3 deletions(-) - ---- a/drivers/tty/serial/8250/8250_core.c -+++ b/drivers/tty/serial/8250/8250_core.c -@@ -592,6 +592,7 @@ serial8250_register_ports(struct uart_dr - - #ifdef CONFIG_SERIAL_8250_CONSOLE - -+#ifdef CONFIG_SERIAL_8250_LEGACY_CONSOLE - static void univ8250_console_write(struct console *co, const char *s, - unsigned int count) - { -@@ -599,6 +600,39 @@ static void univ8250_console_write(struc - - serial8250_console_write(up, s, count); - } -+#else -+static void univ8250_console_write_atomic(struct console *co, -+ struct nbcon_write_context *wctxt) -+{ -+ struct uart_8250_port *up = &serial8250_ports[co->index]; -+ -+ serial8250_console_write_atomic(up, wctxt); -+} -+ -+static void univ8250_console_write_thread(struct console *co, -+ struct nbcon_write_context *wctxt) -+{ -+ struct uart_8250_port *up = &serial8250_ports[co->index]; -+ -+ serial8250_console_write_thread(up, wctxt); -+} -+ -+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_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 +732,21 @@ static int univ8250_console_match(struct - - static struct console univ8250_console = { - .name = "ttyS", -+#ifdef CONFIG_SERIAL_8250_LEGACY_CONSOLE - .write = univ8250_console_write, -+ .flags = CON_PRINTBUFFER | CON_ANYTIME, -+#else -+ .write_atomic = univ8250_console_write_atomic, -+ .write_thread = univ8250_console_write_thread, -+ .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, - .exit = univ8250_console_exit, - .match = univ8250_console_match, -- .flags = CON_PRINTBUFFER | CON_ANYTIME, - .index = -1, - .data = &serial8250_reg, - }; ---- a/drivers/tty/serial/8250/8250_port.c -+++ b/drivers/tty/serial/8250/8250_port.c -@@ -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)) { -+ 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 +709,11 @@ static void serial8250_set_sleep(struct - serial8250_rpm_put(p); - } - --static void serial8250_clear_IER(struct uart_8250_port *up) -+/* -+ * Only to be used by write_atomic() and the legacy write(), which do not -+ * require port lock. -+ */ -+static void __serial8250_clear_IER(struct uart_8250_port *up) - { - if (up->capabilities & UART_CAP_UUE) - serial_out(up, UART_IER, UART_IER_UUE); -@@ -710,6 +721,11 @@ static void serial8250_clear_IER(struct - serial_out(up, UART_IER, 0); - } - -+static inline void serial8250_clear_IER(struct uart_8250_port *up) -+{ -+ __serial8250_clear_IER(up); -+} -+ - #ifdef CONFIG_SERIAL_8250_RSA - /* - * Attempts to turn on the RSA FIFO. Returns zero on failure. -@@ -3320,6 +3336,11 @@ static void serial8250_console_putchar(s - - wait_for_xmitr(up, UART_LSR_THRE); - serial_port_out(port, UART_TX, ch); -+ -+ if (ch == '\n') -+ up->console_newline_needed = false; -+ else -+ up->console_newline_needed = true; - } - - /* -@@ -3348,6 +3369,7 @@ static void serial8250_console_restore(s - serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); - } - -+#ifdef CONFIG_SERIAL_8250_LEGACY_CONSOLE - /* - * Print a string to the serial port using the device FIFO - * -@@ -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); -- serial8250_clear_IER(up); -+ __serial8250_clear_IER(up); - - /* 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 +3494,131 @@ void serial8250_console_write(struct uar - if (locked) - uart_port_unlock_irqrestore(port, flags); - } -+#else -+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; -+ unsigned int ier; -+ -+ touch_nmi_watchdog(); -+ -+ if (!nbcon_enter_unsafe(wctxt)) -+ return; -+ -+ /* First save IER then disable the interrupts. */ -+ ier = serial_port_in(port, UART_IER); -+ serial8250_clear_IER(up); -+ -+ /* Check scratch reg if port powered off during system sleep. */ -+ if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { -+ serial8250_console_restore(up); -+ up->canary = 0; -+ } -+ -+ if (em485) { -+ if (em485->tx_stopped) -+ up->rs485_start_tx(up); -+ mdelay(port->rs485.delay_rts_before_send); -+ } -+ -+ if (nbcon_exit_unsafe(wctxt)) { -+ int len = READ_ONCE(wctxt->len); -+ int i; -+ -+ /* -+ * Write out the message. Toggle unsafe for each byte in order -+ * to give another (higher priority) context the opportunity -+ * for a friendly takeover. If such a takeover occurs, this -+ * context must reacquire ownership in order to perform final -+ * actions (such as re-enabling the interrupts). -+ * -+ * IMPORTANT: wctxt->outbuf and wctxt->len are no longer valid -+ * after a reacquire so writing the message must be -+ * aborted. -+ */ -+ for (i = 0; i < len; i++) { -+ if (!nbcon_enter_unsafe(wctxt)) { -+ nbcon_reacquire(wctxt); -+ break; -+ } -+ -+ uart_console_write(port, wctxt->outbuf + i, 1, serial8250_console_putchar); -+ -+ if (!nbcon_exit_unsafe(wctxt)) { -+ nbcon_reacquire(wctxt); -+ break; -+ } -+ } -+ } else { -+ nbcon_reacquire(wctxt); -+ } -+ -+ while (!nbcon_enter_unsafe(wctxt)) -+ nbcon_reacquire(wctxt); -+ -+ /* Finally, wait for transmitter to become empty and restore IER. */ -+ wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); -+ if (em485) { -+ mdelay(port->rs485.delay_rts_after_send); -+ if (em485->tx_stopped) -+ up->rs485_stop_tx(up); -+ } -+ serial_port_out(port, UART_IER, ier); -+ -+ /* -+ * The receive handling will happen properly because the receive ready -+ * bit will still be set; it is not cleared on read. However, modem -+ * control will not, we must call it if we have saved something in the -+ * saved flags while processing with interrupts off. -+ */ -+ if (up->msr_saved_flags) -+ serial8250_modem_status(up); -+ -+ nbcon_exit_unsafe(wctxt); -+} -+ -+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 (WARN_ON_ONCE(up->em485)) -+ return; -+ -+ touch_nmi_watchdog(); -+ -+ if (!nbcon_enter_unsafe(wctxt)) -+ return; -+ -+ /* -+ * First save IER then disable the interrupts. The special variant to -+ * clear IER is used because atomic printing may occur without holding -+ * the port lock. -+ */ -+ ier = serial_port_in(port, UART_IER); -+ __serial8250_clear_IER(up); -+ -+ /* Check scratch reg if port powered off during system sleep. */ -+ if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { -+ serial8250_console_restore(up); -+ up->canary = 0; -+ } -+ -+ if (up->console_newline_needed) -+ uart_console_write(port, "\n", 1, serial8250_console_putchar); -+ uart_console_write(port, wctxt->outbuf, wctxt->len, serial8250_console_putchar); -+ -+ /* Finally, wait for transmitter to become empty and restore IER. */ -+ wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); -+ serial_port_out(port, UART_IER, ier); -+ -+ nbcon_exit_unsafe(wctxt); -+} -+#endif /* CONFIG_SERIAL_8250_LEGACY_CONSOLE */ - - static unsigned int probe_baud(struct uart_port *port) - { -@@ -3490,6 +3637,7 @@ static unsigned int probe_baud(struct ua - - int serial8250_console_setup(struct uart_port *port, char *options, bool probe) - { -+ struct uart_8250_port *up = up_to_u8250p(port); - int baud = 9600; - int bits = 8; - int parity = 'n'; -@@ -3499,6 +3647,8 @@ int serial8250_console_setup(struct uart - if (!port->iobase && !port->membase) - return -ENODEV; - -+ up->console_newline_needed = false; -+ - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - else if (probe) ---- a/include/linux/serial_8250.h -+++ b/include/linux/serial_8250.h -@@ -153,6 +153,8 @@ struct uart_8250_port { - #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA - unsigned char msr_saved_flags; - -+ bool console_newline_needed; -+ - struct uart_8250_dma *dma; - const struct uart_8250_ops *ops; - -@@ -204,6 +206,10 @@ void serial8250_init_port(struct uart_82 - void serial8250_set_defaults(struct uart_8250_port *up); - void serial8250_console_write(struct uart_8250_port *up, const char *s, - unsigned int count); -+void serial8250_console_write_atomic(struct uart_8250_port *up, -+ struct nbcon_write_context *wctxt); -+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/0045-printk-Provide-threadprintk-boot-argument.patch b/debian/patches-rt/0045-printk-Provide-threadprintk-boot-argument.patch new file mode 100644 index 0000000000..afb91f6f64 --- /dev/null +++ b/debian/patches-rt/0045-printk-Provide-threadprintk-boot-argument.patch @@ -0,0 +1,96 @@ +From: John Ogness +Date: Tue, 6 Feb 2024 14:19:34 +0000 +Subject: [PATCH 45/46] printk: Provide threadprintk boot argument +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Signed-off-by: Sebastian Andrzej Siewior +--- + 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 +@@ -6552,6 +6552,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,EARLY] + 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 ++#include + #include + #include + +@@ -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/0045-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch b/debian/patches-rt/0045-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch deleted file mode 100644 index e9544b9f8c..0000000000 --- a/debian/patches-rt/0045-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: John Ogness -Date: Mon, 2 Oct 2023 15:30:43 +0000 -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.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. - -This reverts commit 3d9e6f556e235ddcdc9f73600fdd46fe1736b090. - -Signed-off-by: John Ogness -Signed-off-by: Sebastian Andrzej Siewior ---- - drivers/tty/serial/8250/8250_port.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/tty/serial/8250/8250_port.c -+++ b/drivers/tty/serial/8250/8250_port.c -@@ -723,6 +723,9 @@ static void __serial8250_clear_IER(struc - - static inline void serial8250_clear_IER(struct uart_8250_port *up) - { -+ /* Port locked to synchronize UART_IER access against the console. */ -+ lockdep_assert_held_once(&up->port.lock); -+ - __serial8250_clear_IER(up); - } - diff --git a/debian/patches-rt/0046-printk-Add-kthread-for-all-legacy-consoles.patch b/debian/patches-rt/0046-printk-Add-kthread-for-all-legacy-consoles.patch deleted file mode 100644 index e29281db8f..0000000000 --- a/debian/patches-rt/0046-printk-Add-kthread-for-all-legacy-consoles.patch +++ /dev/null @@ -1,566 +0,0 @@ -From: John Ogness -Date: Fri, 22 Sep 2023 17:35:04 +0000 -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 makes use of spinlocks. -This is not permitted with PREEMPT_RT in atomic contexts. - -For PREEMPT_RT, create a new kthread to handle printing of all -the legacy consoles (and nbcon consoles if boot consoles are -registered). - -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. - -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 -@@ -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 -@@ -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 procedure as console_emit_next_record(). */ -- printk_safe_enter_irqsave(flags); -- console_lock_spinning_enable(); -- stop_critical_timings(); -- -- 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); -+ 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; - } -@@ -1536,6 +1548,8 @@ static int __init printk_setup_threads(v - printk_threads_enabled = true; - for_each_console(con) - nbcon_kthread_create(con); -+ 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 -@@ -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); -+ -+static DECLARE_WAIT_QUEUE_HEAD(legacy_wait); -+ - /* All 3 protected by @syslog_lock. */ - /* the next printk record to read by syslog(READ) or /proc/kmsg */ - static u64 syslog_seq; -@@ -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 && -+ !force_printkthreads(); - int printed_len; - - /* Suppress unimportant messages after panic happens */ -@@ -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); - -+static struct task_struct *nbcon_legacy_kthread; -+ -+static inline void wake_up_legacy_kthread(void) -+{ -+ if (nbcon_legacy_kthread) -+ wake_up_interruptible(&legacy_wait); -+} -+ - #else /* CONFIG_PRINTK */ - - #define printk_time false -@@ -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; } - -+static inline void nbcon_legacy_kthread_create(void) { } -+static inline void wake_up_legacy_kthread(void) { } - #endif /* CONFIG_PRINTK */ - - #ifdef CONFIG_EARLY_PRINTK -@@ -2739,6 +2745,8 @@ void resume_console(void) - } - console_srcu_read_unlock(cookie); - -+ wake_up_legacy_kthread(); -+ - pr_flush(1000, true); - } - -@@ -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 && -+ !force_printkthreads()) { - /* If trylock fails, someone else is doing the printing */ - if (console_trylock()) - console_unlock(); -@@ -3013,31 +3022,43 @@ static bool console_emit_next_record(str - con->dropped = 0; - } - -- /* -- * While actively printing out messages, if another printk() -- * were to occur on another CPU, it may wait for this one to -- * finish. This task can not be preempted if there is a -- * waiter waiting to take over. -- * -- * Interrupts are disabled because the hand over to a waiter -- * must not be interrupted until the hand over is completed -- * (@console_waiter is cleared). -- */ -- printk_safe_enter_irqsave(flags); -- console_lock_spinning_enable(); -+ /* Write everything out to the hardware. */ -+ -+ if (force_printkthreads()) { -+ /* -+ * 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. -+ */ - -- /* Do not trace print latency. */ -- stop_critical_timings(); -+ con->write(con, outbuf, pmsg.outbuf_len); -+ con->seq = pmsg.seq + 1; -+ } else { -+ /* -+ * While actively printing out messages, if another printk() -+ * were to occur on another CPU, it may wait for this one to -+ * finish. This task can not be preempted if there is a -+ * waiter waiting to take over. -+ * -+ * Interrupts are disabled because the hand over to a waiter -+ * must not be interrupted until the hand over is completed -+ * (@console_waiter is cleared). -+ */ -+ printk_safe_enter_irqsave(flags); -+ console_lock_spinning_enable(); - -- /* Write everything out to the hardware. */ -- con->write(con, outbuf, pmsg.outbuf_len); -+ /* Do not trace print latency. */ -+ stop_critical_timings(); - -- 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); -+ con->seq = pmsg.seq + 1; -+ -+ *handover = console_lock_spinning_disable_and_check(cookie); -+ printk_safe_exit_irqrestore(flags); -+ } - skip: - return true; - } -@@ -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; - } - --/** -- * console_unlock - unblock the console subsystem from printing -- * -- * Releases the console_lock which the caller holds to block printing of -- * the console subsystem. -- * -- * While the console_lock was held, console output may have been buffered -- * by printk(). If this is the case, console_unlock(); emits -- * the output prior to releasing the lock. -- * -- * console_unlock(); may be called from any context. -- */ --void console_unlock(void) -+static void console_flush_and_unlock(void) - { - bool do_cond_resched; - bool handover; -@@ -3201,6 +3211,32 @@ void console_unlock(void) - */ - } while (prb_read_valid(prb, next_seq, NULL) && console_trylock()); - } -+ -+/** -+ * console_unlock - unblock the console subsystem from printing -+ * -+ * Releases the console_lock which the caller holds to block printing of -+ * the console subsystem. -+ * -+ * While the console_lock was held, console output may have been buffered -+ * by printk(). If this is the case, console_unlock(); emits -+ * the output prior to releasing the lock. -+ * -+ * console_unlock(); may be called from any context. -+ */ -+void console_unlock(void) -+{ -+ /* -+ * Forced threading relies on kthread and atomic consoles for -+ * printing. It never attempts to print from console_unlock(). -+ */ -+ if (force_printkthreads()) { -+ __console_unlock(); -+ return; -+ } -+ -+ console_flush_and_unlock(); -+} - EXPORT_SYMBOL(console_unlock); - - /** -@@ -3410,11 +3446,106 @@ void console_start(struct console *conso - - if (flags & CON_NBCON) - nbcon_kthread_wake(console); -+ else -+ wake_up_legacy_kthread(); - - __pr_flush(console, 1000, true); - } - EXPORT_SYMBOL(console_start); - -+#ifdef CONFIG_PRINTK -+static bool printer_should_wake(void) -+{ -+ bool available = false; -+ struct console *con; -+ int cookie; -+ -+ if (kthread_should_stop()) -+ return true; -+ -+ cookie = console_srcu_read_lock(); -+ for_each_console_srcu(con) { -+ short flags = console_srcu_read_flags(con); -+ u64 printk_seq; -+ -+ /* -+ * The legacy printer thread is only for legacy consoles, -+ * unless the nbcon console has no kthread printer. -+ */ -+ if ((flags & CON_NBCON) && con->kthread) -+ continue; -+ -+ if (!console_is_usable(con, flags, true)) -+ continue; -+ -+ if (flags & CON_NBCON) { -+ printk_seq = nbcon_seq_read(con); -+ } else { -+ /* -+ * It is safe to read @seq because only this -+ * thread context updates @seq. -+ */ -+ printk_seq = con->seq; -+ } -+ -+ if (prb_read_valid(prb, printk_seq, NULL)) { -+ available = true; -+ break; -+ } -+ } -+ console_srcu_read_unlock(cookie); -+ -+ return available; -+} -+ -+static int nbcon_legacy_kthread_func(void *unused) -+{ -+ int error; -+ -+ for (;;) { -+ error = wait_event_interruptible(legacy_wait, printer_should_wake()); -+ -+ if (kthread_should_stop()) -+ break; -+ -+ if (error) -+ continue; -+ -+ console_lock(); -+ console_flush_and_unlock(); -+ } -+ -+ return 0; -+} -+ -+void nbcon_legacy_kthread_create(void) -+{ -+ struct task_struct *kt; -+ -+ lockdep_assert_held(&console_mutex); -+ -+ if (!force_printkthreads()) -+ return; -+ -+ if (!printk_threads_enabled || nbcon_legacy_kthread) -+ return; -+ -+ kt = kthread_run(nbcon_legacy_kthread_func, NULL, "pr/legacy"); -+ if (IS_ERR(kt)) { -+ pr_err("unable to start legacy printing thread\n"); -+ return; -+ } -+ -+ nbcon_legacy_kthread = kt; -+ -+ /* -+ * It is important that console printing threads are scheduled -+ * shortly after a printk call and with generous runtime budgets. -+ */ -+ sched_set_normal(nbcon_legacy_kthread, -20); -+} -+#endif /* CONFIG_PRINTK */ -+ - static int __read_mostly keep_bootcon; - - static int __init keep_bootcon_setup(char *str) -@@ -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) -@@ -3846,6 +3978,13 @@ static int unregister_console_locked(str - nbcon_kthread_create(c); - } - -+#ifdef CONFIG_PRINTK -+ if (!printing_via_unlock && nbcon_legacy_kthread) { -+ kthread_stop(nbcon_legacy_kthread); -+ nbcon_legacy_kthread = NULL; -+ } -+#endif -+ - return res; - } - -@@ -4004,8 +4143,12 @@ static bool __pr_flush(struct console *c - - seq = prb_next_reserve_seq(prb); - -- /* Flush the consoles so that records up to @seq are printed. */ -- if (printing_via_unlock) { -+ /* -+ * Flush the consoles so that records up to @seq are printed. -+ * Otherwise this function will just wait for the threaded printers -+ * to print up to @seq. -+ */ -+ if (printing_via_unlock && !force_printkthreads()) { - console_lock(); - console_unlock(); - } -@@ -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 (force_printkthreads()) { -+ wake_up_legacy_kthread(); -+ } else { -+ /* -+ * If trylock fails, some other context -+ * will do the printing. -+ */ -+ if (console_trylock()) -+ console_unlock(); -+ } - } - - if (pending & PRINTK_PENDING_WAKEUP) diff --git a/debian/patches-rt/0046-printk-Avoid-false-positive-lockdep-report-for-legac.patch b/debian/patches-rt/0046-printk-Avoid-false-positive-lockdep-report-for-legac.patch new file mode 100644 index 0000000000..7906760f71 --- /dev/null +++ b/debian/patches-rt/0046-printk-Avoid-false-positive-lockdep-report-for-legac.patch @@ -0,0 +1,86 @@ +From: John Ogness +Date: Mon, 11 Dec 2023 09:34:16 +0000 +Subject: [PATCH 46/46] printk: Avoid false positive lockdep report for legacy + printing +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 +Signed-off-by: Sebastian Andrzej Siewior +--- + kernel/printk/printk.c | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2980,6 +2980,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. +@@ -3034,7 +3061,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); +@@ -3056,7 +3083,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/0047-printk-Provide-threadprintk-boot-argument.patch b/debian/patches-rt/0047-printk-Provide-threadprintk-boot-argument.patch deleted file mode 100644 index cc47be3205..0000000000 --- a/debian/patches-rt/0047-printk-Provide-threadprintk-boot-argument.patch +++ /dev/null @@ -1,96 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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 -+#include - #include - #include - -@@ -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 deleted file mode 100644 index 510b3c0808..0000000000 --- a/debian/patches-rt/0048-printk-Avoid-false-positive-lockdep-report-for-legac.patch +++ /dev/null @@ -1,86 +0,0 @@ -From: John Ogness -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 -Signed-off-by: Sebastian Andrzej Siewior ---- - 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/ARM64__Allow_to_enable_RT.patch b/debian/patches-rt/ARM64__Allow_to_enable_RT.patch index 9f85cf15b9..6035feec48 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 Date: Fri Oct 11 13:14:35 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Sebastian Andrzej Siewior diff --git a/debian/patches-rt/ARM__Allow_to_enable_RT.patch b/debian/patches-rt/ARM__Allow_to_enable_RT.patch index 08fb67f116..f8b96792fb 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 Date: Fri Oct 11 13:14:29 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Sebastian Andrzej Siewior @@ -17,7 +17,7 @@ Signed-off-by: Thomas Gleixner --- --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -36,6 +36,7 @@ config ARM +@@ -37,6 +37,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 select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF select ARCH_USE_MEMTEST -@@ -120,6 +121,7 @@ config ARM +@@ -122,6 +123,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 9ca02d6a8b..30db897eb8 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 Date: Wed Dec 10 10:32:09 2014 +0800 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Yadi.hu @@ -69,7 +69,7 @@ Signed-off-by: Thomas Gleixner --- --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c -@@ -436,6 +436,9 @@ do_translation_fault(unsigned long addr, +@@ -443,6 +443,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 if (user_mode(regs)) goto bad_area; -@@ -506,6 +509,9 @@ do_translation_fault(unsigned long addr, +@@ -513,6 +516,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 1dbdcfcb68..ad37a7f522 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 Date: Fri Jul 8 20:25:16 2011 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Thomas Gleixner @@ -16,4 +16,4 @@ Signed-off-by: Thomas Gleixner --- /dev/null +++ b/localversion-rt @@ -0,0 +1 @@ -+-rt11 ++-rt5 diff --git a/debian/patches-rt/POWERPC__Allow_to_enable_RT.patch b/debian/patches-rt/POWERPC__Allow_to_enable_RT.patch index 34d9aae651..9ac12f490a 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 Date: Fri Oct 11 13:14:41 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Sebastian Andrzej Siewior diff --git a/debian/patches-rt/PREEMPT_AUTO.patch b/debian/patches-rt/PREEMPT_AUTO.patch index 338abae7c3..f9098eb616 100644 --- a/debian/patches-rt/PREEMPT_AUTO.patch +++ b/debian/patches-rt/PREEMPT_AUTO.patch @@ -1,7 +1,7 @@ From: Thomas Gleixner 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -277,6 +277,7 @@ config X86 +@@ -279,6 +279,7 @@ config X86 select HAVE_STATIC_CALL select HAVE_STATIC_CALL_INLINE if HAVE_OBJTOOL select HAVE_PREEMPT_DYNAMIC_CALL @@ -132,7 +132,7 @@ Signed-off-by: Sebastian Andrzej Siewior select HAVE_SYSCALL_TRACEPOINTS --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h -@@ -81,8 +81,9 @@ struct thread_info { +@@ -87,8 +87,9 @@ struct thread_info { #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ @@ -144,7 +144,7 @@ Signed-off-by: Sebastian Andrzej Siewior #define TIF_SPEC_IB 9 /* Indirect branch speculation mitigation */ #define TIF_SPEC_L1D_FLUSH 10 /* Flush L1D on mm switches (processes) */ #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ -@@ -104,6 +105,7 @@ struct thread_info { +@@ -110,6 +111,7 @@ struct thread_info { #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -187,7 +187,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1934,17 +1934,17 @@ static inline void update_tsk_thread_fla +@@ -1938,17 +1938,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 { return test_ti_thread_flag(task_thread_info(tsk), flag); } -@@ -1957,9 +1957,11 @@ static inline void set_tsk_need_resched( +@@ -1961,9 +1961,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 { return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); } -@@ -2100,7 +2102,7 @@ static inline bool preempt_model_preempt +@@ -2104,7 +2106,7 @@ static inline bool preempt_model_preempt static __always_inline bool need_resched(void) { @@ -313,7 +313,7 @@ Signed-off-by: Sebastian Andrzej Siewior #ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h -@@ -178,8 +178,8 @@ unsigned int tracing_gen_ctx_irq_test(un +@@ -184,8 +184,8 @@ unsigned int tracing_gen_ctx_irq_test(un enum trace_flag_type { TRACE_FLAG_IRQS_OFF = 0x01, @@ -324,7 +324,7 @@ Signed-off-by: Sebastian Andrzej Siewior TRACE_FLAG_HARDIRQ = 0x08, TRACE_FLAG_SOFTIRQ = 0x10, TRACE_FLAG_PREEMPT_RESCHED = 0x20, -@@ -205,11 +205,11 @@ static inline unsigned int tracing_gen_c +@@ -211,11 +211,11 @@ static inline unsigned int tracing_gen_c static inline unsigned int tracing_gen_ctx_flags(unsigned long irqflags) { @@ -383,7 +383,7 @@ Signed-off-by: Sebastian Andrzej Siewior default y if HAVE_PREEMPT_DYNAMIC_CALL --- a/kernel/entry/common.c +++ b/kernel/entry/common.c -@@ -92,7 +92,7 @@ void __weak arch_do_signal_or_restart(st +@@ -98,7 +98,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 schedule(); if (ti_work & _TIF_UPROBE) -@@ -301,7 +301,7 @@ void raw_irqentry_exit_cond_resched(void +@@ -307,7 +307,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()); @@ -556,7 +556,7 @@ Signed-off-by: Sebastian Andrzej Siewior late_initcall(sched_init_debug); --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c -@@ -975,8 +975,10 @@ static void clear_buddies(struct cfs_rq +@@ -981,8 +981,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 if ((s64)(se->vruntime - se->deadline) < 0) return; -@@ -995,10 +997,19 @@ static void update_deadline(struct cfs_r +@@ -1001,10 +1003,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 } #include "pelt.h" -@@ -1153,7 +1164,7 @@ s64 update_curr_common(struct rq *rq) +@@ -1159,7 +1170,7 @@ s64 update_curr_common(struct rq *rq) /* * Update the current task's runtime statistics. */ @@ -600,7 +600,7 @@ Signed-off-by: Sebastian Andrzej Siewior { struct sched_entity *curr = cfs_rq->curr; s64 delta_exec; -@@ -1166,7 +1177,7 @@ static void update_curr(struct cfs_rq *c +@@ -1172,7 +1183,7 @@ static void update_curr(struct cfs_rq *c return; curr->vruntime += calc_delta_fair(delta_exec, curr); @@ -609,7 +609,7 @@ Signed-off-by: Sebastian Andrzej Siewior update_min_vruntime(cfs_rq); if (entity_is_task(curr)) -@@ -1175,6 +1186,11 @@ static void update_curr(struct cfs_rq *c +@@ -1181,6 +1192,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 static void update_curr_fair(struct rq *rq) { update_curr(cfs_rq_of(&rq->curr->se)); -@@ -5493,7 +5509,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc +@@ -5505,7 +5521,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 /* * Ensure that runnable average is periodically updated. -@@ -5507,7 +5523,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc +@@ -5519,7 +5535,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 return; } /* -@@ -5653,7 +5669,7 @@ static void __account_cfs_rq_runtime(str +@@ -5665,7 +5681,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 } static __always_inline -@@ -5913,7 +5929,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cf +@@ -5925,7 +5941,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 } #ifdef CONFIG_SMP -@@ -6628,7 +6644,7 @@ static void hrtick_start_fair(struct rq +@@ -6640,7 +6656,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 return; } hrtick_start(rq, delta); -@@ -8304,7 +8320,7 @@ static void check_preempt_wakeup_fair(st +@@ -8316,7 +8332,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 return; /* Idle tasks are by definition preempted by non-idle tasks. */ -@@ -8346,7 +8362,7 @@ static void check_preempt_wakeup_fair(st +@@ -8358,7 +8374,7 @@ static void check_preempt_wakeup_fair(st return; preempt: @@ -684,7 +684,7 @@ Signed-off-by: Sebastian Andrzej Siewior } #ifdef CONFIG_SMP -@@ -12516,7 +12532,7 @@ static inline void task_tick_core(struct +@@ -12504,7 +12520,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 } /* -@@ -12681,7 +12697,7 @@ prio_changed_fair(struct rq *rq, struct +@@ -12669,7 +12685,7 @@ prio_changed_fair(struct rq *rq, struct */ if (task_current(rq, p)) { if (p->prio > oldprio) @@ -724,7 +724,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h -@@ -2463,6 +2463,7 @@ extern void init_sched_fair_class(void); +@@ -2465,6 +2465,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 extern struct rt_bandwidth def_rt_bandwidth; --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -2717,6 +2717,8 @@ unsigned int tracing_gen_ctx_irq_test(un +@@ -2513,6 +2513,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 9c05d2aeb7..a94094c5bc 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 index 09dcd78d53..478d746f75 100644 --- 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 @@ -2,7 +2,7 @@ From: Sebastian Andrzej Siewior 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 +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz gup_pgd_range() is invoked with disabled interrupts and invokes __kmap_local_page_prot() via pte_offset_map(), gup_p4d_range(). @@ -24,7 +24,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -98,7 +98,7 @@ config ARM +@@ -99,7 +99,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 diff --git a/debian/patches-rt/drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch b/debian/patches-rt/drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch new file mode 100644 index 0000000000..33a7f3cc72 --- /dev/null +++ b/debian/patches-rt/drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch @@ -0,0 +1,59 @@ +From: Sebastian Andrzej Siewior +Date: Thu, 6 Dec 2018 09:52:20 +0100 +Subject: [PATCH] drm/i915: Disable tracing points on PREEMPT_RT +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +Luca Abeni reported this: +| BUG: scheduling while atomic: kworker/u8:2/15203/0x00000003 +| CPU: 1 PID: 15203 Comm: kworker/u8:2 Not tainted 4.19.1-rt3 #10 +| Call Trace: +| rt_spin_lock+0x3f/0x50 +| gen6_read32+0x45/0x1d0 [i915] +| g4x_get_vblank_counter+0x36/0x40 [i915] +| trace_event_raw_event_i915_pipe_update_start+0x7d/0xf0 [i915] + +The tracing events use trace_intel_pipe_update_start() among other events +use functions acquire spinlock_t locks which are transformed into +sleeping locks on PREEMPT_RT. A few trace points use +intel_get_crtc_scanline(), others use ->get_vblank_counter() wich also +might acquire a sleeping locks on PREEMPT_RT. +At the time the arguments are evaluated within trace point, preemption +is disabled and so the locks must not be acquired on PREEMPT_RT. + +Based on this I don't see any other way than disable trace points on +PREMPT_RT. + +Reported-by: Luca Abeni +Cc: Steven Rostedt +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/gpu/drm/i915/display/intel_display_trace.h | 4 ++++ + drivers/gpu/drm/i915/i915_trace.h | 4 ++++ + 2 files changed, 8 insertions(+) + +--- a/drivers/gpu/drm/i915/display/intel_display_trace.h ++++ b/drivers/gpu/drm/i915/display/intel_display_trace.h +@@ -9,6 +9,10 @@ + #if !defined(__INTEL_DISPLAY_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ) + #define __INTEL_DISPLAY_TRACE_H__ + ++#if defined(CONFIG_PREEMPT_RT) && !defined(NOTRACE) ++#define NOTRACE ++#endif ++ + #include + #include + #include +--- a/drivers/gpu/drm/i915/i915_trace.h ++++ b/drivers/gpu/drm/i915/i915_trace.h +@@ -6,6 +6,10 @@ + #if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) + #define _I915_TRACE_H_ + ++#if defined(CONFIG_PREEMPT_RT) && !defined(NOTRACE) ++#define NOTRACE ++#endif ++ + #include + #include + #include 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 76342bd2d7..30f4ed6cf3 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h -@@ -362,7 +362,7 @@ static inline int intel_guc_send_busy_lo +@@ -360,7 +360,7 @@ static inline int intel_guc_send_busy_lo { int err; unsigned int sleep_period_ms = 1; diff --git a/debian/patches-rt/drm-ttm-tests-Let-ttm_bo_test-consider-different-ww_.patch b/debian/patches-rt/drm-ttm-tests-Let-ttm_bo_test-consider-different-ww_.patch new file mode 100644 index 0000000000..13ce972247 --- /dev/null +++ b/debian/patches-rt/drm-ttm-tests-Let-ttm_bo_test-consider-different-ww_.patch @@ -0,0 +1,52 @@ +From: Sebastian Andrzej Siewior +Date: Thu, 4 Apr 2024 12:25:34 +0200 +Subject: [PATCH] drm/ttm/tests: Let ttm_bo_test consider different ww_mutex + implementation. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz + +PREEMPT_RT has a different locking implementation for ww_mutex. The +base mutex of struct ww_mutex is declared as struct WW_MUTEX_BASE. The +latter is defined as `mutex' for non-PREEMPT_RT builds and `rt_mutex' +for PREEMPT_RT builds. + +Using mutex_lock() directly on the base mutex in +ttm_bo_reserve_deadlock() leads to compile error on PREEMPT_RT. + +The locking-selftest has its own defines to deal with this and it is +probably best to defines the needed one within the test program since +their usefulness is limited outside of well known selftests. + +Provide ww_mutex_base_lock() which points to the correct function for +PREEMPT_RT and non-PREEMPT_RT builds. + +Fixes: 995279d280d1e ("drm/ttm/tests: Add tests for ttm_bo functions") +Link: https://lore.kernel.org/r/20240404102534.QTa80QPY@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/gpu/drm/ttm/tests/ttm_bo_test.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c ++++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +@@ -18,6 +18,12 @@ + + #define BO_SIZE SZ_8K + ++#ifdef CONFIG_PREEMPT_RT ++#define ww_mutex_base_lock(b) rt_mutex_lock(b) ++#else ++#define ww_mutex_base_lock(b) mutex_lock(b) ++#endif ++ + struct ttm_bo_test_case { + const char *description; + bool interruptible; +@@ -142,7 +148,7 @@ static void ttm_bo_reserve_deadlock(stru + bo2 = ttm_bo_kunit_init(test, test->priv, BO_SIZE); + + ww_acquire_init(&ctx1, &reservation_ww_class); +- mutex_lock(&bo2->base.resv->lock.base); ++ ww_mutex_base_lock(&bo2->base.resv->lock.base); + + /* The deadlock will be caught by WW mutex, don't warn about it */ + lock_release(&bo2->base.resv->lock.base.dep_map, 1); diff --git a/debian/patches-rt/pinctrl-renesas-rzg2l-Use-spin_-lock-unlock-_irq-sav.patch b/debian/patches-rt/pinctrl-renesas-rzg2l-Use-spin_-lock-unlock-_irq-sav.patch new file mode 100644 index 0000000000..3462fa28ef --- /dev/null +++ b/debian/patches-rt/pinctrl-renesas-rzg2l-Use-spin_-lock-unlock-_irq-sav.patch @@ -0,0 +1,38 @@ +From: Claudiu Beznea +Date: Wed, 22 May 2024 08:54:21 +0300 +Subject: [PATCH] pinctrl: renesas: rzg2l: Use + spin_{lock,unlock}_irq{save,restore} +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.10/older/patches-6.10-rc1-rt1.tar.xz + +On PREEMPT_RT kernels the spinlock_t maps to an rtmutex. Using +raw_spin_lock_irqsave()/raw_spin_unlock_irqrestore() on +&pctrl->lock.rlock breaks the PREEMPT_RT builds. To fix this use +spin_lock_irqsave()/spin_unlock_irqrestore() on &pctrl->lock. + +Fixes: 02cd2d3be1c3 ("pinctrl: renesas: rzg2l: Configure the interrupt type on resume") +Reported-by: Diederik de Haas +Closes: https://lore.kernel.org/all/131999629.KQPSlr0Zke@bagend +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20240522055421.2842689-1-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Sebastian Andrzej Siewior +--- + drivers/pinctrl/renesas/pinctrl-rzg2l.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c ++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +@@ -2069,11 +2069,11 @@ static void rzg2l_gpio_irq_restore(struc + * This has to be atomically executed to protect against a concurrent + * interrupt. + */ +- raw_spin_lock_irqsave(&pctrl->lock.rlock, flags); ++ spin_lock_irqsave(&pctrl->lock, flags); + ret = rzg2l_gpio_irq_set_type(data, irqd_get_trigger_type(data)); + if (!ret && !irqd_irq_disabled(data)) + rzg2l_gpio_irq_enable(data); +- raw_spin_unlock_irqrestore(&pctrl->lock.rlock, flags); ++ spin_unlock_irqrestore(&pctrl->lock, flags); + + if (ret) + dev_crit(pctrl->dev, "Failed to set IRQ type for virq=%u\n", virq); 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 e1c231f6cb..c151c8dc89 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 0b7d65c60a..0f642da4a1 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 Date: Fri Jul 26 11:30:49 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Sebastian Andrzej Siewior 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 871e35c564..222142d683 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 Date: Fri Apr 24 15:53:13 2015 +0000 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Bogdan Purcareata @@ -33,7 +33,7 @@ Signed-off-by: Thomas Gleixner --- --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig -@@ -222,6 +222,7 @@ config KVM_E500MC +@@ -221,6 +221,7 @@ config KVM_E500MC config KVM_MPIC bool "KVM in-kernel MPIC emulation" depends on KVM && PPC_E500 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 d88fbd396a..eda53cbb05 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 Date: Tue Mar 26 18:31:54 2019 +0100 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Sebastian Andrzej Siewior 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 f61851260e..3031f56343 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 Date: Tue Mar 26 18:31:29 2019 +0100 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Sebastian Andrzej Siewior 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 97f6c5b9bf..bd0a683cc6 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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, @@ -35,7 +35,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -610,6 +610,7 @@ extern void raise_softirq_irqoff(unsigne +@@ -613,6 +613,7 @@ extern void raise_softirq_irqoff(unsigne extern void raise_softirq(unsigned int nr); #ifdef CONFIG_PREEMPT_RT @@ -45,7 +45,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c -@@ -2409,6 +2409,12 @@ static int rcutorture_booster_init(unsig +@@ -2413,6 +2413,12 @@ static int rcutorture_booster_init(unsig WARN_ON_ONCE(!t); sp.sched_priority = 2; sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); @@ -60,7 +60,7 @@ Signed-off-by: Sebastian Andrzej Siewior /* Don't allow time recalculation while creating a new task. */ --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -620,7 +620,7 @@ static inline void tick_irq_exit(void) +@@ -625,7 +625,7 @@ static inline void tick_irq_exit(void) } #ifdef CONFIG_PREEMPT_RT diff --git a/debian/patches-rt/riscv-add-PREEMPT_AUTO-support.patch b/debian/patches-rt/riscv-add-PREEMPT_AUTO-support.patch index 0158d653a0..fb0322f9f3 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig -@@ -142,6 +142,7 @@ config RISCV +@@ -152,6 +152,7 @@ config RISCV select HAVE_PERF_USER_STACK_DUMP select HAVE_POSIX_CPU_TIMERS_TASK_WORK select HAVE_PREEMPT_DYNAMIC_KEY if !XIP_KERNEL diff --git a/debian/patches-rt/riscv-allow-to-enable-RT.patch b/debian/patches-rt/riscv-allow-to-enable-RT.patch index 4a8356d70f..346680179e 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz Now, it's ready to enable RT on riscv. @@ -13,8 +13,8 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig -@@ -49,6 +49,7 @@ config RISCV - select ARCH_SUPPORTS_HUGETLBFS if MMU +@@ -56,6 +56,7 @@ config RISCV + select ARCH_SUPPORTS_LTO_CLANG_THIN if LLD_VERSION >= 140000 select ARCH_SUPPORTS_PAGE_TABLE_CHECK if MMU select ARCH_SUPPORTS_PER_VMA_LOCK if MMU + select ARCH_SUPPORTS_RT 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 dd0fd1eb70..1a1bc95251 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 diff --git a/debian/patches-rt/series b/debian/patches-rt/series index 3429bdc302..4735031450 100644 --- a/debian/patches-rt/series +++ b/debian/patches-rt/series @@ -10,26 +10,6 @@ # Posted ########################################################################### -# 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 @@ -42,6 +22,11 @@ 0003-perf-Remove-perf_swevent_get_recursion_context-from-.patch 0004-perf-Split-__perf_pending_irq-out-of-perf_pending_ir.patch +# locking. +drm-ttm-tests-Let-ttm_bo_test-consider-different-ww_.patch + +pinctrl-renesas-rzg2l-Use-spin_-lock-unlock-_irq-sav.patch + ########################################################################### # Post ########################################################################### @@ -74,61 +59,61 @@ zram-Replace-bit-spinlocks-with-spinlock_t-for-PREEM.patch ########################################################################### # John's printk queue ########################################################################### -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 +0001-printk-Add-notation-to-console_srcu-locking.patch +0002-printk-Properly-deal-with-nbcon-consoles-on-seq-init.patch +0003-printk-nbcon-Remove-return-value-for-write_atomic.patch +0004-printk-Check-printk_deferred_enter-_exit-usage.patch +0005-printk-nbcon-Add-detailed-doc-for-write_atomic.patch +0006-printk-nbcon-Add-callbacks-to-synchronize-with-drive.patch +0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch +0008-serial-core-Provide-low-level-functions-to-lock-port.patch +0009-serial-core-Introduce-wrapper-to-set-uart_port-cons.patch +0010-console-Improve-console_srcu_read_flags-comments.patch +0011-nbcon-Provide-functions-for-drivers-to-acquire-conso.patch +0012-serial-core-Implement-processing-in-port-lock-wrappe.patch +0013-printk-nbcon-Do-not-rely-on-proxy-headers.patch +0014-printk-Make-console_is_usable-available-to-nbcon.patch +0015-printk-Let-console_is_usable-handle-nbcon.patch +0016-printk-Add-flags-argument-for-console_is_usable.patch +0017-printk-nbcon-Add-helper-to-assign-priority-based-on-.patch +0018-printk-nbcon-Provide-function-to-flush-using-write_a.patch +0019-printk-Track-registered-boot-consoles.patch +0020-printk-nbcon-Use-nbcon-consoles-in-console_flush_all.patch +0021-printk-nbcon-Add-unsafe-flushing-on-panic.patch +0022-printk-Avoid-console_lock-dance-if-no-legacy-or-boot.patch +0023-printk-Track-nbcon-consoles.patch +0024-printk-Coordinate-direct-printing-in-panic.patch +0025-printk-nbcon-Implement-emergency-sections.patch +0026-panic-Mark-emergency-section-in-warn.patch +0027-panic-Mark-emergency-section-in-oops.patch +0028-rcu-Mark-emergency-sections-in-rcu-stalls.patch +0029-lockdep-Mark-emergency-sections-in-lockdep-splats.patch +0030-printk-nbcon-Introduce-printing-kthreads.patch +0031-printk-Atomic-print-in-printk-context-on-shutdown.patch +0032-printk-nbcon-Add-context-to-console_is_usable.patch +0033-printk-nbcon-Add-printer-thread-wakeups.patch +0034-printk-nbcon-Stop-threads-on-shutdown-reboot.patch +0035-printk-nbcon-Start-printing-threads.patch +0036-printk-Provide-helper-for-message-prepending.patch +0037-printk-nbcon-Show-replay-message-on-takeover.patch +0038-proc-consoles-Add-notation-to-c_start-c_stop.patch +0039-proc-Add-nbcon-support-for-proc-consoles.patch +0040-tty-sysfs-Add-nbcon-support-for-active.patch +0041-printk-nbcon-Provide-function-to-reacquire-ownership.patch +0042-serial-8250-Switch-to-nbcon-console.patch +0043-serial-8250-Revert-drop-lockdep-annotation-from-seri.patch +0044-printk-Add-kthread-for-all-legacy-consoles.patch +0045-printk-Provide-threadprintk-boot-argument.patch +0046-printk-Avoid-false-positive-lockdep-report-for-legac.patch ########################################################################### # DRM: ########################################################################### +# https://lore.kernel.org/all/20240405142737.920626-1-bigeasy@linutronix.de/ 0003-drm-i915-Use-preempt_disable-enable_rt-where-recomme.patch 0004-drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch 0005-drm-i915-Don-t-check-for-atomic-context-on-PREEMPT_R.patch -0006-drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch -0007-drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch -0008-drm-i915-gt-Queue-and-wait-for-the-irq_work-item.patch +drm-i915-Disable-tracing-points-on-PREEMPT_RT.patch 0009-drm-i915-gt-Use-spin_lock_irq-instead-of-local_irq_d.patch 0010-drm-i915-Drop-the-irqs_disabled-check.patch drm-i915-guc-Consider-also-RCU-depth-in-busy-loop.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 a5f1a10093..fdfc59c52e 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -46,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -609,6 +609,22 @@ extern void __raise_softirq_irqoff(unsig +@@ -612,6 +612,22 @@ extern void __raise_softirq_irqoff(unsig extern void raise_softirq_irqoff(unsigned int nr); extern void raise_softirq(unsigned int nr); @@ -71,7 +71,7 @@ Signed-off-by: Sebastian Andrzej Siewior static inline struct task_struct *this_cpu_ksoftirqd(void) --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -619,6 +619,29 @@ static inline void tick_irq_exit(void) +@@ -624,6 +624,29 @@ static inline void tick_irq_exit(void) #endif } @@ -101,7 +101,7 @@ Signed-off-by: Sebastian Andrzej Siewior static inline void __irq_exit_rcu(void) { #ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED -@@ -628,8 +651,13 @@ static inline void __irq_exit_rcu(void) +@@ -633,8 +656,13 @@ static inline void __irq_exit_rcu(void) #endif account_hardirq_exit(current); preempt_count_sub(HARDIRQ_OFFSET); @@ -117,7 +117,7 @@ Signed-off-by: Sebastian Andrzej Siewior tick_irq_exit(); } -@@ -963,12 +991,70 @@ static struct smp_hotplug_thread softirq +@@ -972,12 +1000,70 @@ static struct smp_hotplug_thread softirq .thread_comm = "ksoftirqd/%u", }; @@ -191,7 +191,7 @@ Signed-off-by: Sebastian Andrzej Siewior early_initcall(spawn_ksoftirqd); --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1809,7 +1809,7 @@ void hrtimer_interrupt(struct clock_even +@@ -1812,7 +1812,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 } __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); -@@ -1922,7 +1922,7 @@ void hrtimer_run_queues(void) +@@ -1925,7 +1925,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,12 +211,12 @@ Signed-off-by: Sebastian Andrzej Siewior __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); --- a/kernel/time/timer.c +++ b/kernel/time/timer.c -@@ -2070,7 +2070,7 @@ static void run_local_timers(void) - if (time_before(jiffies, base->next_expiry)) +@@ -2466,7 +2466,7 @@ static void run_local_timers(void) + /* Raise the softirq only if required. */ + if (time_after_eq(jiffies, base->next_expiry) || + (i == BASE_DEF && tmigr_requires_handle_remote())) { +- raise_softirq(TIMER_SOFTIRQ); ++ raise_timer_softirq(); return; + } } -- raise_softirq(TIMER_SOFTIRQ); -+ raise_timer_softirq(); - } - - /* 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 0528a0e138..ef9bb04143 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -23,7 +23,7 @@ Signed-off-by: Sebastian Andrzej Siewior --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -646,13 +646,12 @@ static inline void __irq_exit_rcu(void) +@@ -651,13 +651,12 @@ static inline void __irq_exit_rcu(void) #endif account_hardirq_exit(current); preempt_count_sub(HARDIRQ_OFFSET); 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 8ae88f1168..966bb57692 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 Date: Sat Jul 30 21:55:53 2011 -0500 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Clark Williams @@ -25,9 +25,9 @@ Signed-off-by: Thomas Gleixner --- --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c -@@ -179,6 +179,15 @@ KERNEL_ATTR_RO(crash_elfcorehdr_size); +@@ -181,6 +181,15 @@ KERNEL_ATTR_RO(crash_elfcorehdr_size); - #endif /* CONFIG_CRASH_CORE */ + #endif /* CONFIG_VMCORE_INFO */ +#if defined(CONFIG_PREEMPT_RT) +static ssize_t realtime_show(struct kobject *kobj, @@ -41,7 +41,7 @@ Signed-off-by: Thomas Gleixner /* whether file capabilities are enabled */ static ssize_t fscaps_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -@@ -275,6 +284,9 @@ static struct attribute * kernel_attrs[] +@@ -279,6 +288,9 @@ static struct attribute * kernel_attrs[] &rcu_expedited_attr.attr, &rcu_normal_attr.attr, #endif 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 be10774fe2..7c62b746e2 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 @@ -48,7 +48,7 @@ Link: https://lkml.kernel.org/r/20220405010752.1347437-2-frederic@kernel.org --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -611,9 +611,16 @@ extern void raise_softirq(unsigned int n +@@ -614,9 +614,16 @@ extern void raise_softirq(unsigned int n #ifdef CONFIG_PREEMPT_RT DECLARE_PER_CPU(struct task_struct *, timersd); @@ -65,7 +65,7 @@ Link: https://lkml.kernel.org/r/20220405010752.1347437-2-frederic@kernel.org #else static inline void raise_timer_softirq(void) { -@@ -624,6 +631,11 @@ static inline void raise_hrtimer_softirq +@@ -627,6 +634,11 @@ static inline void raise_hrtimer_softirq { raise_softirq_irqoff(HRTIMER_SOFTIRQ); } @@ -79,7 +79,7 @@ Link: https://lkml.kernel.org/r/20220405010752.1347437-2-frederic@kernel.org DECLARE_PER_CPU(struct task_struct *, ksoftirqd); --- a/kernel/softirq.c +++ b/kernel/softirq.c -@@ -621,12 +621,7 @@ static inline void tick_irq_exit(void) +@@ -626,12 +626,7 @@ static inline void tick_irq_exit(void) #ifdef CONFIG_PREEMPT_RT DEFINE_PER_CPU(struct task_struct *, timersd); @@ -95,7 +95,7 @@ Link: https://lkml.kernel.org/r/20220405010752.1347437-2-frederic@kernel.org { --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c -@@ -796,7 +796,7 @@ static void tick_nohz_restart(struct tic +@@ -859,7 +859,7 @@ static void tick_nohz_restart(struct tic static inline bool local_timer_softirq_pending(void) { @@ -103,4 +103,4 @@ Link: https://lkml.kernel.org/r/20220405010752.1347437-2-frederic@kernel.org + return local_pending_timers() & BIT(TIMER_SOFTIRQ); } - static ktime_t tick_nohz_next_event(struct tick_sched *ts, int cpu) + /* diff --git a/debian/patches-rt/x86__Allow_to_enable_RT.patch b/debian/patches-rt/x86__Allow_to_enable_RT.patch index 9e900b332c..b24342b73e 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 Date: Wed Aug 7 18:15:38 2019 +0200 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Sebastian Andrzej Siewior 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 5f49eedcca..4cd4dd98e3 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 Date: Thu Nov 7 17:49:20 2019 +0100 -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz From: Sebastian Andrzej Siewior @@ -15,7 +15,7 @@ Signed-off-by: Thomas Gleixner --- --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -120,6 +120,7 @@ config X86 +@@ -121,6 +121,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 497f896e71..0151ca89f4 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 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.8/older/patches-6.8.2-rt11.tar.xz +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.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 -- cgit v1.2.3