Dispatch interrupts asynchroneously
This patch-set changes interrupt dispatching to happen asynchronously. This is a first step towards making API-calls interrupt safe. It also makes Epicardium more robust against a buggy payload as such a payload can no longer deadlock tasks which try to send interrupts (in such an instance, now they will be scheduled but never leave the IRQ queue).
Patch-List:
chore(interrupts): Make api_interrupt_trigger() return void
api_interrupt_trigger() cannot fail except by a programmer error
(passing an invalid ID) in which case we should raise an assertion.
Thus, make it return void
instead of int
.
fix(lifecycle): Don't trigger a reset during startup
This is a silent issue which I noticed during work in this patchset; we are sending a superfluous interrupt during boot. This patch changes this although it reduces readability of the code. I'd be ok with dropping it again if readability here is more important.
chore(interrupts): Move api into an epicardium module
Our buildsystem prevents implementing the task in epicardium/api
so I moved the interrupts API into an Epicardium module.
chore(interrupts): Fix all modules to use new api
Update code-base to use new API.
feat(interrupts): Dispatch interrupts asynchroneously
Instead of blocking the triggering task when core 1 is still busy handling the previous interrupt, offload interrupt dispatching into a separate task. This is the first step towards making API-calls interrupt safe.
Next to the async triggering, the synchroneous mechanism is retained for special cases where async does not work (e.g. because of spin-locks). Currently, there is only one such case when resetting core 1 (triggering EPIC_INT_RESET).
docs(interrupts): Document new interrupt dispatcher task
Docs ...
Merge request reports
Activity
changed milestone to %v1.16
added 3-Epicardium 6 - Needs Review labels
- Resolved by schneider
- Resolved by schneider
- Resolved by schneider
- Resolved by schneider
- Resolved by rahix
- Resolved by rahix
Can you quickly state with which app you've tested this already?
added 26 commits
-
d834d48c...861d604a - 20 commits from branch
master
- 079b9344 - chore(interrupts): Make api_interrupt_trigger() return void
- 8bb6a743 - fix(lifecycle): Don't trigger a reset during startup
- fc57e82f - chore(interrupts): Move api into an epicardium module
- 5abd0cd0 - chore(interrupts): Fix all modules to use new api
- f8d75535 - feat(interrupts): Dispatch interrupts asynchroneously
- f5dbaac0 - docs(interrupts): Document new interrupt dispatcher task
Toggle commit list-
d834d48c...861d604a - 20 commits from branch
- Resolved by schneider
I just noticed something ... :(
This code snippet
import interrupt import utime def handler(_): print("handling IRQ") interrupt.set_callback(interrupt.RTC_ALARM, handler) interrupt.enable_callback(interrupt.RTC_ALARM) utime.alarm(utime.time() + 2) while True: print("And going to sleep ...") utime.sleep(5)
triggers a panic. Seems like I didn't test all code-paths through the RTC module and missed something important:
The current implementation of the RTC driver calls
interrupt_trigger()
from the RTC IRQ. This fails horribly becauseinterrupt_trigger()
wants to do multiple things which can't ever happen from an interrupt (locking a mutex, callingxTaskNotifyGive()
).
The proper solution to this would be refactoring the RTC module to have no logic in the IRQ handler and instead have a task woken up which actually dispatches the interrupt.
But this is also not great; yet another task which sits idle 99% of the time wasting RAM in epicardium. The number of these has gotten considerably large already ... So the proper proper solution would be finally implementing a worker-queue which takes all those work items that currently have their own tasks and runs them. But I'm not up to implementing such a thing right now ...
So, I would suggest the following: I build an 'unsafe' (that is, not checking the lock for
interrupt_data.int_enabled
) version ofinterrupt_trigger_sync()
which can be called from an IRQ and which is only used in this one place. And we hopefully fix the RTC module properly soon(tm) ...
added 21 commits
-
f5dbaac0...12992926 - 15 commits from branch
master
- 0b845e99 - chore(interrupts): Make api_interrupt_trigger() return void
- 079982a6 - fix(lifecycle): Don't trigger a reset during startup
- 1f7e44e6 - chore(interrupts): Move api into an epicardium module
- 682565f2 - chore(interrupts): Fix all modules to use new api
- 37e7fb35 - feat(interrupts): Dispatch interrupts asynchroneously
- 3d4d0eb4 - docs(interrupts): Document new interrupt dispatcher task
Toggle commit list-
f5dbaac0...12992926 - 15 commits from branch
added 1 commit
- 4b171bea - docs(interrupts): Document changed interrupt behavior
@schneider, I tried addressing all remaining comments. Can you take another look?