mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-24 00:43:24 +00:00
重写调度模块 (#679)
## PR:重写调度模块 --- ### 完成的部分 - 实现cfs调度策略 - 搭建框架,后续功能可以迭代开发 - 目前能跑,未测试性能 ### 需要后续接力的部分 - 实现组内调度(task_group) - 实现跨核负载均衡(pelt算法) - 接入sysfs,实现参数动态调节(sched_stat等) - nice值以及priority等参数的设置及调优
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
use core::cell::RefCell;
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
|
||||
use crate::arch::driver::tsc::TSCManager;
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
@ -12,7 +13,7 @@ use crate::exception::IrqNumber;
|
||||
|
||||
use crate::kdebug;
|
||||
use crate::mm::percpu::PerCpu;
|
||||
use crate::sched::core::sched_update_jiffies;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::smp::core::smp_get_processor_id;
|
||||
use crate::smp::cpu::ProcessorId;
|
||||
use crate::time::clocksource::HZ;
|
||||
@ -66,9 +67,10 @@ impl IrqHandler for LocalApicTimerHandler {
|
||||
struct LocalApicTimerIrqFlowHandler;
|
||||
|
||||
impl IrqFlowHandler for LocalApicTimerIrqFlowHandler {
|
||||
fn handle(&self, _irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) {
|
||||
LocalApicTimer::handle_irq().ok();
|
||||
fn handle(&self, _irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame) {
|
||||
LocalApicTimer::handle_irq(trap_frame).ok();
|
||||
CurrentApic.send_eoi();
|
||||
fence(Ordering::SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,8 +276,9 @@ impl LocalApicTimer {
|
||||
return (res.ecx & (1 << 24)) != 0;
|
||||
}
|
||||
|
||||
pub(super) fn handle_irq() -> Result<IrqReturn, SystemError> {
|
||||
sched_update_jiffies();
|
||||
pub(super) fn handle_irq(trap_frame: &TrapFrame) -> Result<IrqReturn, SystemError> {
|
||||
// sched_update_jiffies();
|
||||
ProcessManager::update_process_times(trap_frame.is_from_user());
|
||||
return Ok(IrqReturn::Handled);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use core::sync::atomic::{fence, Ordering};
|
||||
|
||||
use x86::msr::{
|
||||
rdmsr, wrmsr, IA32_APIC_BASE, IA32_X2APIC_APICID, IA32_X2APIC_EOI, IA32_X2APIC_SIVR,
|
||||
IA32_X2APIC_VERSION,
|
||||
@ -62,9 +64,12 @@ impl LocalAPIC for X2Apic {
|
||||
|
||||
/// 发送 EOI (End Of Interrupt)
|
||||
fn send_eoi(&self) {
|
||||
fence(Ordering::SeqCst);
|
||||
unsafe {
|
||||
wrmsr(IA32_X2APIC_EOI, 0);
|
||||
}
|
||||
|
||||
fence(Ordering::SeqCst);
|
||||
}
|
||||
|
||||
/// 获取 x2APIC 版本
|
||||
|
@ -1,15 +1,13 @@
|
||||
use core::intrinsics::likely;
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
driver::apic::{apic_timer::APIC_TIMER_IRQ_NUM, CurrentApic, LocalAPIC},
|
||||
sched::sched,
|
||||
},
|
||||
arch::driver::apic::{apic_timer::APIC_TIMER_IRQ_NUM, CurrentApic, LocalAPIC},
|
||||
exception::{irqdesc::irq_desc_manager, softirq::do_softirq, IrqNumber},
|
||||
process::{
|
||||
utils::{current_pcb_flags, current_pcb_preempt_count},
|
||||
ProcessFlags,
|
||||
},
|
||||
sched::{SchedMode, __schedule},
|
||||
};
|
||||
|
||||
use super::TrapFrame;
|
||||
@ -47,6 +45,6 @@ unsafe extern "C" fn x86_64_do_irq(trap_frame: &mut TrapFrame, vector: u32) {
|
||||
if (current_pcb_flags().contains(ProcessFlags::NEED_SCHEDULE))
|
||||
&& vector == APIC_TIMER_IRQ_NUM.data()
|
||||
{
|
||||
sched();
|
||||
__schedule(SchedMode::SM_PREEMPT);
|
||||
}
|
||||
}
|
||||
|
@ -254,12 +254,12 @@ impl IrqFlowHandler for X86_64IpiIrqFlowHandler {
|
||||
}
|
||||
IPI_NUM_FLUSH_TLB => {
|
||||
FlushTLBIpiHandler.handle(irq, None, None).ok();
|
||||
CurrentApic.send_eoi();
|
||||
}
|
||||
_ => {
|
||||
kerror!("Unknown IPI: {}", irq.data());
|
||||
CurrentApic.send_eoi();
|
||||
}
|
||||
}
|
||||
|
||||
CurrentApic.send_eoi();
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use crate::{
|
||||
fpu::FpState,
|
||||
interrupt::TrapFrame,
|
||||
process::table::{USER_CS, USER_DS},
|
||||
sched::sched,
|
||||
CurrentIrqArch, MMArch,
|
||||
},
|
||||
exception::InterruptArch,
|
||||
@ -18,6 +17,7 @@ use crate::{
|
||||
kerror,
|
||||
mm::MemoryManagementArch,
|
||||
process::ProcessManager,
|
||||
sched::{schedule, SchedMode},
|
||||
syscall::{user_access::UserBufferWriter, Syscall},
|
||||
};
|
||||
|
||||
@ -715,7 +715,7 @@ fn sig_stop(sig: Signal) {
|
||||
);
|
||||
});
|
||||
drop(guard);
|
||||
sched();
|
||||
schedule(SchedMode::SM_NONE);
|
||||
// TODO 暂停进程
|
||||
}
|
||||
/// 信号默认处理函数——继续进程
|
||||
|
@ -1,11 +1,21 @@
|
||||
use core::hint::spin_loop;
|
||||
|
||||
use crate::{arch::CurrentIrqArch, exception::InterruptArch, kBUG, process::ProcessManager};
|
||||
use crate::{
|
||||
arch::CurrentIrqArch,
|
||||
exception::InterruptArch,
|
||||
kBUG,
|
||||
process::{ProcessFlags, ProcessManager},
|
||||
sched::{SchedMode, __schedule},
|
||||
};
|
||||
|
||||
impl ProcessManager {
|
||||
/// 每个核的idle进程
|
||||
pub fn arch_idle_func() -> ! {
|
||||
loop {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
if pcb.flags().contains(ProcessFlags::NEED_SCHEDULE) {
|
||||
__schedule(SchedMode::SM_NONE);
|
||||
}
|
||||
if CurrentIrqArch::is_irq_enabled() {
|
||||
unsafe {
|
||||
x86::halt();
|
||||
|
@ -563,6 +563,8 @@ pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<Str
|
||||
current_pcb.flags().remove(ProcessFlags::KTHREAD);
|
||||
current_pcb.worker_private().take();
|
||||
|
||||
*current_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::CFS;
|
||||
|
||||
let mut trap_frame = TrapFrame::new();
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
@ -591,6 +593,7 @@ unsafe extern "sysv64" fn ready_to_switch_to_user(
|
||||
new_rip: usize,
|
||||
) -> ! {
|
||||
*(trapframe_vaddr as *mut TrapFrame) = trap_frame;
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
asm!(
|
||||
"swapgs",
|
||||
"mov rsp, {trapframe_vaddr}",
|
||||
@ -601,3 +604,35 @@ unsafe extern "sysv64" fn ready_to_switch_to_user(
|
||||
);
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
// bitflags! {
|
||||
// pub struct ProcessThreadFlags: u32 {
|
||||
// /*
|
||||
// * thread information flags
|
||||
// * - these are process state flags that various assembly files
|
||||
// * may need to access
|
||||
// */
|
||||
// const TIF_NOTIFY_RESUME = 1 << 1; /* callback before returning to user */
|
||||
// const TIF_SIGPENDING = 1 << 2; /* signal pending */
|
||||
// const TIF_NEED_RESCHED = 1 << 3; /* rescheduling necessary */
|
||||
// const TIF_SINGLESTEP = 1 << 4; /* reenable singlestep on user return*/
|
||||
// const TIF_SSBD = 1 << 5; /* Speculative store bypass disable */
|
||||
// const TIF_SPEC_IB = 1 << 9; /* Indirect branch speculation mitigation */
|
||||
// const TIF_SPEC_L1D_FLUSH = 1 << 10; /* Flush L1D on mm switches (processes) */
|
||||
// const TIF_USER_RETURN_NOTIFY = 1 << 11; /* notify kernel of userspace return */
|
||||
// const TIF_UPROBE = 1 << 12; /* breakpointed or singlestepping */
|
||||
// const TIF_PATCH_PENDING = 1 << 13; /* pending live patching update */
|
||||
// const TIF_NEED_FPU_LOAD = 1 << 14; /* load FPU on return to userspace */
|
||||
// const TIF_NOCPUID = 1 << 15; /* CPUID is not accessible in userland */
|
||||
// const TIF_NOTSC = 1 << 16; /* TSC is not accessible in userland */
|
||||
// const TIF_NOTIFY_SIGNAL = 1 << 17; /* signal notifications exist */
|
||||
// const TIF_MEMDIE = 1 << 20; /* is terminating due to OOM killer */
|
||||
// const TIF_POLLING_NRFLAG = 1 << 21; /* idle is polling for TIF_NEED_RESCHED */
|
||||
// const TIF_IO_BITMAP = 1 << 22; /* uses I/O bitmap */
|
||||
// const TIF_SPEC_FORCE_UPDATE = 1 << 23; /* Force speculation MSR update in context switch */
|
||||
// const TIF_FORCED_TF = 1 << 24; /* true if TF in eflags artificially */
|
||||
// const TIF_BLOCKSTEP = 1 << 25; /* set when we want DEBUGCTLMSR_BTF */
|
||||
// const TIF_LAZY_MMU_UPDATES = 1 << 27; /* task is updating the mmu lazily */
|
||||
// const TIF_ADDR32 = 1 << 29; /* 32-bit address space on 64 bits */
|
||||
// }
|
||||
// }
|
||||
|
@ -1,20 +1,19 @@
|
||||
use core::hint::spin_loop;
|
||||
|
||||
use crate::{
|
||||
exception::InterruptArch, include::bindings::bindings::enter_syscall_int, sched::SchedArch,
|
||||
smp::core::smp_get_processor_id, syscall::SYS_SCHED,
|
||||
};
|
||||
use crate::{exception::InterruptArch, sched::SchedArch, smp::core::smp_get_processor_id};
|
||||
|
||||
use super::{driver::apic::apic_timer::apic_timer_init, CurrentIrqArch};
|
||||
|
||||
/// @brief 若内核代码不处在中断上下文中,那么将可以使用本函数,发起一个sys_sched系统调用,然后运行调度器。
|
||||
/// 由于只能在中断上下文中进行进程切换,因此需要发起一个系统调用SYS_SCHED。
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sched() {
|
||||
unsafe {
|
||||
enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
// /// @brief 若内核代码不处在中断上下文中,那么将可以使用本函数,发起一个sys_sched系统调用,然后运行调度器。
|
||||
// /// 由于只能在中断上下文中进行进程切换,因此需要发起一个系统调用SYS_SCHED。
|
||||
// #[no_mangle]
|
||||
// pub extern "C" fn sched() {
|
||||
// let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||
// __schedule(SchedMode::SM_NONE);
|
||||
// // unsafe {
|
||||
// // enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0);
|
||||
// // }
|
||||
// }
|
||||
|
||||
static mut BSP_INIT_OK: bool = false;
|
||||
|
||||
|
Reference in New Issue
Block a user