Patch fix sched and net lockdep error (#479)

- fix: 修复调度器,软中断,定时器,网络子系统的部分锁的使用不符合锁依赖安全规范的问题
- fix: 修复创建pcb时内核栈爆栈的问题
- 把异常的trap gate改成intr gate

---------

Co-authored-by: GnoCiYeH <heyicong@dragonos.org>
This commit is contained in:
LoGin 2023-12-27 14:27:12 +08:00 committed by GitHub
parent 91e9d4ab55
commit 0d6cf65aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 406 additions and 246 deletions

View File

@ -57,9 +57,10 @@ int apic_init()
*/
void do_IRQ(struct pt_regs *rsp, ul number)
{
if((rsp->cs & 0x3) == 3)
if ((rsp->cs & 0x3) == 3)
{
asm volatile("swapgs":::"memory");
asm volatile("swapgs" ::: "memory");
}
if (number < 0x80 && number >= 32) // 以0x80为界限低于0x80的是外部中断控制器高于0x80的是Local APIC
{

View File

@ -112,7 +112,7 @@ pub enum LocalApicTimerMode {
impl LocalApicTimer {
/// 定时器中断的间隔
pub const INTERVAL_MS: u64 = 1000 / HZ as u64;
pub const DIVISOR: u64 = 3;
pub const DIVISOR: u64 = 4;
/// IoApicManager 初值为0或false
pub const fn new() -> Self {
@ -131,7 +131,7 @@ impl LocalApicTimer {
// 疑惑这里使用khz吗
// 我觉得应该是hz但是由于旧的代码是测量出initcnt的而不是计算的
// 然后我发现使用hz会导致计算出来的initcnt太大导致系统卡顿而khz的却能跑
let count = cpu_khz * Self::INTERVAL_MS / (1000 * Self::DIVISOR);
let count = cpu_khz * Self::INTERVAL_MS / (Self::DIVISOR);
return count;
}

View File

@ -10,11 +10,15 @@ use acpi::HpetInfo;
use system_error::SystemError;
use crate::{
arch::CurrentIrqArch,
driver::{
acpi::acpi_manager,
timers::hpet::{HpetRegisters, HpetTimerRegisters},
},
exception::softirq::{softirq_vectors, SoftirqNumber},
exception::{
softirq::{softirq_vectors, SoftirqNumber},
InterruptArch,
},
kdebug, kerror, kinfo,
libs::{
rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
@ -51,8 +55,8 @@ struct InnerHpet {
}
impl Hpet {
/// HPET0 中断间隔为500us
pub const HPET0_INTERVAL_USEC: u64 = 500;
/// HPET0 中断间隔为 10ms
pub const HPET0_INTERVAL_USEC: u64 = 10000;
fn new(mut hpet_info: HpetInfo) -> Result<Self, SystemError> {
let paddr = PhysAddr::new(hpet_info.base_address);
@ -222,7 +226,8 @@ impl Hpet {
/// 处理HPET的中断
pub(super) fn handle_irq(&self, timer_num: u32) {
if timer_num == 0 {
update_timer_jiffies(Self::HPET0_INTERVAL_USEC);
assert!(CurrentIrqArch::is_irq_enabled() == false);
update_timer_jiffies(Self::HPET0_INTERVAL_USEC, Self::HPET0_INTERVAL_USEC as i64);
if let Ok(first_expire) = timer_get_first_expire() {
if first_expire <= clock() {

View File

@ -239,6 +239,17 @@ impl TSCManager {
///
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/arch/x86/kernel/tsc.c#389
fn pit_calibrate_tsc(latch: u64, ms: u64, loopmin: u64) -> Option<u64> {
// 当前暂时没写legacy pic的驱动因此这里直接返回
let has_legacy_pic = false;
if !has_legacy_pic {
let mut cnt = 10000;
while cnt > 0 {
cnt -= 1;
}
return None;
}
unsafe {
// Set the Gate high, disable speaker
let d = (CurrentPortIOArch::in8(0x61) & (!0x02)) | 0x01;

View File

@ -384,7 +384,7 @@ impl SigContext {
/// - `false` -> 执行失败
pub fn restore_sigcontext(&mut self, frame: &mut TrapFrame) -> bool {
let guard = ProcessManager::current_pcb();
let mut arch_info = guard.arch_info();
let mut arch_info = guard.arch_info_irqsave();
(*frame) = self.frame.clone();
// (*current_thread).trap_num = (*context).trap_num;
*arch_info.cr2_mut() = self.cr2 as usize;

View File

@ -98,6 +98,7 @@ impl ArchPCBInfo {
/// ## 返回值
///
/// 返回一个新的ArchPCBInfo
#[inline(never)]
pub fn new(kstack: &KernelStack) -> Self {
let mut r = Self {
rflags: 0,
@ -325,7 +326,7 @@ impl ProcessManager {
child_trapframe.set_return_value(0);
// 设置子进程的栈基址(开始执行中断返回流程时的栈基址)
let mut new_arch_guard = new_pcb.arch_info();
let mut new_arch_guard = unsafe { new_pcb.arch_info() };
let kernel_stack_guard = new_pcb.kernel_stack();
// 设置子进程在内核态开始执行时的rsp、rbp
@ -385,13 +386,13 @@ impl ProcessManager {
assert!(CurrentIrqArch::is_irq_enabled() == false);
// 保存浮点寄存器
prev.arch_info().save_fp_state();
prev.arch_info_irqsave().save_fp_state();
// 切换浮点寄存器
next.arch_info().restore_fp_state();
next.arch_info_irqsave().restore_fp_state();
// 切换fsbase
prev.arch_info().save_fsbase();
next.arch_info().restore_fsbase();
prev.arch_info_irqsave().save_fsbase();
next.arch_info_irqsave().restore_fsbase();
// 切换gsbase
Self::switch_gsbase(&prev, &next);
@ -406,8 +407,8 @@ impl ProcessManager {
// 切换内核栈
// 获取arch info的锁并强制泄露其守卫切换上下文后在switch_finish_hook中会释放锁
let next_arch = SpinLockGuard::leak(next.arch_info()) as *mut ArchPCBInfo;
let prev_arch = SpinLockGuard::leak(prev.arch_info()) as *mut ArchPCBInfo;
let next_arch = SpinLockGuard::leak(next.arch_info_irqsave()) as *mut ArchPCBInfo;
let prev_arch = SpinLockGuard::leak(prev.arch_info_irqsave()) as *mut ArchPCBInfo;
(*prev_arch).rip = switch_back as usize;
@ -430,10 +431,10 @@ impl ProcessManager {
unsafe fn switch_gsbase(prev: &Arc<ProcessControlBlock>, next: &Arc<ProcessControlBlock>) {
asm!("swapgs", options(nostack, preserves_flags));
prev.arch_info().save_gsbase();
next.arch_info().restore_gsbase();
prev.arch_info_irqsave().save_gsbase();
next.arch_info_irqsave().restore_gsbase();
// 将下一个进程的kstack写入kernel_gsbase
next.arch_info().store_kernel_gsbase();
next.arch_info_irqsave().store_kernel_gsbase();
asm!("swapgs", options(nostack, preserves_flags));
}
}

View File

@ -67,7 +67,11 @@ macro_rules! syscall_return {
pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
let syscall_num = frame.rax as usize;
// 防止sys_sched由于超时无法退出导致的死锁
if syscall_num != SYS_SCHED {
if syscall_num == SYS_SCHED {
unsafe {
CurrentIrqArch::interrupt_disable();
}
} else {
unsafe {
CurrentIrqArch::interrupt_enable();
}

View File

@ -343,6 +343,8 @@ pub fn e1000e_driver_init(device: E1000EDevice) {
let driver = E1000EDriver::new(device);
let iface = E1000EInterface::new(driver);
// 将网卡的接口信息注册到全局的网卡接口信息表中
NET_DRIVERS.write().insert(iface.nic_id(), iface.clone());
NET_DRIVERS
.write_irqsave()
.insert(iface.nic_id(), iface.clone());
kinfo!("e1000e driver init successfully!\tMAC: [{}]", mac);
}

View File

@ -234,7 +234,9 @@ pub fn virtio_net<T: Transport + 'static>(transport: T) {
let iface = VirtioInterface::new(driver);
let name = iface.name.clone();
// 将网卡的接口信息注册到全局的网卡接口信息表中
NET_DRIVERS.write().insert(iface.nic_id(), iface.clone());
NET_DRIVERS
.write_irqsave()
.insert(iface.nic_id(), iface.clone());
kinfo!(
"Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]",
name,

View File

@ -3,16 +3,21 @@ use core::{
intrinsics::unlikely,
mem::{self, MaybeUninit},
ptr::null_mut,
sync::atomic::{compiler_fence, Ordering},
sync::atomic::{compiler_fence, AtomicI16, Ordering},
};
use alloc::{boxed::Box, sync::Arc};
use alloc::{boxed::Box, sync::Arc, vec::Vec};
use num_traits::FromPrimitive;
use system_error::SystemError;
use crate::{
arch::CurrentIrqArch, exception::InterruptArch, kdebug, kinfo, libs::rwlock::RwLock,
mm::percpu::PerCpu, process::ProcessManager, smp::core::smp_get_processor_id,
arch::CurrentIrqArch,
exception::InterruptArch,
kdebug, kinfo,
libs::rwlock::RwLock,
mm::percpu::{PerCpu, PerCpuVar},
process::ProcessManager,
smp::core::smp_get_processor_id,
time::timer::clock,
};
@ -94,8 +99,12 @@ pub trait SoftirqVec: Send + Sync + Debug {
#[derive(Debug)]
pub struct Softirq {
table: RwLock<[Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>,
/// 软中断嵌套层数per cpu
cpu_running_count: PerCpuVar<AtomicI16>,
}
impl Softirq {
/// 每个CPU最大嵌套的软中断数量
const MAX_RUNNING_PER_CPU: i16 = 3;
fn new() -> Softirq {
let mut data: [MaybeUninit<Option<Arc<dyn SoftirqVec>>>; MAX_SOFTIRQ_NUM as usize] =
unsafe { MaybeUninit::uninit().assume_init() };
@ -108,11 +117,20 @@ impl Softirq {
mem::transmute::<_, [Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>(data)
};
let mut percpu_count = Vec::with_capacity(PerCpu::MAX_CPU_NUM as usize);
percpu_count.resize_with(PerCpu::MAX_CPU_NUM as usize, || AtomicI16::new(0));
let cpu_running_count = PerCpuVar::new(percpu_count).unwrap();
return Softirq {
table: RwLock::new(data),
cpu_running_count,
};
}
fn cpu_running_count(&self) -> &PerCpuVar<AtomicI16> {
return &self.cpu_running_count;
}
/// @brief 注册软中断向量
///
/// @param softirq_num 中断向量号
@ -127,7 +145,7 @@ impl Softirq {
// let self = &mut SOFTIRQ_VECTORS.lock();
// 判断该软中断向量是否已经被注册
let mut table_guard = self.table.write();
let mut table_guard = self.table.write_irqsave();
if table_guard[softirq_num as usize].is_some() {
// kdebug!("register_softirq failed");
@ -149,7 +167,7 @@ impl Softirq {
/// @param irq_num 中断向量号码
pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) {
// kdebug!("unregister_softirq softirq_num = {:?}", softirq_num as u64);
let mut table_guard = self.table.write();
let mut table_guard = self.table.write_irqsave();
// 将软中断向量清空
table_guard[softirq_num as usize] = None;
drop(table_guard);
@ -162,8 +180,14 @@ impl Softirq {
}
pub fn do_softirq(&self) {
if self.cpu_running_count().get().load(Ordering::SeqCst) >= Self::MAX_RUNNING_PER_CPU {
// 当前CPU的软中断嵌套层数已经达到最大值不再执行
return;
}
// 创建一个RunningCountGuard当退出作用域时会自动将cpu_running_count减1
let _count_guard = RunningCountGuard::new(self.cpu_running_count());
// TODO pcb的flags未修改
// todo: 是否需要判断在当前cpu上面该函数的嵌套层数防止爆栈
let end = clock() + 500 * 2;
let cpu_id = smp_get_processor_id();
let mut max_restart = MAX_SOFTIRQ_RESTART;
@ -180,7 +204,7 @@ impl Softirq {
continue;
}
let table_guard = self.table.read();
let table_guard = self.table.read_irqsave();
let softirq_func = table_guard[i as usize].clone();
drop(table_guard);
if softirq_func.is_none() {
@ -236,6 +260,27 @@ impl Softirq {
}
}
/// 当前CPU的软中断嵌套层数的计数器守卫
///
/// 当进入作用域时会自动将cpu_running_count加1
/// 当退出作用域时会自动将cpu_running_count减1
struct RunningCountGuard<'a> {
cpu_running_count: &'a PerCpuVar<AtomicI16>,
}
impl<'a> RunningCountGuard<'a> {
fn new(cpu_running_count: &'a PerCpuVar<AtomicI16>) -> RunningCountGuard {
cpu_running_count.get().fetch_add(1, Ordering::SeqCst);
return RunningCountGuard { cpu_running_count };
}
}
impl<'a> Drop for RunningCountGuard<'a> {
fn drop(&mut self) {
self.cpu_running_count.get().fetch_sub(1, Ordering::SeqCst);
}
}
// ======= 以下为给C提供的接口 =======
#[no_mangle]
pub extern "C" fn rs_raise_softirq(softirq_num: u32) {

View File

@ -316,27 +316,27 @@ void sys_vector_init()
for (int i = 0; i < 256; ++i)
set_intr_gate(i, 0, ignore_int);
set_trap_gate(0, 0, divide_error);
set_trap_gate(1, 0, debug);
set_intr_gate(0, 0, divide_error);
set_intr_gate(1, 0, debug);
set_intr_gate(2, 0, nmi);
set_system_trap_gate(3, 0, int3);
set_system_trap_gate(4, 0, overflow);
set_system_trap_gate(5, 0, bounds);
set_trap_gate(6, 0, undefined_opcode);
set_trap_gate(7, 0, dev_not_avaliable);
set_trap_gate(8, 0, double_fault);
set_trap_gate(9, 0, coprocessor_segment_overrun);
set_trap_gate(10, 0, invalid_TSS);
set_trap_gate(11, 0, segment_not_exists);
set_trap_gate(12, 0, stack_segment_fault);
set_trap_gate(13, 0, general_protection);
set_trap_gate(14, 0, page_fault);
set_intr_gate(6, 0, undefined_opcode);
set_intr_gate(7, 0, dev_not_avaliable);
set_intr_gate(8, 0, double_fault);
set_intr_gate(9, 0, coprocessor_segment_overrun);
set_intr_gate(10, 0, invalid_TSS);
set_intr_gate(11, 0, segment_not_exists);
set_intr_gate(12, 0, stack_segment_fault);
set_intr_gate(13, 0, general_protection);
set_intr_gate(14, 0, page_fault);
// 中断号15由Intel保留不能使用
set_trap_gate(16, 0, x87_FPU_error);
set_trap_gate(17, 0, alignment_check);
set_trap_gate(18, 0, machine_check);
set_trap_gate(19, 0, SIMD_exception);
set_trap_gate(20, 0, virtualization_exception);
set_intr_gate(16, 0, x87_FPU_error);
set_intr_gate(17, 0, alignment_check);
set_intr_gate(18, 0, machine_check);
set_intr_gate(19, 0, SIMD_exception);
set_intr_gate(20, 0, virtualization_exception);
// 中断号21-31由Intel保留不能使用
// 32-255为用户自定义中断内部

View File

@ -146,7 +146,7 @@ impl ProcFSInode {
);
let sched_info_guard = pcb.sched_info();
let state = sched_info_guard.state();
let state = sched_info_guard.inner_lock_read_irqsave().state();
let cpu_id = sched_info_guard
.on_cpu()
.map(|cpu| cpu as i32)
@ -155,8 +155,6 @@ impl ProcFSInode {
let priority = sched_info_guard.priority();
let vrtime = sched_info_guard.virtual_runtime();
drop(sched_info_guard);
pdata.append(&mut format!("\nState:\t{:?}", state).as_bytes().to_owned());
pdata.append(
&mut format!("\nPid:\t{}", pcb.pid().into())

View File

@ -201,10 +201,8 @@ impl Signal {
if *self == Signal::SIGKILL {
return true;
}
if pcb.sched_info().state().is_blocked()
&& (pcb.sched_info().state().is_blocked_interruptable() == false)
{
let state = pcb.sched_info().inner_lock_read_irqsave().state();
if state.is_blocked() && (state.is_blocked_interruptable() == false) {
return false;
}
@ -287,7 +285,7 @@ fn signal_wake_up(pcb: Arc<ProcessControlBlock>, _guard: SpinLockGuard<SignalStr
// 如果不是 fatal 的就只唤醒 stop 的进程来响应
// kdebug!("signal_wake_up");
// 如果目标进程已经在运行则发起一个ipi使得它陷入内核
let state = pcb.sched_info().state();
let state = pcb.sched_info().inner_lock_read_irqsave().state();
let mut wakeup_ok = true;
if state.is_blocked_interruptable() {
ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
@ -337,7 +335,7 @@ fn recalc_sigpending() {
pub fn flush_signal_handlers(pcb: Arc<ProcessControlBlock>, force_default: bool) {
compiler_fence(core::sync::atomic::Ordering::SeqCst);
// kdebug!("hand=0x{:018x}", hand as *const sighand_struct as usize);
let actions = &mut pcb.sig_struct().handlers;
let actions = &mut pcb.sig_struct_irqsave().handlers;
for sigaction in actions.iter_mut() {
if force_default || !sigaction.is_ignore() {
@ -436,7 +434,7 @@ pub fn set_current_sig_blocked(new_set: &mut SigSet) {
return;
}
let guard = pcb.sig_struct_irq();
let guard = pcb.sig_struct_irqsave();
// todo: 当一个进程有多个线程后在这里需要设置每个线程的block字段并且 retarget_shared_pending虽然我还没搞明白linux这部分是干啥的
// 设置当前进程的sig blocked

View File

@ -1,6 +1,11 @@
use core::{ffi::c_void, mem::size_of, sync::atomic::AtomicI64};
use core::{
ffi::c_void,
mem::size_of,
ops::{Deref, DerefMut},
sync::atomic::AtomicI64,
};
use alloc::vec::Vec;
use alloc::{boxed::Box, vec::Vec};
use system_error::SystemError;
use crate::{
@ -55,13 +60,41 @@ pub const SIG_KERNEL_IGNORE_MASK: SigSet = Signal::into_sigset(Signal::SIGCONT)
/// SignalStruct 在 pcb 中加锁
#[derive(Debug)]
pub struct SignalStruct {
inner: Box<InnerSignalStruct>,
}
#[derive(Debug)]
pub struct InnerSignalStruct {
pub cnt: AtomicI64,
/// 如果对应linux这部分会有一个引用计数但是没发现在哪里有用到需要计算引用的地方因此
/// 暂时删掉不然这个Arc会导致其他地方的代码十分丑陋
pub handlers: [Sigaction; MAX_SIG_NUM as usize],
}
impl Default for SignalStruct {
impl SignalStruct {
#[inline(never)]
pub fn new() -> Self {
Self {
inner: Box::new(InnerSignalStruct::default()),
}
}
}
impl Deref for SignalStruct {
type Target = InnerSignalStruct;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl DerefMut for SignalStruct {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl Default for InnerSignalStruct {
fn default() -> Self {
Self {
cnt: Default::default(),

View File

@ -164,6 +164,7 @@ impl<T> RwLock<T> {
} //忙等待
}
/// 关中断并获取读者守卫
pub fn read_irqsave(&self) -> RwLockReadGuard<T> {
loop {
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
@ -177,6 +178,17 @@ impl<T> RwLock<T> {
}
}
/// 尝试关闭中断并获取读者守卫
pub fn try_read_irqsave(&self) -> Option<RwLockReadGuard<T>> {
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
if let Some(mut guard) = self.try_read() {
guard.irq_guard = Some(irq_guard);
return Some(guard);
} else {
return None;
}
}
#[allow(dead_code)]
#[inline]
/// @brief 获取读者+UPGRADER的数量, 不能保证能否获得同步值

View File

@ -184,18 +184,27 @@ impl WaitQueue {
/// @return true 成功唤醒进程
/// @return false 没有唤醒进程
pub fn wakeup(&self, state: Option<ProcessState>) -> bool {
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
// 如果队列为空,则返回
if guard.wait_list.is_empty() {
return false;
}
// 如果队列头部的pcb的state与给定的state相与结果不为0则唤醒
if let Some(state) = state {
if guard.wait_list.front().unwrap().sched_info().state() != state {
if guard
.wait_list
.front()
.unwrap()
.sched_info()
.inner_lock_read_irqsave()
.state()
!= state
{
return false;
}
}
let to_wakeup = guard.wait_list.pop_front().unwrap();
drop(guard);
let res = ProcessManager::wakeup(&to_wakeup).is_ok();
return res;
}
@ -215,7 +224,7 @@ impl WaitQueue {
while let Some(to_wakeup) = guard.wait_list.pop_front() {
let mut wake = false;
if let Some(state) = state {
if to_wakeup.sched_info().state() == state {
if to_wakeup.sched_info().inner_lock_read_irqsave().state() == state {
wake = true;
}
} else {
@ -302,7 +311,7 @@ impl EventWaitQueue {
pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) {
before_sleep_check(1);
let mut guard = self.wait_list.lock();
let mut guard = self.wait_list.lock_irqsave();
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
panic!("sleep error: {:?}", e);
@ -322,7 +331,9 @@ impl EventWaitQueue {
/// 需要注意的是只要触发了events中的任意一件事件进程都会被唤醒
pub fn wakeup_any(&self, events: u64) -> usize {
let mut ret = 0;
let _ = self.wait_list.lock().extract_if(|(es, pcb)| {
let mut wq_guard = self.wait_list.lock_irqsave();
wq_guard.retain(|(es, pcb)| {
if *es & events > 0 {
// 有感兴趣的事件
if ProcessManager::wakeup(pcb).is_ok() {
@ -346,7 +357,8 @@ impl EventWaitQueue {
/// 需要注意的是,只有满足所有事件的进程才会被唤醒
pub fn wakeup(&self, events: u64) -> usize {
let mut ret = 0;
let _ = self.wait_list.lock().extract_if(|(es, pcb)| {
let mut wq_guard = self.wait_list.lock_irqsave();
wq_guard.retain(|(es, pcb)| {
if *es == events {
// 有感兴趣的事件
if ProcessManager::wakeup(pcb).is_ok() {

View File

@ -30,11 +30,13 @@ pub mod socket;
pub mod syscall;
lazy_static! {
/// @brief 所有网络接口的列表
/// 所有网络接口的列表
///
/// 这个列表在中断上下文会使用到因此需要irqsave
pub static ref NET_DRIVERS: RwLock<BTreeMap<usize, Arc<dyn NetDriver>>> = RwLock::new(BTreeMap::new());
}
/// @brief 生成网络接口的id (全局自增)
/// 生成网络接口的id (全局自增)
pub fn generate_iface_id() -> usize {
static IFACE_ID: AtomicUsize = AtomicUsize::new(0);
return IFACE_ID

View File

@ -41,7 +41,7 @@ pub fn net_init() -> Result<(), SystemError> {
}
fn dhcp_query() -> Result<(), SystemError> {
let binding = NET_DRIVERS.write();
let binding = NET_DRIVERS.write_irqsave();
let net_face = binding.get(&0).ok_or(SystemError::ENODEV)?.clone();
@ -56,13 +56,13 @@ fn dhcp_query() -> Result<(), SystemError> {
// IMPORTANT: This should be removed in production.
dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
let dhcp_handle = SOCKET_SET.lock().add(dhcp_socket);
let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket);
const DHCP_TRY_ROUND: u8 = 10;
for i in 0..DHCP_TRY_ROUND {
kdebug!("DHCP try round: {}", i);
net_face.poll(&mut SOCKET_SET.lock()).ok();
let mut binding = SOCKET_SET.lock();
net_face.poll(&mut SOCKET_SET.lock_irqsave()).ok();
let mut binding = SOCKET_SET.lock_irqsave();
let event = binding.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
match event {
@ -120,12 +120,12 @@ fn dhcp_query() -> Result<(), SystemError> {
}
pub fn poll_ifaces() {
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read_irqsave();
if guard.len() == 0 {
kwarn!("poll_ifaces: No net driver found!");
return;
}
let mut sockets = SOCKET_SET.lock();
let mut sockets = SOCKET_SET.lock_irqsave();
for (_, iface) in guard.iter() {
iface.poll(&mut sockets).ok();
}
@ -140,13 +140,14 @@ pub fn poll_ifaces() {
pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
let mut i = 0;
while i < times {
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> =
NET_DRIVERS.read_irqsave();
if guard.len() == 0 {
kwarn!("poll_ifaces: No net driver found!");
// 没有网卡,返回错误
return Err(SystemError::ENODEV);
}
let sockets = SOCKET_SET.try_lock();
let sockets = SOCKET_SET.try_lock_irqsave();
// 加锁失败,继续尝试
if sockets.is_err() {
i += 1;
@ -171,13 +172,13 @@ pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
/// @return 加锁超时返回SystemError::EAGAIN_OR_EWOULDBLOCK
/// @return 没有网卡返回SystemError::ENODEV
pub fn poll_ifaces_try_lock_onetime() -> Result<(), SystemError> {
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read_irqsave();
if guard.len() == 0 {
kwarn!("poll_ifaces: No net driver found!");
// 没有网卡,返回错误
return Err(SystemError::ENODEV);
}
let mut sockets = SOCKET_SET.try_lock()?;
let mut sockets = SOCKET_SET.try_lock_irqsave()?;
for (_, iface) in guard.iter() {
iface.poll(&mut sockets).ok();
}
@ -241,7 +242,7 @@ fn send_event(sockets: &smoltcp::iface::SocketSet) -> Result<(), SystemError> {
fn wakeup_epoll(handle: SocketHandle, events: u32) -> Result<(), SystemError> {
let mut handle_guard = HANDLE_MAP.write_irqsave();
let handle_item = handle_guard.get_mut(&handle).unwrap();
let mut epitems_guard = handle_item.epitems.try_lock()?;
let mut epitems_guard = handle_item.epitems.try_lock_irqsave()?;
// 从events拿到epoll相关事件
let pollflags = EPollEventType::from_bits_truncate(events);
@ -249,9 +250,9 @@ fn wakeup_epoll(handle: SocketHandle, events: u32) -> Result<(), SystemError> {
// 一次只取一个,因为一次也只有一个进程能拿到对应文件的🔓
if let Some(epitem) = epitems_guard.pop_front() {
let epoll = epitem.epoll().upgrade().unwrap();
let mut epoll_guard = epoll.try_lock()?;
let mut epoll_guard = epoll.try_lock_irqsave()?;
let binding = epitem.clone();
let event_guard = binding.event().read();
let event_guard = binding.event().read_irqsave();
let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
// 检查事件合理性以及是否有感兴趣的事件

View File

@ -99,7 +99,7 @@ impl SocketHandleItem {
}
pub fn shutdown_type_writer(&mut self) -> RwLockWriteGuard<ShutdownType> {
self.shutdown_type.write()
self.shutdown_type.write_irqsave()
}
pub fn add_epoll(&mut self, epitem: Arc<EPollItem>) {
@ -238,7 +238,7 @@ impl Clone for GlobalSocketHandle {
impl Drop for GlobalSocketHandle {
fn drop(&mut self) {
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
socket_set_guard.remove(self.0); // 删除的时候会发送一条FINISH的信息
drop(socket_set_guard);
poll_ifaces();
@ -353,7 +353,7 @@ impl RawSocket {
// 把socket添加到socket集合中并得到socket的句柄
let handle: Arc<GlobalSocketHandle> =
GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
GlobalSocketHandle::new(SOCKET_SET.lock_irqsave().add(socket));
let metadata = SocketMetadata::new(
SocketType::RawSocket,
@ -376,7 +376,7 @@ impl Socket for RawSocket {
poll_ifaces();
loop {
// 如何优化这里?
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
match socket.recv_slice(buf) {
@ -409,7 +409,7 @@ impl Socket for RawSocket {
fn write(&self, buf: &[u8], to: Option<super::Endpoint>) -> Result<usize, SystemError> {
// 如果用户发送的数据包包含IP头则直接发送
if self.header_included {
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
match socket.send_slice(buf) {
Ok(_len) => {
@ -423,12 +423,12 @@ impl Socket for RawSocket {
// 如果用户发送的数据包不包含IP头则需要自己构造IP头
if let Some(Endpoint::Ip(Some(endpoint))) = to {
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
let socket: &mut raw::Socket =
socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
// 暴力解决方案只考虑0号网卡。 TODO考虑多网卡的情况
let iface = NET_DRIVERS.read().get(&0).unwrap().clone();
let iface = NET_DRIVERS.read_irqsave().get(&0).unwrap().clone();
// 构造IP头
let ipv4_src_addr: Option<smoltcp::wire::Ipv4Address> =
@ -535,7 +535,7 @@ impl UdpSocket {
// 把socket添加到socket集合中并得到socket的句柄
let handle: Arc<GlobalSocketHandle> =
GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
GlobalSocketHandle::new(SOCKET_SET.lock_irqsave().add(socket));
let metadata = SocketMetadata::new(
SocketType::UdpSocket,
@ -579,7 +579,7 @@ impl Socket for UdpSocket {
loop {
// kdebug!("Wait22 to Read");
poll_ifaces();
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
let socket = socket_set_guard.get_mut::<udp::Socket>(self.handle.0);
// kdebug!("Wait to Read");
@ -616,7 +616,7 @@ impl Socket for UdpSocket {
};
// kdebug!("udp write: remote = {:?}", remote_endpoint);
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
let socket = socket_set_guard.get_mut::<udp::Socket>(self.handle.0);
// kdebug!("is open()={}", socket.is_open());
// kdebug!("socket endpoint={:?}", socket.endpoint());
@ -660,14 +660,14 @@ impl Socket for UdpSocket {
}
fn bind(&mut self, endpoint: Endpoint) -> Result<(), SystemError> {
let mut sockets = SOCKET_SET.lock();
let mut sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get_mut::<udp::Socket>(self.handle.0);
// kdebug!("UDP Bind to {:?}", endpoint);
return self.do_bind(socket, endpoint);
}
fn poll(&self) -> EPollEventType {
let sockets = SOCKET_SET.lock();
let sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get::<udp::Socket>(self.handle.0);
return SocketPollMethod::udp_poll(
@ -708,7 +708,7 @@ impl Socket for UdpSocket {
}
fn endpoint(&self) -> Option<Endpoint> {
let sockets = SOCKET_SET.lock();
let sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get::<udp::Socket>(self.handle.0);
let listen_endpoint = socket.endpoint();
@ -773,7 +773,7 @@ impl TcpSocket {
// 把socket添加到socket集合中并得到socket的句柄
let handle: Arc<GlobalSocketHandle> =
GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
GlobalSocketHandle::new(SOCKET_SET.lock_irqsave().add(socket));
let metadata = SocketMetadata::new(
SocketType::TcpSocket,
@ -833,7 +833,7 @@ impl Socket for TcpSocket {
loop {
poll_ifaces();
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
// 如果socket已经关闭返回错误
@ -898,7 +898,7 @@ impl Socket for TcpSocket {
{
return Err(SystemError::ENOTCONN);
}
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
if socket.is_open() {
@ -923,7 +923,7 @@ impl Socket for TcpSocket {
}
fn poll(&self) -> EPollEventType {
let mut socket_set_guard = SOCKET_SET.lock();
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
return SocketPollMethod::tcp_poll(
@ -937,7 +937,7 @@ impl Socket for TcpSocket {
}
fn connect(&mut self, endpoint: Endpoint) -> Result<(), SystemError> {
let mut sockets = SOCKET_SET.lock();
let mut sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
if let Endpoint::Ip(Some(ip)) = endpoint {
@ -946,7 +946,7 @@ impl Socket for TcpSocket {
PORT_MANAGER.bind_port(self.metadata.socket_type, temp_port, self.handle.clone())?;
// kdebug!("temp_port: {}", temp_port);
let iface: Arc<dyn NetDriver> = NET_DRIVERS.write().get(&0).unwrap().clone();
let iface: Arc<dyn NetDriver> = NET_DRIVERS.write_irqsave().get(&0).unwrap().clone();
let mut inner_iface = iface.inner_iface().lock();
// kdebug!("to connect: {ip:?}");
@ -958,7 +958,7 @@ impl Socket for TcpSocket {
drop(sockets);
loop {
poll_ifaces();
let mut sockets = SOCKET_SET.lock();
let mut sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
match socket.state() {
@ -1001,7 +1001,7 @@ impl Socket for TcpSocket {
}
let local_endpoint = self.local_endpoint.ok_or(SystemError::EINVAL)?;
let mut sockets = SOCKET_SET.lock();
let mut sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
if socket.is_listening() {
@ -1044,7 +1044,7 @@ impl Socket for TcpSocket {
// kdebug!("tcp accept: poll_ifaces()");
poll_ifaces();
let mut sockets = SOCKET_SET.lock();
let mut sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
@ -1126,7 +1126,7 @@ impl Socket for TcpSocket {
self.local_endpoint.clone().map(|x| Endpoint::Ip(Some(x)));
if result.is_none() {
let sockets = SOCKET_SET.lock();
let sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get::<tcp::Socket>(self.handle.0);
if let Some(ep) = socket.local_endpoint() {
result = Some(Endpoint::Ip(Some(ep)));
@ -1136,7 +1136,7 @@ impl Socket for TcpSocket {
}
fn peer_endpoint(&self) -> Option<Endpoint> {
let sockets = SOCKET_SET.lock();
let sockets = SOCKET_SET.lock_irqsave();
let socket = sockets.get::<tcp::Socket>(self.handle.0);
return socket.remote_endpoint().map(|x| Endpoint::Ip(Some(x)));
}

View File

@ -154,8 +154,9 @@ fn do_wait(kwo: &mut KernelWaitOption) -> Result<usize, SystemError> {
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
for pid in rd_childen.iter() {
let pcb = ProcessManager::find(*pid).ok_or(SystemError::ECHILD)?;
if pcb.sched_info().state().is_exited() {
kwo.ret_status = pcb.sched_info().state().exit_code().unwrap() as i32;
let state = pcb.sched_info().inner_lock_read_irqsave().state();
if state.is_exited() {
kwo.ret_status = state.exit_code().unwrap() as i32;
drop(pcb);
unsafe { ProcessManager::release(pid.clone()) };
return Ok(pid.clone().into());
@ -179,7 +180,7 @@ fn do_waitpid(
child_pcb: Arc<ProcessControlBlock>,
kwo: &mut KernelWaitOption,
) -> Option<Result<usize, SystemError>> {
let state = child_pcb.sched_info().state();
let state = child_pcb.sched_info().inner_lock_read_irqsave().state();
// 获取退出码
match state {
ProcessState::Runnable => {

View File

@ -159,6 +159,7 @@ impl ProcessManager {
let new_kstack: KernelStack = KernelStack::new()?;
let name = current_pcb.basic().name().to_string();
let pcb = ProcessControlBlock::new(name, new_kstack);
let mut args = KernelCloneArgs::new();
@ -166,7 +167,6 @@ impl ProcessManager {
args.exit_signal = Signal::SIGCHLD;
Self::copy_process(&current_pcb, &pcb, args, current_trapframe)?;
ProcessManager::add_pcb(pcb.clone());
// 向procfs注册进程
@ -232,7 +232,7 @@ impl ProcessManager {
unsafe { new_pcb.basic_mut().set_user_vm(Some(old_address_space)) };
return Ok(());
}
let new_address_space = old_address_space.write().try_clone().unwrap_or_else(|e| {
let new_address_space = old_address_space.write_irqsave().try_clone().unwrap_or_else(|e| {
panic!(
"copy_mm: Failed to clone address space of current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
current_pcb.pid(), new_pcb.pid(), e
@ -242,6 +242,7 @@ impl ProcessManager {
return Ok(());
}
#[inline(never)]
fn copy_files(
clone_flags: &CloneFlags,
current_pcb: &Arc<ProcessControlBlock>,
@ -274,7 +275,8 @@ impl ProcessManager {
}
if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
(*new_pcb.sig_struct()).handlers = current_pcb.sig_struct().handlers.clone();
(*new_pcb.sig_struct_irqsave()).handlers =
current_pcb.sig_struct_irqsave().handlers.clone();
}
return Ok(());
}
@ -288,8 +290,8 @@ impl ProcessManager {
/// ## 参数
///
/// - clone_flags 标志位
/// - des_pcb 目标pcb
/// - src_pcb 拷贝源pcb
/// - current_pcb 拷贝源pcb
/// - pcb 目标pcb
///
/// ## return
/// - 发生错误时返回Err(SystemError)
@ -350,7 +352,7 @@ impl ProcessManager {
// 克隆架构相关
let guard = current_pcb.arch_info_irqsave();
pcb.arch_info().clone_from(&guard);
unsafe { pcb.arch_info().clone_from(&guard) };
drop(guard);
// 为内核线程设置WorkerPrivate

View File

@ -291,7 +291,6 @@ impl KernelThreadMechanism {
CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
)
.expect("Failed to create kthread daemon");
let pcb = ProcessManager::find(kthreadd_pid).unwrap();
ProcessManager::wakeup(&pcb).expect("Failed to wakeup kthread daemon");
unsafe {
@ -379,7 +378,7 @@ impl KernelThreadMechanism {
// 忙等目标内核线程退出
// todo: 使用completion机制优化这里
loop {
if let ProcessState::Exited(code) = pcb.sched_info().state() {
if let ProcessState::Exited(code) = pcb.sched_info().inner_lock_read_irqsave().state() {
return Ok(code);
}
spin_loop();

View File

@ -112,7 +112,7 @@ impl ProcessManager {
compiler_fence(Ordering::SeqCst);
};
ALL_PROCESS.lock().replace(HashMap::new());
ALL_PROCESS.lock_irqsave().replace(HashMap::new());
Self::arch_init();
kdebug!("process arch init done.");
Self::init_idle();
@ -164,7 +164,7 @@ impl ProcessManager {
///
/// 如果找到了对应的进程那么返回该进程的pcb否则返回None
pub fn find(pid: Pid) -> Option<Arc<ProcessControlBlock>> {
return ALL_PROCESS.lock().as_ref()?.get(&pid).cloned();
return ALL_PROCESS.lock_irqsave().as_ref()?.get(&pid).cloned();
}
/// 向系统中添加一个进程的pcb
@ -178,7 +178,7 @@ impl ProcessManager {
/// 无
pub fn add_pcb(pcb: Arc<ProcessControlBlock>) {
ALL_PROCESS
.lock()
.lock_irqsave()
.as_mut()
.unwrap()
.insert(pcb.pid(), pcb.clone());
@ -187,9 +187,9 @@ impl ProcessManager {
/// 唤醒一个进程
pub fn wakeup(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> {
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
let state = pcb.sched_info().state();
let state = pcb.sched_info().inner_lock_read_irqsave().state();
if state.is_blocked() {
let mut writer: RwLockWriteGuard<'_, ProcessSchedulerInfo> = pcb.sched_info_mut();
let mut writer = pcb.sched_info().inner_lock_write_irqsave();
let state = writer.state();
if state.is_blocked() {
writer.set_state(ProcessState::Runnable);
@ -213,9 +213,9 @@ impl ProcessManager {
/// 唤醒暂停的进程
pub fn wakeup_stop(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> {
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
let state = pcb.sched_info().state();
let state = pcb.sched_info().inner_lock_read_irqsave().state();
if let ProcessState::Stopped = state {
let mut writer = pcb.sched_info_mut();
let mut writer = pcb.sched_info().inner_lock_write_irqsave();
let state = writer.state();
if let ProcessState::Stopped = state {
writer.set_state(ProcessState::Runnable);
@ -251,7 +251,7 @@ impl ProcessManager {
);
let pcb = ProcessManager::current_pcb();
let mut writer = pcb.sched_info_mut_irqsave();
let mut writer = pcb.sched_info().inner_lock_write_irqsave();
if !matches!(writer.state(), ProcessState::Exited(_)) {
writer.set_state(ProcessState::Blocked(interruptable));
pcb.flags().insert(ProcessFlags::NEED_SCHEDULE);
@ -276,7 +276,7 @@ impl ProcessManager {
);
let pcb = ProcessManager::current_pcb();
let mut writer = pcb.sched_info_mut_irqsave();
let mut writer = pcb.sched_info().inner_lock_write_irqsave();
if !matches!(writer.state(), ProcessState::Exited(_)) {
writer.set_state(ProcessState::Stopped);
pcb.flags().insert(ProcessFlags::NEED_SCHEDULE);
@ -321,10 +321,10 @@ impl ProcessManager {
/// - `exit_code` : 进程的退出码
pub fn exit(exit_code: usize) -> ! {
// 关中断
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
unsafe { CurrentIrqArch::interrupt_disable() };
let pcb = ProcessManager::current_pcb();
pcb.sched_info
.write()
.inner_lock_write_irqsave()
.set_state(ProcessState::Exited(exit_code));
pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true)));
@ -350,7 +350,7 @@ impl ProcessManager {
unsafe { pcb.basic_mut().set_user_vm(None) };
drop(pcb);
ProcessManager::exit_notify();
drop(irq_guard);
unsafe { CurrentIrqArch::interrupt_enable() };
sched();
loop {}
@ -373,7 +373,7 @@ impl ProcessManager {
// panic!()
// }
ALL_PROCESS.lock().as_mut().unwrap().remove(&pid);
ALL_PROCESS.lock_irqsave().as_mut().unwrap().remove(&pid);
}
}
@ -544,7 +544,7 @@ pub struct ProcessControlBlock {
syscall_stack: RwLock<KernelStack>,
/// 与调度相关的信息
sched_info: RwLock<ProcessSchedulerInfo>,
sched_info: ProcessSchedulerInfo,
/// 与处理器架构相关的信息
arch_info: SpinLock<ArchPCBInfo>,
/// 与信号处理相关的信息(似乎可以是无锁的)
@ -592,6 +592,7 @@ impl ProcessControlBlock {
return Self::do_create_pcb(name, kstack, true);
}
#[inline(never)]
fn do_create_pcb(name: String, kstack: KernelStack, is_idle: bool) -> Arc<Self> {
let (pid, ppid, cwd) = if is_idle {
(Pid(0), Pid(0), "/".to_string())
@ -624,7 +625,7 @@ impl ProcessControlBlock {
sched_info,
arch_info,
sig_info: RwLock::new(ProcessSignalInfo::default()),
sig_struct: SpinLock::new(SignalStruct::default()),
sig_struct: SpinLock::new(SignalStruct::new()),
exit_signal: AtomicSignal::new(Signal::SIGCHLD),
parent_pcb: RwLock::new(ppcb.clone()),
real_parent_pcb: RwLock::new(ppcb),
@ -657,7 +658,7 @@ impl ProcessControlBlock {
// 将当前pcb加入父进程的子进程哈希表中
if pcb.pid() > Pid(1) {
if let Some(ppcb_arc) = pcb.parent_pcb.read().upgrade() {
let mut children = ppcb_arc.children.write();
let mut children = ppcb_arc.children.write_irqsave();
children.push(pcb.pid());
} else {
panic!("parent pcb is None");
@ -702,6 +703,8 @@ impl ProcessControlBlock {
return self.flags.get_mut();
}
/// 请注意,这个值能在中断上下文中读取,但不能被中断上下文修改
/// 否则会导致死锁
#[inline(always)]
pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> {
return self.basic.read();
@ -714,19 +717,28 @@ impl ProcessControlBlock {
#[inline(always)]
pub fn basic_mut(&self) -> RwLockWriteGuard<ProcessBasicInfo> {
return self.basic.write();
}
#[inline(always)]
pub fn arch_info(&self) -> SpinLockGuard<ArchPCBInfo> {
return self.arch_info.lock();
return self.basic.write_irqsave();
}
/// # 获取arch info的锁同时关闭中断
#[inline(always)]
pub fn arch_info_irqsave(&self) -> SpinLockGuard<ArchPCBInfo> {
return self.arch_info.lock_irqsave();
}
/// # 获取arch info的锁但是不关闭中断
///
/// 由于arch info在进程切换的时候会使用到
/// 因此在中断上下文外获取arch info 而不irqsave是不安全的.
///
/// 只能在以下情况下使用这个函数:
/// - 在中断上下文中中断已经禁用获取arch info的锁。
/// - 刚刚创建新的pcb
#[inline(always)]
pub unsafe fn arch_info(&self) -> SpinLockGuard<ArchPCBInfo> {
return self.arch_info.lock();
}
#[inline(always)]
pub fn kernel_stack(&self) -> RwLockReadGuard<KernelStack> {
return self.kernel_stack.read();
@ -739,48 +751,8 @@ impl ProcessControlBlock {
}
#[inline(always)]
pub fn sched_info(&self) -> RwLockReadGuard<ProcessSchedulerInfo> {
return self.sched_info.read();
}
#[inline(always)]
pub fn try_sched_info(&self, times: u8) -> Option<RwLockReadGuard<ProcessSchedulerInfo>> {
for _ in 0..times {
if let Some(r) = self.sched_info.try_read() {
return Some(r);
}
}
return None;
}
#[allow(dead_code)]
#[inline(always)]
pub fn sched_info_irqsave(&self) -> RwLockReadGuard<ProcessSchedulerInfo> {
return self.sched_info.read_irqsave();
}
#[inline(always)]
pub fn sched_info_try_upgradeable_irqsave(
&self,
times: u8,
) -> Option<RwLockUpgradableGuard<ProcessSchedulerInfo>> {
for _ in 0..times {
if let Some(r) = self.sched_info.try_upgradeable_read_irqsave() {
return Some(r);
}
}
return None;
}
#[inline(always)]
pub fn sched_info_mut(&self) -> RwLockWriteGuard<ProcessSchedulerInfo> {
return self.sched_info.write();
}
#[inline(always)]
pub fn sched_info_mut_irqsave(&self) -> RwLockWriteGuard<ProcessSchedulerInfo> {
return self.sched_info.write_irqsave();
pub fn sched_info(&self) -> &ProcessSchedulerInfo {
return &self.sched_info;
}
#[inline(always)]
@ -877,7 +849,7 @@ impl ProcessControlBlock {
}
pub fn sig_info_mut(&self) -> RwLockWriteGuard<ProcessSignalInfo> {
self.sig_info.write()
self.sig_info.write_irqsave()
}
pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> {
@ -904,7 +876,7 @@ impl ProcessControlBlock {
return None;
}
pub fn sig_struct_irq(&self) -> SpinLockGuard<SignalStruct> {
pub fn sig_struct_irqsave(&self) -> SpinLockGuard<SignalStruct> {
self.sig_struct.lock_irqsave()
}
}
@ -971,6 +943,7 @@ pub struct ProcessBasicInfo {
}
impl ProcessBasicInfo {
#[inline(never)]
pub fn new(
pgid: Pid,
ppid: Pid,
@ -1036,11 +1009,7 @@ pub struct ProcessSchedulerInfo {
/// 如果当前进程等待被迁移到另一个cpu核心上也就是flags中的PF_NEED_MIGRATE被置位
/// 该字段存储要被迁移到的目标处理器核心号
migrate_to: AtomicI32,
/// 当前进程的状态
state: ProcessState,
/// 进程的调度策略
sched_policy: SchedPolicy,
inner_locked: RwLock<InnerSchedInfo>,
/// 进程的调度优先级
priority: SchedPriority,
/// 当前进程的虚拟运行时间
@ -1049,21 +1018,46 @@ pub struct ProcessSchedulerInfo {
rt_time_slice: AtomicIsize,
}
#[derive(Debug)]
pub struct InnerSchedInfo {
/// 当前进程的状态
state: ProcessState,
/// 进程的调度策略
sched_policy: SchedPolicy,
}
impl InnerSchedInfo {
pub fn state(&self) -> ProcessState {
return self.state;
}
pub fn set_state(&mut self, state: ProcessState) {
self.state = state;
}
pub fn policy(&self) -> SchedPolicy {
return self.sched_policy;
}
}
impl ProcessSchedulerInfo {
pub fn new(on_cpu: Option<u32>) -> RwLock<Self> {
#[inline(never)]
pub fn new(on_cpu: Option<u32>) -> Self {
let cpu_id = match on_cpu {
Some(cpu_id) => cpu_id as i32,
None => -1,
};
return RwLock::new(Self {
return Self {
on_cpu: AtomicI32::new(cpu_id),
migrate_to: AtomicI32::new(-1),
state: ProcessState::Blocked(false),
sched_policy: SchedPolicy::CFS,
inner_locked: RwLock::new(InnerSchedInfo {
state: ProcessState::Blocked(false),
sched_policy: SchedPolicy::CFS,
}),
virtual_runtime: AtomicIsize::new(0),
rt_time_slice: AtomicIsize::new(0),
priority: SchedPriority::new(100).unwrap(),
});
};
}
pub fn on_cpu(&self) -> Option<u32> {
@ -1100,16 +1094,38 @@ impl ProcessSchedulerInfo {
}
}
pub fn state(&self) -> ProcessState {
return self.state;
pub fn inner_lock_write_irqsave(&self) -> RwLockWriteGuard<InnerSchedInfo> {
return self.inner_locked.write_irqsave();
}
pub fn set_state(&mut self, state: ProcessState) {
self.state = state;
pub fn inner_lock_read_irqsave(&self) -> RwLockReadGuard<InnerSchedInfo> {
return self.inner_locked.read_irqsave();
}
pub fn policy(&self) -> SchedPolicy {
return self.sched_policy;
pub fn inner_lock_try_read_irqsave(
&self,
times: u8,
) -> Option<RwLockReadGuard<InnerSchedInfo>> {
for _ in 0..times {
if let Some(r) = self.inner_locked.try_read_irqsave() {
return Some(r);
}
}
return None;
}
pub fn inner_lock_try_upgradable_read_irqsave(
&self,
times: u8,
) -> Option<RwLockUpgradableGuard<InnerSchedInfo>> {
for _ in 0..times {
if let Some(r) = self.inner_locked.try_upgradeable_read_irqsave() {
return Some(r);
}
}
return None;
}
pub fn virtual_runtime(&self) -> isize {

View File

@ -9,7 +9,6 @@ use crate::{
kBUG,
libs::{
rbtree::RBTree,
rwlock::RwLockReadGuard,
spinlock::{SpinLock, SpinLockGuard},
},
process::{
@ -150,16 +149,13 @@ impl SchedulerCFS {
}
/// @brief 时钟中断到来时由sched的core模块中的函数调用本函数更新CFS进程的可执行时间
pub fn timer_update_jiffies(
&mut self,
sched_info_guard: &RwLockReadGuard<'_, ProcessSchedulerInfo>,
) {
pub fn timer_update_jiffies(&mut self, sched_info: &ProcessSchedulerInfo) {
let current_cpu_queue: &mut CFSQueue = self.cpu_queue[smp_get_processor_id() as usize];
// todo: 引入调度周期以及所有进程的优先权进行计算,然后设置进程的可执行时间
let mut queue = None;
for _ in 0..10 {
if let Ok(q) = current_cpu_queue.locked_queue.try_lock() {
if let Ok(q) = current_cpu_queue.locked_queue.try_lock_irqsave() {
queue = Some(q);
break;
}
@ -179,13 +175,13 @@ impl SchedulerCFS {
drop(queue);
// 更新当前进程的虚拟运行时间
sched_info_guard.increase_virtual_runtime(1);
sched_info.increase_virtual_runtime(1);
}
/// @brief 将进程加入cpu的cfs调度队列并且重设其虚拟运行时间为当前队列的最小值
pub fn enqueue_reset_vruntime(&mut self, pcb: Arc<ProcessControlBlock>) {
let cpu_queue = &mut self.cpu_queue[pcb.sched_info().on_cpu().unwrap() as usize];
let queue = cpu_queue.locked_queue.lock();
let queue = cpu_queue.locked_queue.lock_irqsave();
if queue.len() > 0 {
pcb.sched_info()
.set_virtual_runtime(CFSQueue::min_vruntime(&queue).unwrap_or(0) as isize)
@ -202,7 +198,7 @@ impl SchedulerCFS {
}
/// 获取某个cpu的运行队列中的进程数
pub fn get_cfs_queue_len(&mut self, cpu_id: u32) -> usize {
let queue = self.cpu_queue[cpu_id as usize].locked_queue.lock();
let queue = self.cpu_queue[cpu_id as usize].locked_queue.lock_irqsave();
return CFSQueue::get_cfs_queue_size(&queue);
}
}
@ -225,13 +221,17 @@ impl Scheduler for SchedulerCFS {
compiler_fence(core::sync::atomic::Ordering::SeqCst);
// 如果当前不是running态或者当前进程的虚拟运行时间大于等于下一个进程的那就需要切换。
if (ProcessManager::current_pcb().sched_info().state() != ProcessState::Runnable)
let state = ProcessManager::current_pcb()
.sched_info()
.inner_lock_read_irqsave()
.state();
if (state != ProcessState::Runnable)
|| (ProcessManager::current_pcb().sched_info().virtual_runtime()
>= proc.sched_info().virtual_runtime())
{
compiler_fence(core::sync::atomic::Ordering::SeqCst);
// 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
if ProcessManager::current_pcb().sched_info().state() == ProcessState::Runnable {
if state == ProcessState::Runnable {
sched_enqueue(ProcessManager::current_pcb(), false);
compiler_fence(core::sync::atomic::Ordering::SeqCst);
}

View File

@ -102,7 +102,9 @@ pub fn do_sched() -> Option<Arc<ProcessControlBlock>> {
// 当前进程持有锁,不切换,避免死锁
if ProcessManager::current_pcb().preempt_count() != 0 {
let binding = ProcessManager::current_pcb();
let guard = binding.sched_info_try_upgradeable_irqsave(5);
let guard = binding
.sched_info()
.inner_lock_try_upgradable_read_irqsave(5);
if unlikely(guard.is_none()) {
return None;
}
@ -154,7 +156,7 @@ pub fn do_sched() -> Option<Arc<ProcessControlBlock>> {
/// @param reset_time 是否重置虚拟运行时间
pub fn sched_enqueue(pcb: Arc<ProcessControlBlock>, mut reset_time: bool) {
compiler_fence(core::sync::atomic::Ordering::SeqCst);
if pcb.sched_info().state() != ProcessState::Runnable {
if pcb.sched_info().inner_lock_read_irqsave().state() != ProcessState::Runnable {
return;
}
let cfs_scheduler = __get_cfs_scheduler();
@ -173,7 +175,7 @@ pub fn sched_enqueue(pcb: Arc<ProcessControlBlock>, mut reset_time: bool) {
assert!(pcb.sched_info().on_cpu().is_some());
match pcb.sched_info().policy() {
match pcb.sched_info().inner_lock_read_irqsave().policy() {
SchedPolicy::CFS => {
if reset_time {
cfs_scheduler.enqueue_reset_vruntime(pcb.clone());
@ -199,17 +201,19 @@ pub extern "C" fn sched_init() {
/// @brief 当时钟中断到达时,更新时间片
/// 请注意,该函数只能被时钟中断处理程序调用
pub extern "C" fn sched_update_jiffies() {
#[inline(never)]
pub fn sched_update_jiffies() {
let binding = ProcessManager::current_pcb();
let guard = binding.try_sched_info(10);
let guard = binding.sched_info().inner_lock_try_read_irqsave(10);
if unlikely(guard.is_none()) {
return;
}
let guard = guard.unwrap();
let policy = guard.policy();
drop(guard);
match policy {
SchedPolicy::CFS => {
__get_cfs_scheduler().timer_update_jiffies(&guard);
__get_cfs_scheduler().timer_update_jiffies(binding.sched_info());
}
SchedPolicy::FIFO | SchedPolicy::RR => {
__get_rt_scheduler().timer_update_jiffies();

View File

@ -81,7 +81,7 @@ impl RTQueue {
queue.push_front(pcb);
}
pub fn get_rt_queue_size(&mut self) -> usize {
let queue = self.locked_queue.lock();
let queue = self.locked_queue.lock_irqsave();
return queue.len();
}
}
@ -176,7 +176,7 @@ impl Scheduler for SchedulerRT {
let proc: Arc<ProcessControlBlock> =
self.pick_next_task_rt(cpu_id).expect("No RT process found");
let priority = proc.sched_info().priority();
let policy = proc.sched_info().policy();
let policy = proc.sched_info().inner_lock_read_irqsave().policy();
match policy {
// 如果是fifo策略则可以一直占有cpu直到有优先级更高的任务就绪(即使优先级相同也不行)或者主动放弃(等待资源)
SchedPolicy::FIFO => {

View File

@ -100,7 +100,7 @@ impl Timekeeper {
///
/// * 'clock' - 指定的时钟实际类型。初始为ClocksourceJiffies
pub fn timekeeper_setup_internals(&self, clock: Arc<dyn Clocksource>) {
let mut timekeeper = self.0.write();
let mut timekeeper = self.0.write_irqsave();
// 更新clock
let mut clock_data = clock.clocksource_data();
clock_data.watchdog_last = clock.read();
@ -132,8 +132,9 @@ impl Timekeeper {
/// # 获取当前时钟源距离上次检测走过的纳秒数
#[allow(dead_code)]
pub fn tk_get_ns(&self) -> u64 {
let timekeeper = self.0.read();
let timekeeper = self.0.read_irqsave();
let clock = timekeeper.clock.clone().unwrap();
drop(timekeeper);
let clock_now = clock.read();
let clcok_data = clock.clocksource_data();
let clock_delta = clock_now.div(clcok_data.watchdog_last).data() & clcok_data.mask.bits();
@ -164,7 +165,7 @@ pub fn getnstimeofday() -> TimeSpec {
tv_sec: 0,
};
loop {
match timekeeper().0.try_read() {
match timekeeper().0.try_read_irqsave() {
None => continue,
Some(tk) => {
_xtime = tk.xtime;
@ -215,7 +216,7 @@ pub fn timekeeping_init() {
.expect("clocksource_default_clock enable failed");
timekeeper().timekeeper_setup_internals(clock);
// 暂时不支持其他架构平台对时间的设置 所以使用x86平台对应值初始化
let mut timekeeper = timekeeper().0.write();
let mut timekeeper = timekeeper().0.write_irqsave();
timekeeper.xtime.tv_nsec = ktime_get_real_ns();
// 初始化wall time到monotonic的时间
@ -236,7 +237,7 @@ pub fn timekeeping_init() {
}
/// # 使用当前时钟源增加wall time
pub fn update_wall_time() {
pub fn update_wall_time(delta_us: i64) {
// kdebug!("enter update_wall_time, stack_use = {:}",stack_use);
compiler_fence(Ordering::SeqCst);
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
@ -264,8 +265,7 @@ pub fn update_wall_time() {
// ================
compiler_fence(Ordering::SeqCst);
// !!! todo: 这里是硬编码了HPET的500us中断需要修改
__ADDED_USEC.fetch_add(500, Ordering::SeqCst);
__ADDED_USEC.fetch_add(delta_us, Ordering::SeqCst);
compiler_fence(Ordering::SeqCst);
let mut retry = 10;

View File

@ -18,7 +18,7 @@ use crate::{
InterruptArch,
},
kerror, kinfo,
libs::spinlock::SpinLock,
libs::spinlock::{SpinLock, SpinLockGuard},
process::{ProcessControlBlock, ProcessManager},
};
@ -57,7 +57,9 @@ impl TimerFunction for WakeUpHelper {
}
#[derive(Debug)]
pub struct Timer(SpinLock<InnerTimer>);
pub struct Timer {
inner: SpinLock<InnerTimer>,
}
impl Timer {
/// @brief 创建一个定时器单位ms
@ -68,22 +70,28 @@ impl Timer {
///
/// @return 定时器结构体
pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
let result: Arc<Timer> = Arc::new(Timer(SpinLock::new(InnerTimer {
expire_jiffies,
timer_func,
self_ref: Weak::default(),
triggered: false,
})));
let result: Arc<Timer> = Arc::new(Timer {
inner: SpinLock::new(InnerTimer {
expire_jiffies,
timer_func: Some(timer_func),
self_ref: Weak::default(),
triggered: false,
}),
});
result.0.lock().self_ref = Arc::downgrade(&result);
result.inner.lock().self_ref = Arc::downgrade(&result);
return result;
}
pub fn inner(&self) -> SpinLockGuard<InnerTimer> {
return self.inner.lock_irqsave();
}
/// @brief 将定时器插入到定时器链表中
pub fn activate(&self) {
let inner_guard = self.0.lock();
let mut timer_list = TIMER_LIST.lock();
let mut timer_list = TIMER_LIST.lock_irqsave();
let inner_guard = self.inner();
// 链表为空,则直接插入
if timer_list.is_empty() {
@ -99,7 +107,7 @@ impl Timer {
}
let mut split_pos: usize = 0;
for (pos, elt) in timer_list.iter().enumerate() {
if elt.0.lock().expire_jiffies > inner_guard.expire_jiffies {
if elt.inner().expire_jiffies > inner_guard.expire_jiffies {
split_pos = pos;
break;
}
@ -113,9 +121,11 @@ impl Timer {
#[inline]
fn run(&self) {
let mut timer = self.0.lock();
let mut timer = self.inner();
timer.triggered = true;
let r = timer.timer_func.run();
let func = timer.timer_func.take();
drop(timer);
let r = func.map(|mut f| f.run()).unwrap_or(Ok(()));
if unlikely(r.is_err()) {
kerror!(
"Failed to run timer function: {self:?} {:?}",
@ -126,14 +136,15 @@ impl Timer {
/// ## 判断定时器是否已经触发
pub fn timeout(&self) -> bool {
self.0.lock().triggered
self.inner().triggered
}
/// ## 取消定时器任务
pub fn cancel(&self) -> bool {
let this_arc = self.inner().self_ref.upgrade().unwrap();
TIMER_LIST
.lock()
.extract_if(|x| Arc::<Timer>::as_ptr(&x) == self as *const Timer)
.lock_irqsave()
.extract_if(|x| Arc::ptr_eq(&this_arc, x))
.for_each(|p| drop(p));
true
}
@ -145,7 +156,7 @@ pub struct InnerTimer {
/// 定时器结束时刻
pub expire_jiffies: u64,
/// 定时器需要执行的函数结构体
pub timer_func: Box<dyn TimerFunction>,
pub timer_func: Option<Box<dyn TimerFunction>>,
/// self_ref
self_ref: Weak<Timer>,
/// 判断该计时器是否触发
@ -187,7 +198,7 @@ impl SoftirqVec for DoTimerSoftirq {
// 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
// kdebug!("DoTimerSoftirq run");
let timer_list = TIMER_LIST.try_lock();
let timer_list = TIMER_LIST.try_lock_irqsave();
if timer_list.is_err() {
continue;
}
@ -201,7 +212,7 @@ impl SoftirqVec for DoTimerSoftirq {
// kdebug!("to lock timer_list_front");
let mut timer_list_front_guard = None;
for _ in 0..10 {
let x = timer_list_front.0.try_lock();
let x = timer_list_front.inner.try_lock_irqsave();
if x.is_err() {
continue;
}
@ -297,7 +308,7 @@ pub fn timer_get_first_expire() -> Result<u64, SystemError> {
return Ok(0);
} else {
// kdebug!("timer_list not empty");
return Ok(timer_list.front().unwrap().0.lock().expire_jiffies);
return Ok(timer_list.front().unwrap().inner().expire_jiffies);
}
}
// 加锁失败返回啥??
@ -310,10 +321,10 @@ pub fn timer_get_first_expire() -> Result<u64, SystemError> {
/// 更新系统时间片
///
/// todo: 这里的实现有问题貌似把HPET的500us当成了500个jiffies然后update_wall_time()里面也硬编码了这个500us
pub fn update_timer_jiffies(add_jiffies: u64) -> u64 {
pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 {
let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
compiler_fence(Ordering::SeqCst);
update_wall_time();
update_wall_time(time_us);
compiler_fence(Ordering::SeqCst);
return prev + add_jiffies;