Re: [PATCH Dovetail 6.18 1/3] arm64: irq_pipeline: Fix mapping of SGI/LPI IPIs

Florian Bezdeka
2026-02-03T16:05:31Z

On Tue, 2026-02-03 at 14:08 +0100, Philippe Gerum wrote:
> -static inline void map_oob_ipis(int cpu)
> +static inline void map_oob_ipis(int cpu, int offset)
> {
> int ipi;
>
> 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_irq_base + cpu * offset + ipi);
> }

I'm still quite sure that the loop is wrong and should be

+static inline void map_oob_ipis(int cpu, int offset)
{
int ipi;

- 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);
+ offset = ipi_irq_base + (cpu * offset);
+
+ for (ipi = OOB_IPI_OFFSET; ipi < nr_ipi; ipi++)
+ get_ipi_desc(cpu, ipi) = irq_to_desc(offset + ipi);
}

instead. (Note OOB_NR_IPI + OOB_IPI_OFFSET vs. nr_ipi)

Example:

static void arm64_send_ipi(const cpumask_t *mask, unsigned int nr)
{
unsigned int cpu;

if (!percpu_ipi_descs)
__ipi_send_mask(get_ipi_desc(0, nr), mask);

How should that work for IPI_IRQ_WORK? IPI_IRQ_WORK is located behind
the IPIs used for OOB and get_ipi_desc(0, IPI_IRQ_WORK) would return
NULL as we skipped the mapping in map_oob_ipis().

enum ipi_msg_type {
IPI_RESCHEDULE, // INBAND
IPI_CALL_FUNC, // OOB
IPI_CPU_STOP, // OOB
IPI_CPU_STOP_NMI, // OOB
IPI_TIMER, // Unmapped
IPI_IRQ_WORK, // Unmapped
NR_IPI,
/*
* Any enum >= NR_IPI and < MAX_IPI is special and not tracable
* with trace_ipi_*
*/
IPI_CPU_BACKTRACE = NR_IPI,
IPI_KGDB_ROUNDUP,
MAX_IPI
};

I agree that we can simplify the code a bit more, like you suggested.

Florian