RTEMS | raspberrypi: IRQ dispatch hangs when a bank-1 and a speed-up interrupt are pending together (#5810)

Miroslaw Dach (@mirek23) gitlab at rtems.org
Sun Oct 18 04:53:20 UTC 2026



Issue created by Miroslaw Dach: https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5810



```
Board: Raspberry Pi 3 Model B+, BSP arm/raspberrypi2, RTEMS 6.2 (be446b02d0)
and main (4bca987369, same code), rtems-libbsd 6-freebsd-14, EPICS 7.0.10 IOC.

Symptom: with USB (LAN7800 Ethernet) interrupt load the system freezes
completely after seconds to minutes: console dead, no task runs. It looked
like a bus or CPU lockup.

Cause: bsp_interrupt_dispatch() in bsps/arm/raspberrypi/irq/irq.c reads
BCM2835_IRQ_BASIC and, when any speed-up bit is set, calls ffs() on the
UNMASKED value:

    pend = BCM2835_REG(BCM2835_IRQ_BASIC);
    if ( pend & BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS ) {
      pend_bit = ffs(pend) - 1;
      vector = bcm2835_irq_speedup_table[pend_bit];

Bit 8 of IRQ_BASIC ("one or more bits set in pending register 1") is set
whenever a bank-1 interrupt without a speed-up bit is pending, e.g. the
system timer compare 3 used for the clock tick (GPU IRQ 3). If that happens
while a speed-up interrupt (USB, GPU IRQ 9, speed-up bit 11) is pending too,
the register reads 0x900. ffs(0x900) - 1 = 8, bcm2835_irq_speedup_table[8]
is -1, vector becomes 0xffffffff, the "vector < 255" check fails, no handler
runs, the interrupt stays asserted and the CPU re-enters the dispatcher
forever.

Evidence: a RAM trace surviving the watchdog reset shows, in every frozen
run, the last 600 entries as IRQ_BASIC reads returning 0x900 at about
1.3 million per second with no handler call in between. The probability per
interrupt is small, so the time to failure scales with the interrupt rate
(about 30 s at 40000 USB interrupts/s plus a 2 kHz tick).

Fix: mask before the bit scan,
    pend_bit = ffs(pend & BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS) - 1;
With 0x900 the USB interrupt is dispatched first; the immediate re-entry
sees 0x100, takes the IRQ_PENDING1 path and dispatches the tick.

Tested: 15.5 h continuous operation with 450 million USB transfers and
1.8 billion interrupts, then a second run of more than 17 h with a 1 kHz
EPICS scan, versus a freeze within a minute before the change.

Mailing list thread: "EPICS ioc with RTEMS on Raspberry Pi", users@/devel@,
2026-10-14.
```

## MR description

```
bsp_interrupt_dispatch() of the raspberrypi BSP feeds the unmasked
BCM2835_IRQ_BASIC value to ffs(). When a bank-1 interrupt (clock tick) and a
speed-up interrupt (USB) are pending together the register reads 0x900,
ffs() selects bit 8 whose speedup-table entry is -1, no handler is called
and the CPU loops in the dispatcher forever. Mask the value with
BCM2835_IRQ_BASIC_SPEEDUP_USED_BITS before the bit scan.

Tested on Raspberry Pi 3B+ with rtems-libbsd USB Ethernet and an EPICS 7
IOC: >15 h and >17 h soak runs without a freeze, versus a freeze within a
minute before. The same code is in the 6 branch; a backport is requested.

Close #N.
```

-- 
View it on GitLab: https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5810
You're receiving this email because of your account on gitlab.rtems.org. Unsubscribe from this thread: https://gitlab.rtems.org/-/namespace/49/sent_notifications/6-159594alh521pcwwlu0jzevpv-1d/unsubscribe | Manage all notifications: https://gitlab.rtems.org/-/profile/notifications | Help: https://gitlab.rtems.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/bugs/attachments/20261018/119805bb/attachment.htm>


More information about the bugs mailing list