GnoCiYeH 2f6f547ae0
Patch fix sched (#419)
1.解决waitqueue sleep的时候,由于preempt count不为0,导致sched失败,从而导致该waitqueue下一次wakeup时,会把pcb多次加入调度队列的bug
2.修复socket inode 的read和write方法里面没有使用no_preempt的问题
3. 修复cpu0的内核栈由于脏数据导致new_idle的时候set pcb报错的问题

---------

Co-authored-by: longjin <longjin@DragonOS.org>
2023-11-04 21:35:25 +08:00

82 lines
2.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use core::{
intrinsics::unlikely,
sync::atomic::{AtomicBool, Ordering},
};
use alloc::{sync::Arc, vec::Vec};
use crate::{
mm::{percpu::PerCpu, VirtAddr, INITIAL_PROCESS_ADDRESS_SPACE},
process::KernelStack,
smp::core::smp_get_processor_id,
};
use super::{ProcessControlBlock, ProcessManager};
static mut __IDLE_PCB: Option<Vec<Arc<ProcessControlBlock>>> = None;
impl ProcessManager {
/// 初始化每个核的idle进程
pub fn init_idle() {
static INIT_IDLE: AtomicBool = AtomicBool::new(false);
if INIT_IDLE
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
.is_err()
{
panic!("Idle process already initialized");
}
assert!(
smp_get_processor_id() == 0,
"Idle process must be initialized on the first processor"
);
let mut v: Vec<Arc<ProcessControlBlock>> = Vec::with_capacity(PerCpu::MAX_CPU_NUM);
for i in 0..PerCpu::MAX_CPU_NUM {
let kstack = if unlikely(i == 0) {
let stack_ptr =
VirtAddr::new(Self::stack_ptr().data() & (!(KernelStack::ALIGN - 1)));
// 初始化bsp的idle进程
let mut ks = unsafe { KernelStack::from_existed(stack_ptr) }
.expect("Failed to create kernel stack struct for BSP.");
unsafe { ks.clear_pcb(true) };
ks
} else {
KernelStack::new().unwrap_or_else(|e| {
panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e)
})
};
let idle_pcb = ProcessControlBlock::new_idle(smp_get_processor_id(), kstack);
assert!(idle_pcb.basic().user_vm().is_none());
unsafe {
idle_pcb
.basic_mut()
.set_user_vm(Some(INITIAL_PROCESS_ADDRESS_SPACE()))
};
assert!(idle_pcb.sched_info().on_cpu().is_none());
idle_pcb.sched_info().set_on_cpu(Some(i as u32));
v.push(idle_pcb);
}
unsafe {
__IDLE_PCB = Some(v);
}
}
/// 获取当前的栈指针
///
/// 请注意该函数只是于辅助bsp核心的idle进程初始化
fn stack_ptr() -> VirtAddr {
#[cfg(target_arch = "x86_64")]
return VirtAddr::new(x86::current::registers::rsp() as usize);
}
/// 获取idle进程数组的引用
pub fn idle_pcb() -> &'static Vec<Arc<ProcessControlBlock>> {
unsafe { __IDLE_PCB.as_ref().unwrap() }
}
}