* [PATCH Dovetail 6.18 v2 0/4] Fix IPI mapping for arm64
@ 2026-02-05 14:00 Florian Bezdeka
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 1/4] arm64: irq_pipeline: Fix mapping of IPIs in LPI mode Florian Bezdeka
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Florian Bezdeka @ 2026-02-05 14:00 UTC (permalink / raw)
To: xenomai; +Cc: Philippe Gerum, Jan Kiszka, Florian Bezdeka
Hi all,
this is the result of a quite longish debugging session revealed by some
sporadic failures seen in CI.
Please review carefully as the code paths around the KGDB and BACKTRACE IPI
are not part of the hot path.
Backporting:
Patches 2 and 3 should go into Dovetail 6.12 as well. Older versions do
not have the BACKTRACE and KGDB IPIs implemented.
Cc: Philippe Gerum <rpm@xenomai.org>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
Changes in v2:
- Patch 1: Reworked to address the LPI mapping issue only
- Patch 2: Unmodified
- Patch 3: Reworked to address the root cause properly
- Patch 4: New, address wrong IPI reason in tracepoint
- Link to v1: https://lore.kernel.org/r/20260201-wip-flo-fixes-for-6-18-v1-0-91ea07c7eb7e@siemens.com
---
Florian Bezdeka (4):
arm64: irq_pipeline: Fix mapping of IPIs in LPI mode
arm64: irq_pipeline: Fix size of IPI statistics array
arm64: irq_pipeline: Fix IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE IPIs
arm64: irq_pipeline: Fix tracepoint for multiplexed IPIs
arch/arm64/kernel/smp.c | 59 ++++++++++++++++++++++++++++++++-----------------
1 file changed, 39 insertions(+), 20 deletions(-)
---
base-commit: c30f265e8ac5feb0b7076141dd8877d0394e1437
change-id: 20260201-wip-flo-fixes-for-6-18-a2979277ddce
Best regards,
--
Florian Bezdeka <florian.bezdeka@siemens.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH Dovetail 6.18 v2 1/4] arm64: irq_pipeline: Fix mapping of IPIs in LPI mode
2026-02-05 14:00 [PATCH Dovetail 6.18 v2 0/4] Fix IPI mapping for arm64 Florian Bezdeka
@ 2026-02-05 14:00 ` Florian Bezdeka
2026-02-05 17:59 ` Philippe Gerum
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 2/4] arm64: irq_pipeline: Fix size of IPI statistics array Florian Bezdeka
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Florian Bezdeka @ 2026-02-05 14:00 UTC (permalink / raw)
To: xenomai; +Cc: Philippe Gerum, Jan Kiszka, Florian Bezdeka
In LPI mode everything was mapped to the IRQ descriptor of CPU 0,
which is wrong. Each CPU has its own IRQ/LPI used for multiplexing
inband IPIs.
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
arch/arm64/kernel/smp.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 3a12956580a35..52e9d29083fc1 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -1020,12 +1020,14 @@ static void do_handle_IPI(int ipinr)
#ifdef CONFIG_IRQ_PIPELINE
-static inline void map_oob_ipis(int cpu)
+static inline void map_oob_ipis(int cpu, int ipi_offset)
{
int ipi;
+ ipi_offset = ipi_irq_base + (cpu * ipi_offset);
+
for (ipi = OOB_IPI_OFFSET; ipi < OOB_NR_IPI + OOB_IPI_OFFSET; ipi++)
- get_ipi_desc(cpu, ipi) = irq_to_desc(ipi_irq_base + ipi);
+ get_ipi_desc(cpu, ipi) = irq_to_desc(ipi_offset + ipi);
}
static void ipi_setup_oob_sgi(void)
@@ -1033,7 +1035,7 @@ static void ipi_setup_oob_sgi(void)
int cpu;
for_each_possible_cpu(cpu)
- map_oob_ipis(cpu);
+ map_oob_ipis(cpu, 0);
}
static void ipi_setup_oob_lpi(int ncpus)
@@ -1041,7 +1043,7 @@ static void ipi_setup_oob_lpi(int ncpus)
int cpu;
for (cpu = 0; cpu < ncpus; cpu++)
- map_oob_ipis(cpu);
+ map_oob_ipis(cpu, nr_ipi);
}
static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH Dovetail 6.18 v2 2/4] arm64: irq_pipeline: Fix size of IPI statistics array
2026-02-05 14:00 [PATCH Dovetail 6.18 v2 0/4] Fix IPI mapping for arm64 Florian Bezdeka
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 1/4] arm64: irq_pipeline: Fix mapping of IPIs in LPI mode Florian Bezdeka
@ 2026-02-05 14:00 ` Florian Bezdeka
2026-02-05 17:59 ` Philippe Gerum
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 3/4] arm64: irq_pipeline: Fix IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE IPIs Florian Bezdeka
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 4/4] arm64: irq_pipeline: Fix tracepoint for multiplexed IPIs Florian Bezdeka
3 siblings, 1 reply; 9+ messages in thread
From: Florian Bezdeka @ 2026-02-05 14:00 UTC (permalink / raw)
To: xenomai; +Cc: Philippe Gerum, Jan Kiszka, Florian Bezdeka
NR_IPI is not the last possible IPI, it's the last traceable IPI.
IPI_CPU_BACKTRACE and IPI_KGDB_ROUNDUP are located behind NR_IPI,
so access to those counters were out of bounds.
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
arch/arm64/kernel/smp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 52e9d29083fc1..8d3791ed39e69 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -1054,7 +1054,7 @@ static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
static DEFINE_PER_CPU(unsigned long, ipi_messages);
-static DEFINE_PER_CPU(unsigned int [NR_IPI], ipi_counts);
+static DEFINE_PER_CPU(unsigned int [MAX_IPI], ipi_counts);
static irqreturn_t ipi_handler(int irq, void *data)
{
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH Dovetail 6.18 v2 3/4] arm64: irq_pipeline: Fix IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE IPIs
2026-02-05 14:00 [PATCH Dovetail 6.18 v2 0/4] Fix IPI mapping for arm64 Florian Bezdeka
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 1/4] arm64: irq_pipeline: Fix mapping of IPIs in LPI mode Florian Bezdeka
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 2/4] arm64: irq_pipeline: Fix size of IPI statistics array Florian Bezdeka
@ 2026-02-05 14:00 ` Florian Bezdeka
2026-02-05 18:53 ` Philippe Gerum
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 4/4] arm64: irq_pipeline: Fix tracepoint for multiplexed IPIs Florian Bezdeka
3 siblings, 1 reply; 9+ messages in thread
From: Florian Bezdeka @ 2026-02-05 14:00 UTC (permalink / raw)
To: xenomai; +Cc: Philippe Gerum, Jan Kiszka, Florian Bezdeka
Both IPIs (IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE) are multiplexed in
case the IRQ pipelining is enabled, so we have to set an IPI reason
in both cases.
Both cases were directly calling into the IRQ chip implementation and
forgot to set the reason. IPIs were ignored on the receiving side at
the end.
As tracing should be bypassed for all IRQs behind NR_IPI we can not
call smp_cross_call() - where setting the reason / ipi message takes
place.
Setting the reason has been factored out into set_ipi_message() which
can be called with and without IRQ pipelining.
In addition, it is not allowed to call arm64_send_ipi() with ipi != 0
when CONFIG_IRQ_PIPELINE is active. The following kernel splat is now
fixed as well:
[ 115.357495] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000048
[ 115.358088] Mem abort info:
[ 115.358216] ESR = 0x0000000096000004
[ 115.358394] EC = 0x25: DABT (current EL), IL = 32 bits
[ 115.358624] SET = 0, FnV = 0
[ 115.358762] EA = 0, S1PTW = 0
[ 115.358910] FSC = 0x04: level 0 translation fault
[ 115.359117] Data abort info:
[ 115.359254] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[ 115.359498] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 115.359718] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 115.359990] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000042d15000
[ 115.360386] [0000000000000048] pgd=0000000000000000, p4d=0000000000000000
[ 115.361730] Internal error: Oops: 0000000096000004 [#1] SMP
[ 115.361868] Modules linked in: cfg80211 rfkill drm fuse drm_panel_orientation_quirks ipv6
[ 115.362470] CPU: 1 UID: 0 PID: 15 Comm: rcu_preempt Not tainted 6.18.2 #1 PREEMPT
[ 115.362533] Hardware name: linux,dummy-virt (DT)
[ 115.362561] IRQ stage: Linux
[ 115.362746] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 115.362794] pc : __ipi_send_mask+0x18/0x108
[ 115.363335] lr : arm64_backtrace_ipi+0xa8/0xc0
[ 115.363372] sp : ffff80008215b840
[ 115.363388] x29: ffff80008215b840 x28: 0000000000000080 x27: ffff800081cfeec0
[ 115.363481] x26: ffff8000818b6000 x25: ffffffffffffffff x24: 0000000000000040
[ 115.363505] x23: 0000000000000001 x22: ffff800080041080 x21: ffff800082089d98
[ 115.363527] x20: ffff800081c72e40 x19: 0000000000000030 x18: 000000000000019b
[ 115.363548] x17: 74666f7320303030 x16: 3030303030303030 x15: 0000000000000001
[ 115.363569] x14: 0000000000000000 x13: 3a30207355504320 x12: ffff800081c8de70
[ 115.363590] x11: 0000000000000058 x10: 0000000000000018 x9 : ffff800081c8de70
[ 115.363633] x8 : 000000000000019c x7 : ffff800081ce5e70 x6 : ffff800081ce5e70
[ 115.363654] x5 : ffff00001fec25c8 x4 : 0000000000000000 x3 : 0000000000000000
[ 115.363674] x2 : ffff7fff9e316000 x1 : ffff800081c72e40 x0 : 0000000000000000
[ 115.363805] Call trace:
[ 115.364002] __ipi_send_mask+0x18/0x108 (P)
[ 115.364213] arm64_backtrace_ipi+0xa8/0xc0
[ 115.364266] nmi_trigger_cpumask_backtrace+0x1e0/0x1f4
[ 115.364295] arch_trigger_cpumask_backtrace+0x18/0x24
[ 115.364315] dump_cpu_task+0x74/0x80
[ 115.364337] rcu_dump_cpu_stacks+0x150/0x1b8
[ 115.364356] rcu_sched_clock_irq+0xc7c/0xebc
[ 115.364377] update_process_times+0x7c/0xe0
[ 115.364400] tick_nohz_handler+0xbc/0x150
[ 115.364420] __hrtimer_run_queues+0x168/0x2f0
[ 115.364436] hrtimer_interrupt+0xec/0x258
[ 115.364451] proxy_irq_handler+0x24/0x40
[ 115.364469] handle_synthetic_irq+0x94/0x1dc
[ 115.364503] handle_irq_desc+0x38/0x5c
[ 115.364521] arch_do_IRQ_pipelined+0x44/0x80
[ 115.364538] sync_current_irq_stage+0x160/0x200
[ 115.364555] __inband_irq_enable+0x5c/0x70
[ 115.364572] inband_irq_restore+0x28/0x40
[ 115.364589] resched_cpu+0x98/0xc0
[ 115.364606] force_qs_rnp+0x27c/0x34c
[ 115.364623] rcu_gp_fqs_loop+0x304/0x4c4
[ 115.364641] rcu_gp_kthread+0x130/0x15c
[ 115.364659] kthread+0x144/0x200
[ 115.364677] ret_from_fork+0x10/0x20
[ 115.364928] Code: 910003fd a90153f3 9100c013 a9025bf5 (f9400e75)
[ 115.365743] ---[ end trace 0000000000000000 ]---
[ 115.366033] Kernel panic - not syncing: Oops: Fatal exception in interrupt
[ 115.366216] SMP: stopping secondary CPUs
[ 116.728391] SMP: failed to stop secondary CPUs 0
[ 116.728668] Kernel Offset: disabled
[ 116.728691] CPU features: 0x082000,04046800,40004000,0400421b
[ 116.728736] Memory Limit: none
[ 116.739224] ---[ end Kernel panic - not syncing: Oops: Fatal exception in interrupt ]---
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
arch/arm64/kernel/smp.c | 38 +++++++++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 8d3791ed39e69..53ec370235f93 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -913,6 +913,24 @@ static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs
#endif
}
+#ifdef CONFIG_IRQ_PIPELINE
+
+DEFINE_PER_CPU(unsigned long, ipi_messages);
+
+static inline void set_ipi_message(const cpumask_t *target, unsigned int ipi)
+{
+ int cpu;
+
+ for_each_cpu(cpu, target)
+ set_bit(ipi, &per_cpu(ipi_messages, cpu));
+
+ wmb();
+}
+#else
+static inline void set_ipi_message(const cpumask_t *target, unsigned int ipi)
+{ }
+#endif
+
static void arm64_send_ipi(const cpumask_t *mask, unsigned int nr)
{
unsigned int cpu;
@@ -926,7 +944,10 @@ static void arm64_send_ipi(const cpumask_t *mask, unsigned int nr)
static void arm64_backtrace_ipi(cpumask_t *mask)
{
- arm64_send_ipi(mask, IPI_CPU_BACKTRACE);
+ int ipi = IS_ENABLED(CONFIG_IRQ_PIPELINE) ? 0 : IPI_CPU_BACKTRACE;
+
+ set_ipi_message(mask, IPI_CPU_BACKTRACE);
+ arm64_send_ipi(mask, ipi);
}
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
@@ -943,6 +964,7 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
#ifdef CONFIG_KGDB
void kgdb_roundup_cpus(void)
{
+ int ipi = IS_ENABLED(CONFIG_IRQ_PIPELINE) ? 0 : IPI_KGDB_ROUNDUP;
int this_cpu = raw_smp_processor_id();
int cpu;
@@ -951,7 +973,8 @@ void kgdb_roundup_cpus(void)
if (cpu == this_cpu)
continue;
- __ipi_send_single(get_ipi_desc(cpu, IPI_KGDB_ROUNDUP), cpu);
+ set_ipi_message(cpumask_of(cpu), IPI_KGDB_ROUNDUP);
+ __ipi_send_single(get_ipi_desc(cpu, ipi), cpu);
}
}
#endif
@@ -1052,8 +1075,6 @@ static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
arm64_send_ipi(target, ipinr);
}
-static DEFINE_PER_CPU(unsigned long, ipi_messages);
-
static DEFINE_PER_CPU(unsigned int [MAX_IPI], ipi_counts);
static irqreturn_t ipi_handler(int irq, void *data)
@@ -1063,7 +1084,7 @@ static irqreturn_t ipi_handler(int irq, void *data)
/*
* Decode in-band IPIs (0..NR_IPI - 1) multiplexed over
- * SGI0. Out-of-band IPIs (SGI1, SGI2) have their own
+ * SGI0. Out-of-band IPIs (SGI1, SGI2, SGI3) have their own
* individual handler.
*/
pmsg = raw_cpu_ptr(&ipi_messages);
@@ -1079,13 +1100,8 @@ static irqreturn_t ipi_handler(int irq, void *data)
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
{
- unsigned int cpu;
-
/* regular in-band IPI (multiplexed over SGI0). */
- for_each_cpu(cpu, target)
- set_bit(ipinr, &per_cpu(ipi_messages, cpu));
-
- wmb();
+ set_ipi_message(target, ipinr);
__smp_cross_call(target, 0);
}
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH Dovetail 6.18 v2 4/4] arm64: irq_pipeline: Fix tracepoint for multiplexed IPIs
2026-02-05 14:00 [PATCH Dovetail 6.18 v2 0/4] Fix IPI mapping for arm64 Florian Bezdeka
` (2 preceding siblings ...)
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 3/4] arm64: irq_pipeline: Fix IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE IPIs Florian Bezdeka
@ 2026-02-05 14:00 ` Florian Bezdeka
2026-02-05 19:03 ` Philippe Gerum
3 siblings, 1 reply; 9+ messages in thread
From: Florian Bezdeka @ 2026-02-05 14:00 UTC (permalink / raw)
To: xenomai; +Cc: Philippe Gerum, Jan Kiszka, Florian Bezdeka
When IRQ pipelining is enabled the reason for an IPI was always set
to IPI_RESCHEDULE as this is the IPI used for multiplexing all the
inband IPIs via a single SGI/LPI.
Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
---
arch/arm64/kernel/smp.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 53ec370235f93..39499b9797923 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -1069,9 +1069,10 @@ static void ipi_setup_oob_lpi(int ncpus)
map_oob_ipis(cpu, nr_ipi);
}
-static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
+static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr,
+ unsigned int msg)
{
- trace_ipi_raise(target, ipi_types[ipinr]);
+ trace_ipi_raise(target, ipi_types[msg]);
arm64_send_ipi(target, ipinr);
}
@@ -1102,7 +1103,7 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
{
/* regular in-band IPI (multiplexed over SGI0). */
set_ipi_message(target, ipinr);
- __smp_cross_call(target, 0);
+ __smp_cross_call(target, 0, ipinr);
}
static unsigned int get_ipi_count(int ipi, unsigned int cpu)
@@ -1120,7 +1121,7 @@ void irq_send_oob_ipi(unsigned int irq, const struct cpumask *cpumask)
return;
/* Out-of-band IPI (SGI1-3). */
- __smp_cross_call(cpumask, sgi);
+ __smp_cross_call(cpumask, sgi, sgi);
}
EXPORT_SYMBOL_GPL(irq_send_oob_ipi);
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH Dovetail 6.18 v2 1/4] arm64: irq_pipeline: Fix mapping of IPIs in LPI mode
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 1/4] arm64: irq_pipeline: Fix mapping of IPIs in LPI mode Florian Bezdeka
@ 2026-02-05 17:59 ` Philippe Gerum
0 siblings, 0 replies; 9+ messages in thread
From: Philippe Gerum @ 2026-02-05 17:59 UTC (permalink / raw)
To: Florian Bezdeka; +Cc: xenomai, Jan Kiszka
Florian Bezdeka <florian.bezdeka@siemens.com> writes:
> In LPI mode everything was mapped to the IRQ descriptor of CPU 0,
> which is wrong. Each CPU has its own IRQ/LPI used for multiplexing
> inband IPIs.
>
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> ---
> arch/arm64/kernel/smp.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 3a12956580a35..52e9d29083fc1 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -1020,12 +1020,14 @@ static void do_handle_IPI(int ipinr)
>
> #ifdef CONFIG_IRQ_PIPELINE
>
> -static inline void map_oob_ipis(int cpu)
> +static inline void map_oob_ipis(int cpu, int ipi_offset)
> {
> int ipi;
>
> + ipi_offset = ipi_irq_base + (cpu * ipi_offset);
> +
> for (ipi = OOB_IPI_OFFSET; ipi < OOB_NR_IPI + OOB_IPI_OFFSET; ipi++)
> - get_ipi_desc(cpu, ipi) = irq_to_desc(ipi_irq_base + ipi);
> + get_ipi_desc(cpu, ipi) = irq_to_desc(ipi_offset + ipi);
> }
>
> static void ipi_setup_oob_sgi(void)
> @@ -1033,7 +1035,7 @@ static void ipi_setup_oob_sgi(void)
> int cpu;
>
> for_each_possible_cpu(cpu)
> - map_oob_ipis(cpu);
> + map_oob_ipis(cpu, 0);
> }
>
> static void ipi_setup_oob_lpi(int ncpus)
> @@ -1041,7 +1043,7 @@ static void ipi_setup_oob_lpi(int ncpus)
> int cpu;
>
> for (cpu = 0; cpu < ncpus; cpu++)
> - map_oob_ipis(cpu);
> + map_oob_ipis(cpu, nr_ipi);
> }
>
> static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
Ack.
--
Philippe.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH Dovetail 6.18 v2 2/4] arm64: irq_pipeline: Fix size of IPI statistics array
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 2/4] arm64: irq_pipeline: Fix size of IPI statistics array Florian Bezdeka
@ 2026-02-05 17:59 ` Philippe Gerum
0 siblings, 0 replies; 9+ messages in thread
From: Philippe Gerum @ 2026-02-05 17:59 UTC (permalink / raw)
To: Florian Bezdeka; +Cc: xenomai, Jan Kiszka
Florian Bezdeka <florian.bezdeka@siemens.com> writes:
> NR_IPI is not the last possible IPI, it's the last traceable IPI.
> IPI_CPU_BACKTRACE and IPI_KGDB_ROUNDUP are located behind NR_IPI,
> so access to those counters were out of bounds.
>
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> ---
> arch/arm64/kernel/smp.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 52e9d29083fc1..8d3791ed39e69 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -1054,7 +1054,7 @@ static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
>
> static DEFINE_PER_CPU(unsigned long, ipi_messages);
>
> -static DEFINE_PER_CPU(unsigned int [NR_IPI], ipi_counts);
> +static DEFINE_PER_CPU(unsigned int [MAX_IPI], ipi_counts);
>
> static irqreturn_t ipi_handler(int irq, void *data)
> {
Ack.
--
Philippe.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH Dovetail 6.18 v2 3/4] arm64: irq_pipeline: Fix IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE IPIs
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 3/4] arm64: irq_pipeline: Fix IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE IPIs Florian Bezdeka
@ 2026-02-05 18:53 ` Philippe Gerum
0 siblings, 0 replies; 9+ messages in thread
From: Philippe Gerum @ 2026-02-05 18:53 UTC (permalink / raw)
To: Florian Bezdeka; +Cc: xenomai, Jan Kiszka
Florian Bezdeka <florian.bezdeka@siemens.com> writes:
> Both IPIs (IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE) are multiplexed in
> case the IRQ pipelining is enabled, so we have to set an IPI reason
> in both cases.
>
> Both cases were directly calling into the IRQ chip implementation and
> forgot to set the reason. IPIs were ignored on the receiving side at
> the end.
>
> As tracing should be bypassed for all IRQs behind NR_IPI we can not
> call smp_cross_call() - where setting the reason / ipi message takes
> place.
>
> Setting the reason has been factored out into set_ipi_message() which
> can be called with and without IRQ pipelining.
>
> In addition, it is not allowed to call arm64_send_ipi() with ipi != 0
> when CONFIG_IRQ_PIPELINE is active. The following kernel splat is now
> fixed as well:
>
[snip]
> static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> {
> - unsigned int cpu;
> -
> /* regular in-band IPI (multiplexed over SGI0). */
> - for_each_cpu(cpu, target)
> - set_bit(ipinr, &per_cpu(ipi_messages, cpu));
> -
> - wmb();
> + set_ipi_message(target, ipinr);
> __smp_cross_call(target, 0);
> }
Given the significant amount of time and consequential hair loss
invested in debugging this issue, I would recommend to protect against
overlooking new calls to arm64_send_ipi() which upstream might add in
the future.
For instance (happily untested):
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 3a12956580a35..8acbdce764dfd 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -72,6 +72,15 @@ struct ipi_descs {
struct irq_desc *descs[MAX_IPI];
};
+typedef struct ipi_index { unsigned int sgi; } ipi_index_t;
+
+static inline unsigned int ipi_index(ipi_index_t ipi)
+{
+ return ipi.sgi;
+}
+
+static inline ipi_index_t mkipi_inband(unsigned int ipi);
+
static DEFINE_PER_CPU_READ_MOSTLY(struct ipi_descs, pcpu_ipi_desc);
#define get_ipi_desc(__cpu, __ipi) (per_cpu_ptr(&pcpu_ipi_desc, __cpu)->descs[__ipi])
@@ -913,20 +922,20 @@ static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs
#endif
}
-static void arm64_send_ipi(const cpumask_t *mask, unsigned int nr)
+static void arm64_send_ipi(const cpumask_t *mask, ipi_index_t ipi)
{
unsigned int cpu;
if (!percpu_ipi_descs)
- __ipi_send_mask(get_ipi_desc(0, nr), mask);
+ __ipi_send_mask(get_ipi_desc(0, ipi_index(ipi)), mask);
else
for_each_cpu(cpu, mask)
- __ipi_send_single(get_ipi_desc(cpu, nr), cpu);
+ __ipi_send_single(get_ipi_desc(cpu, ipi_index(ipi)), cpu);
}
static void arm64_backtrace_ipi(cpumask_t *mask)
{
- arm64_send_ipi(mask, IPI_CPU_BACKTRACE);
+ arm64_send_ipi(mask, mkipi_inband(IPI_CPU_BACKTRACE));
}
void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
@@ -1020,6 +1029,18 @@ static void do_handle_IPI(int ipinr)
#ifdef CONFIG_IRQ_PIPELINE
+static inline ipi_index_t mkipi_inband(unsigned int ipi)
+{
+ WARN_ON(ipi >= OOB_IPI_OFFSET);
+ return (struct ipi_index){ .sgi = ipi };
+}
+
+static inline ipi_index_t mkipi_oob(unsigned int ipi)
+{
+ WARN_ON(ipi < OOB_IPI_OFFSET || ipi > OOB_IPI_OFFSET + OOB_NR_IPI - 1);
+ return (struct ipi_index){ .sgi = ipi };
+}
+
static inline void map_oob_ipis(int cpu)
{
int ipi;
@@ -1044,12 +1065,6 @@ static void ipi_setup_oob_lpi(int ncpus)
map_oob_ipis(cpu);
}
-static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
-{
- trace_ipi_raise(target, ipi_types[ipinr]);
- arm64_send_ipi(target, ipinr);
-}
-
static DEFINE_PER_CPU(unsigned long, ipi_messages);
static DEFINE_PER_CPU(unsigned int [NR_IPI], ipi_counts);
@@ -1084,7 +1099,8 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
set_bit(ipinr, &per_cpu(ipi_messages, cpu));
wmb();
- __smp_cross_call(target, 0);
+ trace_ipi_raise(target, ipi_types[0]);
+ arm64_send_ipi(target, mkipi_inband(0));
}
static unsigned int get_ipi_count(int ipi, unsigned int cpu)
@@ -1092,22 +1108,30 @@ static unsigned int get_ipi_count(int ipi, unsigned int cpu)
return per_cpu(ipi_counts, cpu)[ipi];
}
-void irq_send_oob_ipi(unsigned int irq, const struct cpumask *cpumask)
+void irq_send_oob_ipi(unsigned int irq, const struct cpumask *target)
{
- unsigned int sgi = irq - ipi_irq_base;
-
- if (WARN_ON(irq_pipeline_debug() &&
- (sgi < OOB_IPI_OFFSET ||
- sgi >= OOB_IPI_OFFSET + OOB_NR_IPI)))
- return;
+ unsigned int ipi = irq - ipi_irq_base;
/* Out-of-band IPI (SGI1-3). */
- __smp_cross_call(cpumask, sgi);
+ wmb();
+ trace_ipi_raise(target, ipi_types[ipi]);
+ arm64_send_ipi(target, mkipi_oob(ipi));
}
EXPORT_SYMBOL_GPL(irq_send_oob_ipi);
#else
+static inline ipi_index_t mkipi_inband(unsigned int ipi)
+{
+ WARN_ON(ipi >= MAX_IPI);
+ return (struct ipi_index_t){ .sgi = ipi };
+}
+
+static inline ipi_index_t mkipi_oob(unsigned int ipi)
+{
+ BUG();
+}
+
static inline void ipi_setup_oob_sgi(void)
{ }
@@ -1125,7 +1149,7 @@ static irqreturn_t ipi_handler(int irq, void *data)
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
{
trace_ipi_raise(target, ipi_types[ipinr]);
- arm64_send_ipi(target, ipinr);
+ arm64_send_ipi(target, mkipi_inband(ipinr));
}
static unsigned int get_ipi_count(int ipi, unsigned int cpu)
--
Philippe.
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH Dovetail 6.18 v2 4/4] arm64: irq_pipeline: Fix tracepoint for multiplexed IPIs
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 4/4] arm64: irq_pipeline: Fix tracepoint for multiplexed IPIs Florian Bezdeka
@ 2026-02-05 19:03 ` Philippe Gerum
0 siblings, 0 replies; 9+ messages in thread
From: Philippe Gerum @ 2026-02-05 19:03 UTC (permalink / raw)
To: Florian Bezdeka; +Cc: xenomai, Jan Kiszka
Florian Bezdeka <florian.bezdeka@siemens.com> writes:
> When IRQ pipelining is enabled the reason for an IPI was always set
> to IPI_RESCHEDULE as this is the IPI used for multiplexing all the
> inband IPIs via a single SGI/LPI.
>
> Signed-off-by: Florian Bezdeka <florian.bezdeka@siemens.com>
> ---
> arch/arm64/kernel/smp.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 53ec370235f93..39499b9797923 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -1069,9 +1069,10 @@ static void ipi_setup_oob_lpi(int ncpus)
> map_oob_ipis(cpu, nr_ipi);
> }
>
> -static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> +static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr,
> + unsigned int msg)
> {
> - trace_ipi_raise(target, ipi_types[ipinr]);
> + trace_ipi_raise(target, ipi_types[msg]);
> arm64_send_ipi(target, ipinr);
> }
>
> @@ -1102,7 +1103,7 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> {
> /* regular in-band IPI (multiplexed over SGI0). */
> set_ipi_message(target, ipinr);
> - __smp_cross_call(target, 0);
> + __smp_cross_call(target, 0, ipinr);
> }
>
> static unsigned int get_ipi_count(int ipi, unsigned int cpu)
> @@ -1120,7 +1121,7 @@ void irq_send_oob_ipi(unsigned int irq, const struct cpumask *cpumask)
> return;
>
> /* Out-of-band IPI (SGI1-3). */
> - __smp_cross_call(cpumask, sgi);
> + __smp_cross_call(cpumask, sgi, sgi);
> }
> EXPORT_SYMBOL_GPL(irq_send_oob_ipi);
Given the added complexity, I would rather not factor __smp_cross_call()
out anymore, open coding it in smp_cross_call() and irq_send_oob_ipi()
instead.
--
Philippe.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-02-05 19:03 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-05 14:00 [PATCH Dovetail 6.18 v2 0/4] Fix IPI mapping for arm64 Florian Bezdeka
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 1/4] arm64: irq_pipeline: Fix mapping of IPIs in LPI mode Florian Bezdeka
2026-02-05 17:59 ` Philippe Gerum
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 2/4] arm64: irq_pipeline: Fix size of IPI statistics array Florian Bezdeka
2026-02-05 17:59 ` Philippe Gerum
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 3/4] arm64: irq_pipeline: Fix IPI_KGDB_ROUNDUP and IPI_CPU_BACKTRACE IPIs Florian Bezdeka
2026-02-05 18:53 ` Philippe Gerum
2026-02-05 14:00 ` [PATCH Dovetail 6.18 v2 4/4] arm64: irq_pipeline: Fix tracepoint for multiplexed IPIs Florian Bezdeka
2026-02-05 19:03 ` Philippe Gerum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox