scx_rustland_core: update README.md

Signed-off-by: Andrea Righi <andrea.righi@linux.dev>
This commit is contained in:
Andrea Righi 2024-08-25 12:39:08 +02:00
parent 894f9582d0
commit 41dfa2481b

View File

@ -1,78 +1,68 @@
# Framework to implement sched_ext schedulers running in user-space # Framework to implement `sched_ext` schedulers running in user-space
[sched_ext](https://github.com/sched-ext/scx) is a Linux kernel feature `scx_rustland_core` is a Rust framework designed to facilitate the
which enables implementing kernel thread schedulers in BPF and dynamically implementation of user-space schedulers based on the Linux kernel `sched_ext`
loading them. feature.
This crate provides a generic layer that can be used to implement sched-ext `sched_ext` allows to dynamic load and execute custom schedulers in the kernel,
schedulers that run in user-space. leveraging BPF to manage scheduling policies.
It provides a generic BPF abstraction that is completely agnostic of the This crate provides an abstraction layer for `sched_ext`, enabling developers
particular scheduling policy implemented in user-space. to write schedulers in Rust without dealing with low-level kernel or BPF
details.
Developers can use such abstraction to implement schedulers using pure Rust ## Features
code, without having to deal with any internal kernel / BPF internal details.
- **Generic BPF Abstraction**: Interact with BPF components using a high-level Rust API.
- **Task Scheduling**: Enqueue and dispatch tasks using provided methods.
- **CPU Selection**: Select idle CPUs for task execution with a preference for reusing previous CPUs.
- **Time slice**: Assign a specific time slice on a per-task basis.
- **Performance Reporting**: Access internal scheduling statistics.
## API ## API
The main BPF interface is provided by the `BpfScheduler` struct. When this ### `BpfScheduler`
object is initialized it will take care of registering and initializing the BPF
The `BpfScheduler` struct is the core interface for interacting with the BPF
component. component.
The scheduler then can use `BpfScheduler` instance to receive tasks (in the - **Initialization**:
form of `QueuedTask` objects) and dispatch tasks (in the form of DispatchedTask - `BpfScheduler::init` registers and initializes the BPF component.
objects), using respectively the methods `dequeue_task()` and `dispatch_task()`.
Example usage (FIFO scheduler): - **Task Management**:
- `dequeue_task()`: Retrieve tasks that need to be scheduled.
- `dispatch_task(task: &DispatchedTask)`: Dispatch tasks to specific CPUs.
- `select_cpu(pid: i32, prev_cpu: i32, flags: u64)`: Select an idle CPU for a task.
- **Completion Notification**:
- `notify_complete(nr_pending: u64)` reports the number of pending tasks to the BPF component.
## Getting Started
- **Installation**:
- Add `scx_rustland_core` to your `Cargo.toml` dependencies.
``` ```
struct Scheduler<'a> { [dependencies]
bpf: BpfScheduler<'a>, scx_rustland_core = "0.1"
}
impl<'a> Scheduler<'a> {
fn init() -> Result<Self> {
let topo = Topology::new().expect("Failed to build host topology");
let bpf = BpfScheduler::init(5000, topo.nr_cpus() as i32, false, false, false)?;
Ok(Self { bpf })
}
fn schedule(&mut self) {
match self.bpf.dequeue_task() {
Ok(Some(task)) => {
// task.cpu < 0 is used to to notify an exiting task, in this
// case we can simply ignore it.
if task.cpu >= 0 {
let _ = self.bpf.dispatch_task(&DispatchedTask {
pid: task.pid,
cpu: task.cpu,
cpumask_cnt: task.cpumask_cnt,
slice_ns: 0,
});
}
}
Ok(None) => {
// Notify the BPF component that all tasks have been dispatched.
self.bpf.update_tasks(Some(0), Some(0))?
break;
}
Err(_) => {
break;
}
}
}
``` ```
- **Implementation**:
- Create your scheduler by implementing the provided API.
Moreover, a CPU ownership map (that keeps track of which PID runs on which CPU) - **Execution**:
can be accessed using the method `get_cpu_pid()`. This also allows to keep - Compile and run your scheduler. Ensure that your kernel supports `sched_ext` and is configured to load your BPF programs.
track of the idle and busy CPUs, with the corresponding PIDs associated to
them.
BPF counters and statistics can be accessed using the methods `nr_*_mut()`, in
particular `nr_queued_mut()` and `nr_scheduled_mut()` can be updated to notify
the BPF component if the user-space scheduler has still some pending work to do
or not.
Lastly, the methods `exited()` and `shutdown_and_report()` can be used ## Example
respectively to test whether the BPF component exited, and to shutdown and
report the exit message. You can find a simple example of a fully working FIFO scheduler implemented
using the `scx_rustland_core` framework here:
[scx_rlfifo](https://github.com/sched-ext/scx/tree/main/scheds/rust/scx_rlfifo).
## License
This software is licensed under the GNU General Public License version 2. See
the LICENSE file for details.
## Contributing
Contributions are welcome! Please submit issues or pull requests via GitHub.