shared irq handler code assumes that a chain of handlers is only used by one core. #730
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#730
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
These IRQ handler chains are rooted in the core's vector table, and therefore are to some extent local to the core, however today (though maybe not at the time) the VTOR is by default shared between the two cores.
There are some race conditions in irq.c that are likely broken if a shared IRQ handler is removed from the the chain by one core when the other core happens to be at a particular point in the invocation of handlers from the same chain.
In practice, i don't believe anyone including me has ever seen this, and indeed it is likely a rare case that anyone actually hooks the enables the same IRQ on both cores. and perhaps even less likely that they remove IRQ handlers.
Still i'm making the issue for reference as I do know the problem exists. Sadly the fix is non-trivial.
Interesting.
I am currently running into an issue where I am trying to use the doorbell interface to signal the other core when a core hits an exception. Once the exception handler finishes recording state of the crashed core, it executes
multicore_doorbell_set_other_core(). My doorbell handler is very simple: it triggers an NMI on the non-crashing core which I use to save state:(yes I know I can do the state recording of the non-crashing-core in the doorbell handler, this is just how I've got it set up for now)
I'm intending on using this with FreeRTOS, and FreeRTOS also uses a doorbell bit for its own inter-core signaling. Its doorbell handler is also very small and looks to do the right thing:
As of today (Jan 2026) FreeRTOS uses
irq_set_exclusive_handler()to assign the doorbell interrupt. I changed it toirq_add_shared_handler()and as long as I don't install my own shared handler, FreeRTOS works fine. However the momentn I add my shared handler, FreeRTOS runs at approximately 1/2 to 3/8 speed, even if I never trigger my own doorbell.I'm currently setting both of the shared handler priorities to
PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY, but have also experimented with setting the priority of one to be higher (or lower) than the other but without any change in the outcome.If I do not install my own shared handler but literally copy my code into FreeRTOS' doorbell handler, it works great, so it's not a code issue in either FreeRTOS or my own handlers, it's gotta be something with how the shared handler code is doing things. I wonder if the shared IRQ handler code is doing something goofy when it's possible that the IRQ is being triggered on different cores.