Skip to content
13 changes: 8 additions & 5 deletions kernel/src/arch/x86_64/driver/apic/apic_timer.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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);
}
}
Expand Down
5 changes: 5 additions & 0 deletions kernel/src/arch/x86_64/driver/apic/x2apic.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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 版本
Expand Down
8 changes: 3 additions & 5 deletions kernel/src/arch/x86_64/interrupt/handle.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
}
}
4 changes: 2 additions & 2 deletions kernel/src/arch/x86_64/interrupt/ipi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
4 changes: 2 additions & 2 deletions kernel/src/arch/x86_64/ipc/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::{
fpu::FpState,
interrupt::TrapFrame,
process::table::{USER_CS, USER_DS},
sched::sched,
CurrentIrqArch, MMArch,
},
exception::InterruptArch,
Expand All @@ -18,6 +17,7 @@ use crate::{
kerror,
mm::MemoryManagementArch,
process::ProcessManager,
sched::{schedule, SchedMode},
syscall::{user_access::UserBufferWriter, Syscall},
};

Expand Down Expand Up @@ -715,7 +715,7 @@ fn sig_stop(sig: Signal) {
);
});
drop(guard);
sched();
schedule(SchedMode::SM_NONE);
// TODO 暂停进程
}
/// 信号默认处理函数——继续进程
Expand Down
12 changes: 11 additions & 1 deletion kernel/src/arch/x86_64/process/idle.rs
Original file line number Diff line number Diff line change
@@ -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();
Expand Down
35 changes: 35 additions & 0 deletions kernel/src/arch/x86_64/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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}",
Expand All @@ -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 */
// }
// }
23 changes: 11 additions & 12 deletions kernel/src/arch/x86_64/sched.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
19 changes: 8 additions & 11 deletions kernel/src/driver/tty/kthread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ use alloc::{string::ToString, sync::Arc};
use kdepends::thingbuf::StaticThingBuf;

use crate::{
arch::sched::sched,
arch::CurrentIrqArch,
driver::tty::virtual_terminal::virtual_console::CURRENT_VCNUM,
exception::InterruptArch,
process::{
kthread::{KernelThreadClosure, KernelThreadMechanism},
ProcessControlBlock, ProcessFlags,
ProcessControlBlock, ProcessManager,
},
sched::{schedule, SchedMode},
};

use super::tty_port::current_tty_port;
Expand All @@ -35,15 +37,9 @@ fn tty_refresh_thread() -> i32 {
loop {
if KEYBUF.is_empty() {
// 如果缓冲区为空,就休眠
unsafe {
TTY_REFRESH_THREAD
.as_ref()
.unwrap()
.flags()
.insert(ProcessFlags::NEED_SCHEDULE)
};

sched();
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
ProcessManager::mark_sleep(true).expect("TTY_REFRESH_THREAD can not mark sleep");
schedule(SchedMode::SM_NONE);
}

let to_dequeue = core::cmp::min(KEYBUF.len(), TO_DEQUEUE_MAX);
Expand All @@ -69,4 +65,5 @@ pub fn send_to_tty_refresh_thread(data: &[u8]) {
for item in data {
KEYBUF.push(*item).ok();
}
let _ = ProcessManager::wakeup(unsafe { TTY_REFRESH_THREAD.as_ref().unwrap() });
}
12 changes: 10 additions & 2 deletions kernel/src/exception/ipi.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use alloc::sync::Arc;
use system_error::SystemError;

#[cfg(target_arch = "x86_64")]
use crate::arch::driver::apic::{CurrentApic, LocalAPIC};

use crate::{
arch::{sched::sched, MMArch},
arch::MMArch,
mm::MemoryManagementArch,
sched::{SchedMode, __schedule},
smp::cpu::ProcessorId,
};

Expand Down Expand Up @@ -47,7 +51,11 @@ impl IrqHandler for KickCpuIpiHandler {
_static_data: Option<&dyn IrqHandlerData>,
_dynamic_data: Option<Arc<dyn IrqHandlerData>>,
) -> Result<IrqReturn, SystemError> {
sched();
#[cfg(target_arch = "x86_64")]
CurrentApic.send_eoi();

// 被其他cpu kick时应该是抢占调度
__schedule(SchedMode::SM_PREEMPT);
Ok(IrqReturn::Handled)
}
}
Expand Down
8 changes: 7 additions & 1 deletion kernel/src/exception/softirq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::{
intrinsics::unlikely,
mem::{self, MaybeUninit},
ptr::null_mut,
sync::atomic::{compiler_fence, AtomicI16, Ordering},
sync::atomic::{compiler_fence, fence, AtomicI16, Ordering},
};

use alloc::{boxed::Box, sync::Arc, vec::Vec};
Expand All @@ -17,6 +17,7 @@ use crate::{
libs::rwlock::RwLock,
mm::percpu::{PerCpu, PerCpuVar},
process::ProcessManager,
sched::cputime::IrqTime,
smp::{core::smp_get_processor_id, cpu::ProcessorId},
time::timer::clock,
};
Expand Down Expand Up @@ -286,6 +287,11 @@ impl<'a> Drop for RunningCountGuard<'a> {
}
}

#[inline(never)]
pub fn do_softirq() {
fence(Ordering::SeqCst);
IrqTime::irqtime_start();
softirq_vectors().do_softirq();
IrqTime::irqtime_account_irq(ProcessManager::current_pcb());
fence(Ordering::SeqCst);
}
10 changes: 3 additions & 7 deletions kernel/src/filesystem/procfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ impl ProcFSInode {
.map(|cpu| cpu.data() as i32)
.unwrap_or(-1);

let priority = sched_info_guard.priority();
let vrtime = sched_info_guard.virtual_runtime();
let priority = sched_info_guard.policy();
let vrtime = sched_info_guard.sched_entity.vruntime;

pdata.append(&mut format!("\nState:\t{:?}", state).as_bytes().to_owned());
pdata.append(
Expand All @@ -183,11 +183,7 @@ impl ProcFSInode {
.to_owned(),
);
pdata.append(&mut format!("\ncpu_id:\t{}", cpu_id).as_bytes().to_owned());
pdata.append(
&mut format!("\npriority:\t{}", priority.data())
.as_bytes()
.to_owned(),
);
pdata.append(&mut format!("\npriority:\t{:?}", priority).as_bytes().to_owned());
pdata.append(
&mut format!("\npreempt:\t{}", pcb.preempt_count())
.as_bytes()
Expand Down
1 change: 0 additions & 1 deletion kernel/src/include/bindings/wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,5 @@
#include <mm/mmio.h>
#include <mm/slab.h>
#include <process/process.h>
#include <sched/sched.h>
#include <time/sleep.h>
#include <common/errno.h>
5 changes: 3 additions & 2 deletions kernel/src/init/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
},
mm::init::mm_init,
process::{kthread::kthread_init, process_init, ProcessManager},
sched::{core::sched_init, SchedArch},
sched::SchedArch,
smp::{early_smp_init, SMPArch},
syscall::Syscall,
time::{
Expand Down Expand Up @@ -59,13 +59,14 @@ fn do_start_kernel() {
unsafe {
acpi_init()
};
crate::sched::sched_init();
process_init();
early_smp_init().expect("early smp init failed");
irq_init().expect("irq init failed");
setup_arch().expect("setup_arch failed");
CurrentSMPArch::prepare_cpus().expect("prepare_cpus failed");

sched_init();
// sched_init();
softirq_init().expect("softirq init failed");
Syscall::init().expect("syscall init failed");
timekeeping_init();
Expand Down
Loading