修正由于init proc union导致的无法运行的问题 && 修正由于内核线程启动后默认sleep的行为导致init进程无法正常运行的bug (#381)

1. 修正由于init proc union导致的无法运行的问题
2. 修正由于内核线程启动后默认sleep的行为导致init进程无法正常运行的bug
This commit is contained in:
LoGin 2023-09-15 19:44:11 +08:00 committed by GitHub
parent 1496ba7b24
commit de71ec259c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 13 deletions

View File

@ -43,7 +43,7 @@ impl InterruptArch for X86_64InterruptArch {
unsafe {
asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags));
}
return rflags & (1 << 9) != 0;
return (rflags & (1 << 9)) != 0;
}
unsafe fn save_and_disable_irq() -> IrqFlagsGuard {

View File

@ -42,6 +42,19 @@ extern "C" {
fn ret_from_intr();
}
#[allow(dead_code)]
#[repr(align(32768))]
union InitProcUnion {
/// 用于存放idle进程的内核栈
idle_stack: [u8; 32768],
}
#[link_section = ".data.init_proc_union"]
#[no_mangle]
static BSP_IDLE_STACK_SPACE: InitProcUnion = InitProcUnion {
idle_stack: [0; 32768],
};
/// PCB中与架构相关的信息
#[derive(Debug, Clone)]
#[allow(dead_code)]
@ -321,6 +334,7 @@ impl ProcessManager {
);
// kdebug!("switch tss ok");
compiler_fence(Ordering::SeqCst);
// 正式切换上下文
switch_to_inner(prev_arch, next_arch);
}

View File

@ -481,13 +481,8 @@ m_ignore_int:
go_to_ignore_int:
.quad ignore_int_handler
ENTRY(head_stack_start)
.quad initial_proc_union + 32768
.align 32768
initial_proc_union:
.fill 32768, 1, 0
.quad BSP_IDLE_STACK_SPACE + 32768
//
.align 0x1000 //4k

View File

@ -112,6 +112,8 @@ pub struct KernelThreadCreateInfo {
/// 不安全的Arc引用计数当内核线程创建失败时需要减少这个计数
has_unsafe_arc_instance: AtomicBool,
self_ref: Weak<Self>,
/// 如果该值为true在进入bootstrap stage2之后就会进入睡眠状态
to_mark_sleep: AtomicBool,
}
#[atomic_enum]
@ -132,6 +134,7 @@ impl KernelThreadCreateInfo {
result_pcb: SpinLock::new(None),
has_unsafe_arc_instance: AtomicBool::new(false),
self_ref: Weak::new(),
to_mark_sleep: AtomicBool::new(true),
});
let tmp = result.clone();
unsafe {
@ -209,12 +212,35 @@ impl KernelThreadCreateInfo {
assert!(Arc::strong_count(&arc) > 0);
return arc;
}
/// 设置是否在进入bootstrap stage2之后就进入睡眠状态
///
/// ## 参数
///
/// - to_mark_sleep: 是否在进入bootstrap stage2之后就进入睡眠状态
///
/// ## 返回值
/// 如果已经创建完成返回EINVAL
pub fn set_to_mark_sleep(&self, to_mark_sleep: bool) -> Result<(), SystemError> {
let result_guard = self.result_pcb.lock();
if result_guard.is_some() {
// 已经创建完成,不需要设置
return Err(SystemError::EINVAL);
}
self.to_mark_sleep.store(to_mark_sleep, Ordering::SeqCst);
return Ok(());
}
pub fn to_mark_sleep(&self) -> bool {
self.to_mark_sleep.load(Ordering::SeqCst)
}
}
pub struct KernelThreadMechanism;
impl KernelThreadMechanism {
pub fn init_stage1() {
assert!(ProcessManager::current_pcb().pid() == Pid::new(0));
kinfo!("Initializing kernel thread mechanism stage1...");
// 初始化第一个内核线程
@ -229,7 +255,9 @@ impl KernelThreadMechanism {
.flags
.lock()
.insert(ProcessFlags::KTHREAD);
create_info
.set_to_mark_sleep(false)
.expect("Failed to set to_mark_sleep");
KernelThreadMechanism::__inner_create(
&create_info,
CloneFlags::CLONE_VM | CloneFlags::CLONE_SIGNAL,
@ -259,6 +287,7 @@ impl KernelThreadMechanism {
.expect("Failed to create kthread daemon");
let pcb = ProcessManager::find(kthreadd_pid).unwrap();
ProcessManager::wakeup(&pcb).expect("Failed to wakeup kthread daemon");
unsafe {
KTHREAD_DAEMON_PCB.replace(pcb);
}
@ -437,11 +466,16 @@ pub unsafe extern "C" fn kernel_thread_bootstrap_stage2(ptr: *const KernelThread
let closure: Box<KernelThreadClosure> = info.take_closure().unwrap();
info.set_create_ok(ProcessManager::current_pcb());
let to_mark_sleep = info.to_mark_sleep();
drop(info);
let irq_guard = CurrentIrqArch::save_and_disable_irq();
ProcessManager::mark_sleep(true).expect("Failed to mark sleep");
drop(irq_guard);
if to_mark_sleep {
// 进入睡眠状态
let irq_guard = CurrentIrqArch::save_and_disable_irq();
ProcessManager::mark_sleep(true).expect("Failed to mark sleep");
drop(irq_guard);
sched();
}
let mut retval = SystemError::EINTR.to_posix_errno();

View File

@ -160,6 +160,7 @@ impl ProcessManager {
/// 唤醒一个进程
pub fn wakeup(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> {
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
let state = pcb.sched_info().state();
if state.is_blocked() {
let mut writer = pcb.sched_info_mut();

View File

@ -3,6 +3,8 @@ use core::sync::atomic::compiler_fence;
use alloc::{boxed::Box, sync::Arc, vec::Vec};
use crate::{
arch::CurrentIrqArch,
exception::InterruptArch,
include::bindings::bindings::MAX_CPU_NUM,
kBUG,
libs::{
@ -190,6 +192,8 @@ impl Scheduler for SchedulerCFS {
/// @brief 在当前cpu上进行调度。
/// 请注意,进入该函数之前,需要关中断
fn sched(&mut self) -> Option<Arc<ProcessControlBlock>> {
assert!(CurrentIrqArch::is_irq_enabled() == false);
ProcessManager::current_pcb()
.flags()
.remove(ProcessFlags::NEED_SCHEDULE);

View File

@ -23,8 +23,13 @@ impl Syscall {
let pcb = do_sched();
if pcb.is_some() {
CPU_EXECUTING.set(smp_get_processor_id(), pcb.as_ref().unwrap().pid());
unsafe { ProcessManager::switch_process(ProcessManager::current_pcb(), pcb.unwrap()) };
let next_pcb = pcb.unwrap();
let current_pcb = ProcessManager::current_pcb();
if current_pcb.pid() != next_pcb.pid() {
CPU_EXECUTING.set(smp_get_processor_id(), next_pcb.pid());
unsafe { ProcessManager::switch_process(current_pcb, next_pcb) };
}
}
drop(irq_guard);
return Ok(0);