Skip to content

Commit

Permalink
[task] support percpu run-queue and cpu affinity for axtask (arceos-o…
Browse files Browse the repository at this point in the history
…rg#176)

* [task] support percpu run-queue and cpu affinity for axtask

* refactor: add preempt guard for AxRunQueue through AxRunQueueRef

* refactor: use kernel_guard hold by RQ in wait_queue.rs

* feat: introduce cpumask

* [feat] add on_cpu and prev_task_on_cpu_ptr field in AxTaskInner

* fix: delete redundant kernel guard in WaitQueue wait()

* Add percpu scheduler doc

* [fix] unit test error related to doc comment

* [feat] delete cancel_alarm from timers

* Update percpu_rq

* [fix] use timer ticket id to prevent potential bug introduced by timer event confusion

* [feat] use type CpuSet to wrap cpumask::CpuMask

* [fix] use allow(clippy::modulo_one) to bypass modulo 1 error in select_run_queue_index

* [fix] miss doc for type alias CpuSet

* [fix] little modification in axtask api.rs

* [fix] some review opinions

* [fix] delete if self.on_cpu() block in unblock_locked

* [refactor] remove in_timer_list flag in axtask

* [fix] doc error in unblock_task

* [refactor] timer ticket id

* [fix] use put_prev_task in unblock_task

* [fix] pontential bug in unblock_locked, set on_cpu as true for init tasks

* [feat] enrich code comments and scheduling-related docs

* [refactor] move percpu related docs to discussions

* [fix] first round fix of review suggestions

* [refactor] add block_current in run_queue.rs

* [refactor] pass SpinNoIrqGuard to blocked_resched

* [feat] add WaitQueueGuard

* [refactor] merge unblock_task, add TaskUnblockGuard

* [fix] second round fix of review suggestions

* [fix] third round fix of review suggestions

* [refactor] use weak reference for prev task to manipulate on_cpu flag

* [feat] enable on_cpu flag only with smp feature enabled

* [fix] enable on_cpu flag only with smp feature enabled

* [fix] change the pos of NoPreemptIrqSave guard hold by rq in wait_queue.rs

* [refactor] delete unblock_locked, use atomic compare_exchange in unblock_task

* [fix] bug in wait_timeout, modify assert in blocked_resched and switch_to

* [fix] modify assert about irqs_enabled in switch_to

* [refactor] keep the guard in the loop in wait_timeout_until

* [fix] some compile warnings

* Update the commit hash for arceos-apps

* Update the commit hash for arceos-apps again

* Update the commit hash for arceos-apps again and again

* [fix] bug in wait_timeout and wait_timeout_until

* [CI] update dependencies for qemu build

* [fix] fourth round fix of review suggestions

* [fix] problems related to WAIT_FOR_EXIT in gc_entry

* [refactor] use current_ref_mut_raw to get TIMER_LIST in check_events()

* [refactor] improve notify_all in wait_queue.rs

* [refactor] delete redundant assertion in block_resched()

* [fix] some compile warnings
  • Loading branch information
hky1999 authored and buhenxihuan committed Nov 13, 2024
1 parent 6152ea8 commit 176f5f4
Show file tree
Hide file tree
Showing 16 changed files with 660 additions and 190 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/actions/setup-musl/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ runs:
steps:
- name: Cache musl
id: cache-musl
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
with:
path: ${{ inputs.arch }}-linux-musl-cross
key: ${{ inputs.arch }}-linux-musl-cross
Expand All @@ -22,7 +22,7 @@ runs:
MUSL_PATH=${{ inputs.arch }}-linux-musl-cross
wget https://musl.cc/${MUSL_PATH}.tgz
tar -xf ${MUSL_PATH}.tgz
- uses: actions/cache/save@v3
- uses: actions/cache/save@v4
if: steps.cache-musl.outputs.cache-hit != 'true'
with:
path: ${{ inputs.arch }}-linux-musl-cross
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/actions/setup-qemu/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ runs:
steps:
- name: Cache QEMU
id: cache-qemu
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
with:
path: qemu_build
key: qemu-${{ inputs.qemu-version }}-slirp-1
Expand All @@ -22,13 +22,13 @@ runs:
PREFIX: ${{ github.workspace }}/qemu_build
shell: bash
run: |
sudo apt-get update && sudo apt-get install -y ninja-build libslirp-dev
sudo apt-get update && sudo apt-get install -y ninja-build libslirp-dev libglib2.0-dev
wget https://download.qemu.org/$QEMU_PATH.tar.xz && tar -xJf $QEMU_PATH.tar.xz
cd $QEMU_PATH \
&& ./configure --prefix=$PREFIX --target-list=x86_64-softmmu,riscv64-softmmu,aarch64-softmmu --enable-slirp \
&& make -j > /dev/null 2>&1 \
&& make install
- uses: actions/cache/save@v3
- uses: actions/cache/save@v4
if: steps.cache-qemu.outputs.cache-hit != 'true'
with:
path: qemu_build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on: [push, pull_request]
env:
qemu-version: 8.2.0
rust-toolchain: nightly-2024-05-02
arceos-apps: '68054e8'
arceos-apps: '57d495a'

jobs:
unit-test:
Expand Down
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ArceOS was inspired a lot by [Unikraft](https://github.com/unikraft/unikraft).
* [x] VirtIO net/blk/gpu drivers
* [x] TCP/UDP net stack using [smoltcp](https://github.com/smoltcp-rs/smoltcp)
* [x] Synchronization/Mutex
* [x] SMP scheduling with single run queue
* [x] SMP scheduling with [per-cpu run queue](https://github.com/arceos-org/arceos/discussions/181)
* [x] File system
* [ ] Compatible with Linux apps
* [ ] Interrupt driven device I/O
Expand Down
2 changes: 1 addition & 1 deletion api/axfeat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ documentation = "https://arceos-org.github.io/arceos/axfeat/index.html"
default = []

# Multicore
smp = ["axhal/smp", "axruntime/smp", "kspin/smp"]
smp = ["axhal/smp", "axruntime/smp", "axtask?/smp", "kspin/smp"]

# Floating point/SIMD
fp_simd = ["axhal/fp_simd"]
Expand Down
7 changes: 7 additions & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,10 @@ See [arceos-apps](https://github.com/arceos-org/arceos-apps) for example applica
Documentation of ArceOS [modules](../modules), [api](../api), and [ulib](../ulib) are generated by [`rustdoc`](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html) and hosted on GitHub Pages:

* https://arceos-org.github.io/arceos/

## Discussions

* [Rust std support](https://github.com/arceos-org/arceos/discussions/92)
* [ArceOS for ARM64](https://github.com/arceos-org/arceos/discussions/101)
* [ArceOS for RISCV Hardware](https://github.com/arceos-org/arceos/discussions/120)
* [Per-CPU scheduling](https://github.com/arceos-org/arceos/discussions/181)
8 changes: 8 additions & 0 deletions modules/axhal/src/arch/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,21 @@ pub use x86_64::structures::tss::TaskStateSegment;
/// Allows the current CPU to respond to interrupts.
#[inline]
pub fn enable_irqs() {
#[cfg(not(target_os = "none"))]
{
warn!("enable_irqs: not implemented");
}
#[cfg(target_os = "none")]
interrupts::enable()
}

/// Makes the current CPU to ignore interrupts.
#[inline]
pub fn disable_irqs() {
#[cfg(not(target_os = "none"))]
{
warn!("disable_irqs: not implemented");
}
#[cfg(target_os = "none")]
interrupts::disable()
}
Expand Down
2 changes: 1 addition & 1 deletion modules/axruntime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ documentation = "https://arceos-org.github.io/arceos/axruntime/index.html"
[features]
default = []

smp = ["axhal/smp"]
smp = ["axhal/smp", "axtask?/smp"]
irq = ["axhal/irq", "axtask?/irq", "percpu", "kernel_guard"]
tls = ["axhal/tls", "axtask?/tls"]
alloc = ["axalloc"]
Expand Down
14 changes: 12 additions & 2 deletions modules/axtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,21 @@ documentation = "https://arceos-org.github.io/arceos/axtask/index.html"
default = []

multitask = [
"dep:axconfig", "dep:percpu", "dep:kspin", "dep:lazyinit", "dep:memory_addr",
"dep:scheduler", "dep:timer_list", "kernel_guard", "dep:crate_interface",
"dep:axconfig",
"dep:percpu",
"dep:kspin",
"dep:lazyinit",
"dep:memory_addr",
"dep:scheduler",
"dep:timer_list",
"kernel_guard",
"dep:crate_interface",
"dep:cpumask",
]
irq = []
tls = ["axhal/tls"]
preempt = ["irq", "percpu?/preempt", "kernel_guard/preempt"]
smp = ["kspin/smp"]

sched_fifo = ["multitask"]
sched_rr = ["multitask", "preempt"]
Expand All @@ -39,6 +48,7 @@ timer_list = { version = "0.1", optional = true }
kernel_guard = { version = "0.1", optional = true }
crate_interface = { version = "0.1", optional = true }
scheduler = { git = "https://github.com/arceos-org/scheduler.git", tag = "v0.1.0", optional = true }
cpumask = { git = "https://github.com/arceos-org/cpumask.git", optional = true }

[dev-dependencies]
rand = "0.8"
Expand Down
24 changes: 17 additions & 7 deletions modules/axtask/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
use alloc::{string::String, sync::Arc};

pub(crate) use crate::run_queue::{AxRunQueue, RUN_QUEUE};
use kernel_guard::NoPreemptIrqSave;

pub(crate) use crate::run_queue::{current_run_queue, select_run_queue};

#[doc(cfg(feature = "multitask"))]
pub use crate::task::{CurrentTask, TaskId, TaskInner};
Expand All @@ -14,6 +16,9 @@ pub use crate::wait_queue::WaitQueue;
/// The reference type of a task.
pub type AxTaskRef = Arc<AxTask>;

/// The wrapper type for cpumask::CpuMask with SMP configuration.
pub type CpuMask = cpumask::CpuMask<{ axconfig::SMP }>;

cfg_if::cfg_if! {
if #[cfg(feature = "sched_rr")] {
const MAX_TIME_SLICE: usize = 5;
Expand Down Expand Up @@ -77,6 +82,8 @@ pub fn init_scheduler() {
/// Initializes the task scheduler for secondary CPUs.
pub fn init_scheduler_secondary() {
crate::run_queue::init_secondary();
#[cfg(feature = "irq")]
crate::timers::init();
}

/// Handles periodic timer ticks for the task manager.
Expand All @@ -85,14 +92,17 @@ pub fn init_scheduler_secondary() {
#[cfg(feature = "irq")]
#[doc(cfg(feature = "irq"))]
pub fn on_timer_tick() {
use kernel_guard::NoOp;
crate::timers::check_events();
RUN_QUEUE.lock().scheduler_timer_tick();
// Since irq and preemption are both disabled here,
// we can get current run queue with the default `kernel_guard::NoOp`.
current_run_queue::<NoOp>().scheduler_timer_tick();
}

/// Adds the given task to the run queue, returns the task reference.
pub fn spawn_task(task: TaskInner) -> AxTaskRef {
let task_ref = task.into_arc();
RUN_QUEUE.lock().add_task(task_ref.clone());
select_run_queue::<NoPreemptIrqSave>(&task_ref).add_task(task_ref.clone());
task_ref
}

Expand Down Expand Up @@ -129,13 +139,13 @@ where
///
/// [CFS]: https://en.wikipedia.org/wiki/Completely_Fair_Scheduler
pub fn set_priority(prio: isize) -> bool {
RUN_QUEUE.lock().set_current_priority(prio)
current_run_queue::<NoPreemptIrqSave>().set_current_priority(prio)
}

/// Current task gives up the CPU time voluntarily, and switches to another
/// ready task.
pub fn yield_now() {
RUN_QUEUE.lock().yield_current();
current_run_queue::<NoPreemptIrqSave>().yield_current()
}

/// Current task is going to sleep for the given duration.
Expand All @@ -150,14 +160,14 @@ pub fn sleep(dur: core::time::Duration) {
/// If the feature `irq` is not enabled, it uses busy-wait instead.
pub fn sleep_until(deadline: axhal::time::TimeValue) {
#[cfg(feature = "irq")]
RUN_QUEUE.lock().sleep_until(deadline);
current_run_queue::<NoPreemptIrqSave>().sleep_until(deadline);
#[cfg(not(feature = "irq"))]
axhal::time::busy_wait_until(deadline);
}

/// Exits the current task.
pub fn exit(exit_code: i32) -> ! {
RUN_QUEUE.lock().exit_current(exit_code)
current_run_queue::<NoPreemptIrqSave>().exit_current(exit_code)
}

/// The idle task routine.
Expand Down
1 change: 1 addition & 0 deletions modules/axtask/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ cfg_if::cfg_if! {
extern crate log;
extern crate alloc;

#[macro_use]
mod run_queue;
mod task;
mod task_ext;
Expand Down
Loading

0 comments on commit 176f5f4

Please sign in to comment.