From: Jonas Jelonek Date: Tue, 16 Jun 2026 10:47:25 +0000 (+0000) Subject: generic: mips: replace pending patch with backport X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a0e6aa95c122cb33c7828fd27ea0dbf56abca5c;p=thirdparty%2Fopenwrt.git generic: mips: replace pending patch with backport The pending patch fixing reboot behavior on Realtek MIPS (and possibly other MIPS targets) has been accepted upstream. Replace with a proper backport. Link: https://github.com/openwrt/openwrt/pull/23831 Signed-off-by: Jonas Jelonek --- diff --git a/target/linux/generic/backport-6.18/300-v7.2-MIPS-smp-report-dying-CPU-to-RCU-in-stop_this_cpu.patch b/target/linux/generic/backport-6.18/300-v7.2-MIPS-smp-report-dying-CPU-to-RCU-in-stop_this_cpu.patch new file mode 100644 index 00000000000..8f419e2fe46 --- /dev/null +++ b/target/linux/generic/backport-6.18/300-v7.2-MIPS-smp-report-dying-CPU-to-RCU-in-stop_this_cpu.patch @@ -0,0 +1,66 @@ +From 9f3f3bdc6d9dac1a5a8262ee7ad0f2ff1527a7e7 Mon Sep 17 00:00:00 2001 +From: Jonas Jelonek +Date: Mon, 8 Jun 2026 09:37:29 +0000 +Subject: MIPS: smp: report dying CPU to RCU in stop_this_cpu() + +smp_send_stop() parks all secondary CPUs in stop_this_cpu(). The function +marks the CPU offline for the scheduler via set_cpu_online(false) but +never informs RCU, so RCU keeps expecting a quiescent state from CPUs +that are now spinning forever with interrupts disabled. + +As long as nothing waits for an RCU grace period after smp_send_stop() +this is harmless, which is why it went unnoticed. Since commit +91840be8f710 ("irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT") +however, irq_work_sync() calls synchronize_rcu() on architectures without +an irq_work self-IPI, i.e. where arch_irq_work_has_interrupt() returns +false. That is the asm-generic default used by MIPS. Any irq_work_sync() +issued in the reboot/shutdown path after smp_send_stop() then blocks on +a grace period that can never complete, hanging the reboot: + + WARNING: CPU: 0 PID: 15 at kernel/irq_work.c:144 irq_work_queue_on + ... + rcu: INFO: rcu_sched detected stalls on CPUs/tasks: + rcu: Offline CPU 1 blocking current GP. + rcu: Offline CPU 2 blocking current GP. + rcu: Offline CPU 3 blocking current GP. + +This issue was noticed on several Realtek MIPS switch SoCs (MIPS +interAptiv) and came up during kernel bump downstream in OpenWrt from +6.18.33 to 6.18.34, after the backport of the patch to the 6.18 stable +branch. The patch also has been backported all the way back to 6.1. + +Call rcutree_report_cpu_dead() once interrupts are disabled, mirroring the +generic CPU-hotplug offline path, so RCU stops waiting on the parked CPUs +and grace periods can still complete. MIPS shuts down all CPUs here +without going through the CPU-hotplug mechanism, so this report is not +otherwise issued. Reporting a dying CPU to RCU outside the regular hotplug +offline path is not unprecedented: arm64 does the same in cpu_die_early(). +There it is an exception for a CPU that was coming online and is aborting +bringup, rather than the default shutdown action as on MIPS. + +Fixes: 91840be8f710 ("irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT") +CC: stable@vger.kernel.org +Signed-off-by: Jonas Jelonek +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/kernel/smp.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/mips/kernel/smp.c ++++ b/arch/mips/kernel/smp.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -422,6 +423,7 @@ static void stop_this_cpu(void *dummy) + set_cpu_online(smp_processor_id(), false); + calculate_cpu_foreign_map(); + local_irq_disable(); ++ rcutree_report_cpu_dead(); + while (1); + } + diff --git a/target/linux/generic/pending-6.18/331-MIPS-smp-report-dying-CPU-to-RCU-in-stop_this_cpu.patch b/target/linux/generic/pending-6.18/331-MIPS-smp-report-dying-CPU-to-RCU-in-stop_this_cpu.patch deleted file mode 100644 index fc8cf0f5da6..00000000000 --- a/target/linux/generic/pending-6.18/331-MIPS-smp-report-dying-CPU-to-RCU-in-stop_this_cpu.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jonas Jelonek -Date: Thu, 04 Jun 2026 00:00:00 +0200 -Subject: [PATCH] MIPS: smp: report dying CPU to RCU in stop_this_cpu() - -smp_send_stop() parks all secondary CPUs in stop_this_cpu(). The function -marks the CPU offline for the scheduler via set_cpu_online(false) but never -informs RCU, so RCU keeps expecting a quiescent state from CPUs that are -now spinning forever with interrupts disabled. - -As long as nothing waits for an RCU grace period after smp_send_stop() this -is harmless, which is why it went unnoticed. Since v6.18.34, however, -irq_work_sync() calls synchronize_rcu() on architectures without an -irq_work self-IPI, i.e. where arch_irq_work_has_interrupt() returns false. -That is the asm-generic default used by MIPS. Any irq_work_sync() issued in -the reboot/shutdown path after smp_send_stop() then blocks on a grace period -that can never complete, hanging the reboot: - - WARNING: CPU: 0 PID: 15 at kernel/irq_work.c:144 irq_work_queue_on - ... - rcu: INFO: rcu_sched detected stalls on CPUs/tasks: - rcu: Offline CPU 1 blocking current GP. - rcu: Offline CPU 2 blocking current GP. - rcu: Offline CPU 3 blocking current GP. - -Call rcutree_report_cpu_dead() once interrupts are disabled, mirroring the -generic CPU-hotplug offline path (and arm64's stop handling), so RCU stops -waiting on the parked CPUs and grace periods can still complete. - -Fixes: 91840be8f710 ("irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT") -Signed-off-by: Jonas Jelonek ---- - arch/mips/kernel/smp.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/mips/kernel/smp.c -+++ b/arch/mips/kernel/smp.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -422,6 +423,7 @@ static void stop_this_cpu(void *dummy) - set_cpu_online(smp_processor_id(), false); - calculate_cpu_foreign_map(); - local_irq_disable(); -+ rcutree_report_cpu_dead(); - while (1); - } -