Re: [PATCH 2/2] alpha: marvel: Fix lock ordering in init_io7_irqs()
Magnus Lindholm <[email protected]> Fri, 29 May 2026 12:16:56 +0200
| Newsgroups | org.kernel.vger.linux-alpha,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <CA+=Fv5SisLyZRfemTxeTnXoh6-uRvVOsv5r3A=mcCjuvGzWfcQ@mail.gmail.com> |
On Fri, May 29, 2026 at 1:05 AM Matt Turner <[email protected]> wrote: > > Move irq_set_chip_and_handler() and irq_set_status_flags() calls > outside the io7->irq_lock raw spinlock. These functions take > sparse_irq_lock, which is a mutex, and taking a sleeping lock while > holding a raw spinlock is invalid. The raw spinlock only needs to > protect the hardware CSR accesses. > > This fixes the following lockdep splat during boot: > > [ BUG: Invalid wait context ] > swapper/0/0 is trying to lock: > sparse_irq_lock{....}-{4:4}, at: irq_mark_irq > other info that might help us debug this: > context-{5:5} > 1 lock held by swapper/0/0: > #0: &io7->irq_lock{....}-{2:2}, at: init_io7_irqs.constprop.0 > > Cc: [email protected] > Assisted-by: Claude:claude-opus-4-6 > Signed-off-by: Matt Turner <[email protected]> > --- > arch/alpha/kernel/sys_marvel.c | 25 ++++++++++++------------- > 1 file changed, 12 insertions(+), 13 deletions(-) > > diff --git ./arch/alpha/kernel/sys_marvel.c ./arch/alpha/kernel/sys_marvel.c > index bebeea3c286d..a37707e05e34 100644 > --- ./arch/alpha/kernel/sys_marvel.c > +++ ./arch/alpha/kernel/sys_marvel.c > @@ -263,6 +263,18 @@ init_io7_irqs(struct io7 *io7, > */ > printk(" Interrupts reported to CPU at PE %u\n", boot_cpuid); > > + /* Set up the lsi irqs. */ > + for (i = 0; i < 128; ++i) { > + irq_set_chip_and_handler(base + i, lsi_ops, handle_level_irq); > + irq_set_status_flags(base + i, IRQ_LEVEL); > + } > + > + /* Set up the msi irqs. */ > + for (i = 128; i < (128 + 512); ++i) { > + irq_set_chip_and_handler(base + i, msi_ops, handle_level_irq); > + irq_set_status_flags(base + i, IRQ_LEVEL); > + } > + > raw_spin_lock(&io7->irq_lock); > > /* set up the error irqs */ > @@ -272,12 +284,6 @@ init_io7_irqs(struct io7 *io7, > io7_redirect_irq(io7, &io7->csrs->STV_CTL.csr, boot_cpuid); > io7_redirect_irq(io7, &io7->csrs->HEI_CTL.csr, boot_cpuid); > > - /* Set up the lsi irqs. */ > - for (i = 0; i < 128; ++i) { > - irq_set_chip_and_handler(base + i, lsi_ops, handle_level_irq); > - irq_set_status_flags(base + i, IRQ_LEVEL); > - } > - > /* Disable the implemented irqs in hardware. */ > for (i = 0; i < 0x60; ++i) > init_one_io7_lsi(io7, i, boot_cpuid); > @@ -285,13 +291,6 @@ init_io7_irqs(struct io7 *io7, > init_one_io7_lsi(io7, 0x74, boot_cpuid); > init_one_io7_lsi(io7, 0x75, boot_cpuid); > > - > - /* Set up the msi irqs. */ > - for (i = 128; i < (128 + 512); ++i) { > - irq_set_chip_and_handler(base + i, msi_ops, handle_level_irq); > - irq_set_status_flags(base + i, IRQ_LEVEL); > - } > - > for (i = 0; i < 16; ++i) > init_one_io7_msi(io7, i, boot_cpuid); > > -- > 2.53.0 > With the preceding irq_set_status_flags(base + i, ...) fix applied, this looks correct to me. The generic IRQ descriptor setup is moved outside io7->irq_lock, while the raw spinlock still protects the IO7 hardware CSR accesses. That matches the lockdep report and avoids taking sparse_irq_lock from raw-spinlock context. Reviewed-by: Magnus Lindholm <[email protected]>