]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Jun 2024 09:34:47 +0000 (11:34 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Jun 2024 09:34:47 +0000 (11:34 +0200)
added patches:
tick-nohz_full-don-t-abuse-smp_call_function_single-in-tick_setup_device.patch

queue-5.10/series
queue-5.10/tick-nohz_full-don-t-abuse-smp_call_function_single-in-tick_setup_device.patch [new file with mode: 0644]

index cd95455766f5b195dc02cc879b69446d3b9942c7..ec845cfe5282ba6e2e3d4ab311eabc129928e8b8 100644 (file)
@@ -122,3 +122,4 @@ intel_th-pci-add-sapphire-rapids-soc-support.patch
 intel_th-pci-add-meteor-lake-s-support.patch
 intel_th-pci-add-lunar-lake-support.patch
 nilfs2-fix-potential-kernel-bug-due-to-lack-of-writeback-flag-waiting.patch
+tick-nohz_full-don-t-abuse-smp_call_function_single-in-tick_setup_device.patch
diff --git a/queue-5.10/tick-nohz_full-don-t-abuse-smp_call_function_single-in-tick_setup_device.patch b/queue-5.10/tick-nohz_full-don-t-abuse-smp_call_function_single-in-tick_setup_device.patch
new file mode 100644 (file)
index 0000000..3967840
--- /dev/null
@@ -0,0 +1,94 @@
+From 07c54cc5988f19c9642fd463c2dbdac7fc52f777 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Tue, 28 May 2024 14:20:19 +0200
+Subject: tick/nohz_full: Don't abuse smp_call_function_single() in tick_setup_device()
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 07c54cc5988f19c9642fd463c2dbdac7fc52f777 upstream.
+
+After the recent commit 5097cbcb38e6 ("sched/isolation: Prevent boot crash
+when the boot CPU is nohz_full") the kernel no longer crashes, but there is
+another problem.
+
+In this case tick_setup_device() calls tick_take_do_timer_from_boot() to
+update tick_do_timer_cpu and this triggers the WARN_ON_ONCE(irqs_disabled)
+in smp_call_function_single().
+
+Kill tick_take_do_timer_from_boot() and just use WRITE_ONCE(), the new
+comment explains why this is safe (thanks Thomas!).
+
+Fixes: 08ae95f4fd3b ("nohz_full: Allow the boot CPU to be nohz_full")
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240528122019.GA28794@redhat.com
+Link: https://lore.kernel.org/all/20240522151742.GA10400@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/tick-common.c |   42 ++++++++++++++----------------------------
+ 1 file changed, 14 insertions(+), 28 deletions(-)
+
+--- a/kernel/time/tick-common.c
++++ b/kernel/time/tick-common.c
+@@ -177,26 +177,6 @@ void tick_setup_periodic(struct clock_ev
+       }
+ }
+-#ifdef CONFIG_NO_HZ_FULL
+-static void giveup_do_timer(void *info)
+-{
+-      int cpu = *(unsigned int *)info;
+-
+-      WARN_ON(tick_do_timer_cpu != smp_processor_id());
+-
+-      tick_do_timer_cpu = cpu;
+-}
+-
+-static void tick_take_do_timer_from_boot(void)
+-{
+-      int cpu = smp_processor_id();
+-      int from = tick_do_timer_boot_cpu;
+-
+-      if (from >= 0 && from != cpu)
+-              smp_call_function_single(from, giveup_do_timer, &cpu, 1);
+-}
+-#endif
+-
+ /*
+  * Setup the tick device
+  */
+@@ -220,19 +200,25 @@ static void tick_setup_device(struct tic
+                       tick_next_period = ktime_get();
+ #ifdef CONFIG_NO_HZ_FULL
+                       /*
+-                       * The boot CPU may be nohz_full, in which case set
+-                       * tick_do_timer_boot_cpu so the first housekeeping
+-                       * secondary that comes up will take do_timer from
+-                       * us.
++                       * The boot CPU may be nohz_full, in which case the
++                       * first housekeeping secondary will take do_timer()
++                       * from it.
+                        */
+                       if (tick_nohz_full_cpu(cpu))
+                               tick_do_timer_boot_cpu = cpu;
+-              } else if (tick_do_timer_boot_cpu != -1 &&
+-                                              !tick_nohz_full_cpu(cpu)) {
+-                      tick_take_do_timer_from_boot();
++              } else if (tick_do_timer_boot_cpu != -1 && !tick_nohz_full_cpu(cpu)) {
+                       tick_do_timer_boot_cpu = -1;
+-                      WARN_ON(tick_do_timer_cpu != cpu);
++                      /*
++                       * The boot CPU will stay in periodic (NOHZ disabled)
++                       * mode until clocksource_done_booting() called after
++                       * smp_init() selects a high resolution clocksource and
++                       * timekeeping_notify() kicks the NOHZ stuff alive.
++                       *
++                       * So this WRITE_ONCE can only race with the READ_ONCE
++                       * check in tick_periodic() but this race is harmless.
++                       */
++                      WRITE_ONCE(tick_do_timer_cpu, cpu);
+ #endif
+               }