New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Systick trait, implement it for e310x and ibex #1985
Conversation
kernel/src/platform/system_timer.rs
Outdated
/// it just guarantees that an interrupt will be generated | ||
/// if an already started timer expires, which is useful for | ||
/// preempting userspace applications. | ||
fn arm(&self); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not enable_interrupt()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@phil-levis didn't like the name enable_interrupt()
because it might imply that all interrupts for the underlying hardware timer are disabled, which is not the case if the trait is on top of a virtualized timer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok overall I think the symmetry in arm/disarm probably makes for the most clear interface, since disarm doesn't have to actually disable anything. I think just capturing the importance of this interrupt in the documentation better to explain this subtlety will avoid any questions along this line in the future. I can add a commit.
437a0b3
to
1f7d920
Compare
Merge conflicts resolved, and I think all comments have been addressed. The coupling between the |
I added the doc commit I promised. I also really like the name. My last two questions:
|
Agreed, changed.
The reason I kept |
The updated version has now been tested on ARM by checking that apps are preempted as expected and that these preemptions are counted by the process console. I will try to re-test on RISC-V before this is merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good -- one comment on a name that I think would be better, but not blocking-worthy to change
463c48e
to
88ca219
Compare
rebased on master, changed I think this is ready to go. |
88ca219
to
d803073
Compare
bors r+ |
Pull Request Overview
This PR updates the SysTick trait to be less specific to the ARM systick peripheral, to instead represent a System Timer abstraction that can be more effectively used by chips without this optional peripheral. It also adds an implementation of this trait for two RISC-V chips, ibex and the e310x, by virtualizing the single available hardware timer available on each such that it can be used by both the scheduler and by kernel capsules/userspace apps.
This includes renaming SysTick to SystemTimer (name subject to bikeshedding) and modifying the functions and documentation of the trait slightly. This PR also removes the reliance on a dedicated interrupt handler for system timer interrupts, instead relying on there simply being some interrupt that fires, and calling systick.expired() whenever userspace processes are interrupted to determine if there has been a timeslice expiration. This change is critical for enabling the ability to implement the system timer on top of a hardware peripheral that is shared with other timer functionality.
This PR also includes a new
VirtualSystemTimer
type which can be constructed by passing anything implementing theAlarm
trait, allowing forVirtualMuxAlarm
s to be used to create a systick. Notably, the design ofMuxAlarm
is such that there is still constant-time overhead on all systick operations except for handling the systick interrupt when it fires (which is O(N) where N is the number of virtual alarms). This seems like a reasonable tradeoff to me, given that systick expirations already lead to thehigher overhead of a context switch, and a well designed system (and scheduler) should minimize the frequency of app preemption.
This PR moves opentitan and the hifive1 to use the new
VirtualSystemTimer
.This PR also removes the reliance of the ARM systick on modifying a global static mut variable to signal timeslice expirations.
Finally, this PR also implements
SystemTimer
directly on the RISC-V mtimer, but this will only work if a different hardware timer is used to provide alarms to the kernel/userspace, and this implementation is untested given that we do not support doing so on any of our current RISC-V chips.Testing Strategy
This pull request (well, a slightly earlier version) was tested on HiFive1 in QEMU and appeared to work (apps still functioned, and putting a busy loop in apps led to timeslice expirations that preempted the app).
I also tested it on OpenTitan in verilator, but have run into issues where after a timeslice expirations I receive spurious interrupts. I still need to debug this to determine whether it is an issue with this PR or the tock implementation of
rv_timer()
.I still need to test on existing ARM boards.
TODO or Help Wanted
This pull request still needs feedback on names, and feedback on the changes to the trait.
I learned today that @rajivr has also been working on modifying the SysTick trait, and he has taken a somewhat different approach, so it may be useful to compare and contrast these approaches.
More testing will be needed.
Documentation Updated
/docs
, or no updates are required.Formatting
make prepush
.