-
Notifications
You must be signed in to change notification settings - Fork 8.3k
[DNM] Enable SMP on RISC-V #11354
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
Closed
Closed
[DNM] Enable SMP on RISC-V #11354
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add a mutex to make sure only one philosopher tries to write state to the console at a time.
Requires a patch to QEMU 3.0.0 which allows the sifive_e target to simulate with multiple cores via the `-smp` option
Allocating the start flag atomic on the stack creates a race condition. In true multicore environments you might be unlikely to hit it, but when debugging in QEMU I frequently found that the stack space got stomped on before the other cores had a chance to read the flag.
For non-SMP targets, makes sure than harts other than hart 0 are permanently parked. For SMP targets, permanently parks all harts >= CONFIG_MP_NUM_CPUS and starts up secondary harts in SMP mode.
_arch_irq_lock disables the interrupt enable bits without locking the global SMP spinlock
Rewrite ISR for SMP and use the switch API instead of the swap API The switch API hands a stack frame and not a thread context, so save the callee-saved registers on the stack frame as well. It might be helpful to retarget the switch handle to be the entire thread context to save stack space again.
The scheduler didn't properly handle SMP in a number of different cases, such as removing the current thread from the queue and determining when a thread was able to be run. The general issues tend to be that running threads in SMP mode are not present in the run queue, and the scheduler often assumes the wrong thing about whether a thread is currently in a queue or not. Adding presence checks fixes a number of these issues.
Codecov Report
@@ Coverage Diff @@
## master #11354 +/- ##
==========================================
+ Coverage 48.37% 48.37% +<.01%
==========================================
Files 265 265
Lines 42188 42196 +8
Branches 10137 10143 +6
==========================================
+ Hits 20408 20412 +4
Misses 17703 17703
- Partials 4077 4081 +4
Continue to review full report at Codecov.
|
aurel32
added a commit
to aurel32/zephyr
that referenced
this pull request
Nov 27, 2025
The 250745e OT stack upmerge pulled upstream commit 079852b67e9b ("[uptime] enforce `UPTIME` feature for MTD and FTD builds (zephyrproject-rtos#11354)") which made `OPENTHREAD_CONFIG_UPTIME_ENABLE` mandatory for MTD builds. Update the module configuration accordingly to fix a build failure with CONFIG_OPENTHREAD_MTD=y. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
aurel32
added a commit
to aurel32/zephyr
that referenced
this pull request
Nov 27, 2025
The 250745e OT stack upmerge pulled upstream commit 079852b67e9b ("[uptime] enforce `UPTIME` feature for MTD and FTD builds (zephyrproject-rtos#11354)") which made `OPENTHREAD_CONFIG_UPTIME_ENABLE` mandatory for MTD builds. Update the module configuration accordingly to fix a build failure with CONFIG_OPENTHREAD_MTD=y. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
area: RISCV
RISCV Architecture (32-bit & 64-bit)
area: SMP
Symmetric multiprocessing
DNM
This PR should not be merged (Do Not Merge)
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Do not merge. Opening a PR to seek feedback and comments.
A series of changes to enable symmetric multiprocessing on riscv32. I based my work partly on the way that SMP was enabled for Xtensa, including the use of the new
_arch_switchAPI in place ofswap. Thanks @andyross for the ground work to make this possible in Zephyr.There are few areas that I'm concerned about:
Scheduler Changes
During development I found that I needed to make a number of changes to the common scheduler code. Most of these revolved around the fact that SMP removes the currently running threads from the ready queue, and in several places the scheduler made the incorrect assumption that threads were in the ready queue when they were not. This usually manifests in the ready queue being corrupted (threads getting dropped) and/or the scheduler handing back a bad thread pointer and making the CPU jump to nowhere.
Odds are I've made some mistakes, or at least not found the extent of the problems. Especially looking for review here.
Testing in QEMU
I've created a
sifive-multicoretarget board for testing purposes. It's basically a clone of HiFive 1 with the SMP flags turned on. QEMU 3.0.0 doesn't have an embedded multicore RISC-V target, so in order to try this out you'll need to patch QEMU. It's a very simple one-line change. Inhw/riscv/sifive_e.c, just change line 203 toI haven't gotten sanitycheck passing on sifive-multicore yet either. Still tracking down bugs.
Saved Registers During Interrupts
The multicore interrupt handler I created saves both callee and caller-saved registers onto the stack immediately, as opposed to the single-core handler which only saves callee-saved registers when it knows that a reschedule is about to occur. I didn't see a particularly good way to optimize this, but I wanted to point it out and see what people thought.