Re-enable CFS

This commit is contained in:
Zejun Zhao
2025-01-22 14:08:35 +08:00
committed by Tate, Hongliang Tian
parent c2f48a41db
commit d71771e49a
17 changed files with 102 additions and 512 deletions

View File

@ -6,7 +6,10 @@ use ostd::{
};
use super::{oops, AsThread, Thread};
use crate::{prelude::*, sched::priority::Priority};
use crate::{
prelude::*,
sched::{Nice, SchedPolicy},
};
/// The inner data of a kernel thread.
struct KernelThread;
@ -14,8 +17,8 @@ struct KernelThread;
/// Options to create or spawn a new kernel thread.
pub struct ThreadOptions {
func: Option<Box<dyn FnOnce() + Send>>,
priority: Priority,
cpu_affinity: CpuSet,
sched_policy: SchedPolicy,
}
impl ThreadOptions {
@ -25,24 +28,25 @@ impl ThreadOptions {
F: FnOnce() + Send + 'static,
{
let cpu_affinity = CpuSet::new_full();
let sched_policy = SchedPolicy::Fair(Nice::default());
Self {
func: Some(Box::new(func)),
priority: Priority::default(),
cpu_affinity,
sched_policy,
}
}
/// Sets the priority of the new thread.
pub fn priority(mut self, priority: Priority) -> Self {
self.priority = priority;
self
}
/// Sets the CPU affinity of the new thread.
pub fn cpu_affinity(mut self, cpu_affinity: CpuSet) -> Self {
self.cpu_affinity = cpu_affinity;
self
}
/// Sets the scheduling policy.
pub fn sched_policy(mut self, sched_policy: SchedPolicy) -> Self {
self.sched_policy = sched_policy;
self
}
}
impl ThreadOptions {
@ -58,13 +62,13 @@ impl ThreadOptions {
Arc::new_cyclic(|weak_task| {
let thread = {
let kernel_thread = KernelThread;
let priority = self.priority;
let cpu_affinity = self.cpu_affinity;
let sched_policy = self.sched_policy;
Arc::new(Thread::new(
weak_task.clone(),
kernel_thread,
priority,
cpu_affinity,
sched_policy,
))
};

View File

@ -12,10 +12,7 @@ use ostd::{
use self::status::{AtomicThreadStatus, ThreadStatus};
use crate::{
prelude::*,
sched::{
priority::{AtomicPriority, Priority},
SchedAttr,
},
sched::{SchedAttr, SchedPolicy},
};
pub mod exception;
@ -39,8 +36,6 @@ pub struct Thread {
// mutable part
/// Thread status
status: AtomicThreadStatus,
/// Thread priority
priority: AtomicPriority,
/// Thread CPU affinity
cpu_affinity: AtomicCpuSet,
sched_attr: SchedAttr,
@ -51,16 +46,15 @@ impl Thread {
pub fn new(
task: Weak<Task>,
data: impl Send + Sync + Any,
priority: Priority,
cpu_affinity: CpuSet,
sched_policy: SchedPolicy,
) -> Self {
Thread {
task,
data: Box::new(data),
status: AtomicThreadStatus::new(ThreadStatus::Init),
priority: AtomicPriority::new(priority),
cpu_affinity: AtomicCpuSet::new(cpu_affinity),
sched_attr: SchedAttr::new(priority.into()),
sched_attr: SchedAttr::new(sched_policy),
}
}
@ -135,11 +129,6 @@ impl Thread {
self.status.store(ThreadStatus::Exited, Ordering::Release);
}
/// Returns the reference to the atomic priority.
pub fn atomic_priority(&self) -> &AtomicPriority {
&self.priority
}
/// Returns the reference to the atomic CPU affinity.
pub fn atomic_cpu_affinity(&self) -> &AtomicCpuSet {
&self.cpu_affinity

View File

@ -10,7 +10,7 @@ use ostd::{
use super::worker_pool::WorkerPool;
use crate::{
prelude::*,
sched::priority::Priority,
sched::{Nice, SchedPolicy},
thread::{kernel_thread::ThreadOptions, AsThread},
};
@ -50,13 +50,15 @@ impl Worker {
});
let mut cpu_affinity = CpuSet::new_empty();
cpu_affinity.add(bound_cpu);
let mut priority = Priority::default();
if worker_pool.upgrade().unwrap().is_high_priority() {
priority = Priority::default_real_time();
}
let sched_policy =
SchedPolicy::Fair(if worker_pool.upgrade().unwrap().is_high_priority() {
Nice::MIN
} else {
Nice::default()
});
let bound_task = ThreadOptions::new(task_fn)
.cpu_affinity(cpu_affinity)
.priority(priority)
.sched_policy(sched_policy)
.build();
Self {
worker_pool,

View File

@ -16,7 +16,7 @@ use ostd::{
use super::{simple_scheduler::SimpleScheduler, worker::Worker, WorkItem, WorkPriority, WorkQueue};
use crate::{
prelude::*,
sched::priority::Priority,
sched::{Nice, SchedPolicy},
thread::{kernel_thread::ThreadOptions, AsThread},
};
@ -237,17 +237,13 @@ impl Monitor {
current_monitor.run_monitor_loop();
});
let cpu_affinity = CpuSet::new_full();
// FIXME: remove the use of real-time priority.
// Logically all monitors should be of default normal priority.
// This workaround is to make the monitor of high-priority worker pool
// starvation-free under the current scheduling policy.
let priority = match priority {
WorkPriority::High => Priority::default_real_time(),
WorkPriority::Normal => Priority::default(),
};
let sched_policy = SchedPolicy::Fair(match priority {
WorkPriority::High => Nice::MIN,
WorkPriority::Normal => Nice::default(),
});
let bound_task = ThreadOptions::new(task_fn)
.cpu_affinity(cpu_affinity)
.priority(priority)
.sched_policy(sched_policy)
.build();
Self {
worker_pool,