-
Notifications
You must be signed in to change notification settings - Fork 2k
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
cortexm_common: Make no_thread_idle compatible with cortex-m0 #14557
cortexm_common: Make no_thread_idle compatible with cortex-m0 #14557
Conversation
Additional benchmarks using bench_mutex_pingpong:
After investigating a bit more on the samr21-xpro, the two extra instructions in the PendSV handler drop the bench_mutex_pingpong from 65217 to 64690. Then enabling the |
cpu/cortexm_common/thread_arch.c
Outdated
@@ -462,8 +467,6 @@ void sched_arch_idle(void) | |||
* According to [this](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0321a/BIHJICIE.html), | |||
* dynamically changing the priority is not supported on CortexM0(+). | |||
*/ |
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.
The comment here is obviously outdated now
@@ -107,7 +107,7 @@ extern "C" { | |||
* If you want to set this, define it in your `cpu_conf.h`. | |||
*/ | |||
#ifndef CPU_CORTEXM_PRIORITY_GROUPING | |||
#define CPU_CORTEXM_PRIORITY_GROUPING (0) | |||
#define CPU_CORTEXM_PRIORITY_GROUPING (1) |
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.
The above comment says
A currently experimental way to make PendSV on Cortex-M to run last is to
But when checking, most implementations (all but nrf52
) will set
#define CPU_DEFAULT_IRQ_PRIO (1U)
in cpu_conf.h
, violating this advice.
(Which begs the question: Why not also move the definition of CPU_DEFAULT_IRQ_PRIO
to cpu_conf_common.h
?)
More measurement of this Pre-PR versus Post-PR on the samr21-xpro using bench_mutex_pingpong:
LLVM+LTO didn't compile here. |
cpu/cortexm_common/thread_arch.c
Outdated
__DSB(); | ||
__ISB(); |
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.
These shouldn't be necessary anymore.
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.
removed!
IIUC CPU_CORTEXM_PRIORITY_GROUPING sets the number of bits that are "ignored" (make two IRQs the same priority). So if set to 1, irq prio 0 and 1 would be the same, or 2 and 3. But wouldn't it make more sense to leave the grouping alone (keep at 0 bits)? Otherwise, the assumptions break if a CPU overrides CPU_DEFAULT_IRQ_PRIO to a non-even value. |
You're right. The only thing here is that the
Yes! If we always want to have the PendSV interrupt at the highest IRQ priority value, we can set it to 255 and let the hardware truncate it to the max value. |
9062901
to
56ff5f8
Compare
rebased! |
9ab3b3e
to
99d4338
Compare
Rebased again to current master |
Please squash. I'm giving this another test run, codewise, LGTM. |
cpu/cortexm_common/thread_arch.c
Outdated
@@ -317,7 +317,10 @@ void __attribute__((naked)) __attribute__((used)) isr_pendsv(void) { | |||
#endif | |||
"push {lr} \n" /* push exception return code */ | |||
|
|||
/* Disable interrupts during scheduling */ | |||
"cpsid i \n" |
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.
could you move this comment after the next line? or would it get too long?
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.
Reworded it a bit to make it fit :)
d14f2bd
to
3e3f066
Compare
Squashed! |
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.
ACK.
This extends the rather hacky previous no-idle code to a more straight forward implementation that also works on smaller Cortex-M.
Those take a ~5% performance hit in synthetic context switching benchmarks.
The benefits are:
- saving 256b of idle stack RAM
- faster thread-sleep-thread transitions (if switching to the same thread)
- with PendSV at low priority, all Cortex-M benefit when multiple threads are triggering PendSV, as sched_run would only run once
I consider the benefits outweighing the performance drop. And, re-enabling the idle thread is still possible by disabling the no-idle-thread feature.
Amended in the Kconfig selector 🙄 |
Murdock is still not happy. :( |
All run tests, I'll check if I can reproduce those locally |
libhydrogen is also failing currently on master, see #14754 (comment) (and the nightlies). |
I can reproduce this failure on current master.
This test does a printf inside the IRQ callback. It looks easy enough to change that to a bit of fmt code. |
This modifies the cortex-m thread specifics to allow running the PendSV interrupt continuously at lower priority and removes the priority modifications during the interrupt itself. Interrupts are disabled during the scheduling itself, but enabled briefly after the sleep to ensure that they are handled if activated during the scheduling or the sleep.
da2fb6c
to
eb73515
Compare
Rebased this to include the commits from #15061 (merged) in here. Makes testing a bit easier |
All build failures should now be unrelated to this PR. |
Removed "CI: run tests" to prevent unrelated build failures, the samr21-xpro:llvm tests also fail on master. |
&go. |
Awesome, thanks for the review! |
Ping @kaspar030 and @bergzand It appears the ba58273 broke stdin on the saml10-xpro. I don't know exactly how to fix it... If you guys understand then you and use the HiL CI to test and verify the fix otherwise I would suggest a revert. This was caught by the nightlies in the HiL CI (far too late though) |
Blegh, thanks for reporting! I strongly suspect something in the power management of the saml10-xpro. At least that's the first spot I would look for this. |
Can confirm, when I remove |
Contribution description
This PR modifies the cortexm thread specific bits to allow running the PendSV IRQ permanently at a lower priority than the other IRQs. With this, the
no_thread_idle
feature is extended to cover the cortex-m0(+).Interrupts are disabled during
sched_run
to prevent the scheduler bits from being modified during the scheduling algorithm. They are briefly enabled after the sleep in sched_arch_idle so that pending interrupts can be serviced after the CPU returns from sleeping.Testing procedure
Same as #14224, but now with the samr21-xpro (or other cortex-m0) included in the tests. Everything should still work as usual.
Benchmarks
Early benchmarks shows that this decreases raw thread switch performance by about 5%:
samr21-xpro on Master
samr21-xpro on this PR
Issues/PRs references
None