Skip to content

Conversation

@nategraff-sifive
Copy link
Contributor

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_switch API in place of swap. 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-multicore target 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. In hw/riscv/sifive_e.c, just change line 203 to

    mc->max_cpus = <some number greater than 1>;

I 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.

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.
@nategraff-sifive nategraff-sifive added area: RISCV RISCV Architecture (32-bit & 64-bit) area: SMP Symmetric multiprocessing labels Nov 13, 2018
@nategraff-sifive nategraff-sifive added the DNM This PR should not be merged (Do Not Merge) label Nov 13, 2018
@codecov-io
Copy link

Codecov Report

Merging #11354 into master will increase coverage by <.01%.
The diff coverage is 71.42%.

Impacted file tree graph

@@            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
Impacted Files Coverage Δ
kernel/sched.c 91.36% <71.42%> (-1.13%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 39b2a09...29c5ab7. Read the comment docs.

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)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants