修正由于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 { unsafe {
asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags)); 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 { unsafe fn save_and_disable_irq() -> IrqFlagsGuard {

View File

@ -42,6 +42,19 @@ extern "C" {
fn ret_from_intr(); 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中与架构相关的信息 /// PCB中与架构相关的信息
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(dead_code)] #[allow(dead_code)]
@ -321,6 +334,7 @@ impl ProcessManager {
); );
// kdebug!("switch tss ok"); // kdebug!("switch tss ok");
compiler_fence(Ordering::SeqCst);
// 正式切换上下文 // 正式切换上下文
switch_to_inner(prev_arch, next_arch); switch_to_inner(prev_arch, next_arch);
} }

View File

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

View File

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

View File

@ -160,6 +160,7 @@ impl ProcessManager {
/// 唤醒一个进程 /// 唤醒一个进程
pub fn wakeup(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> { 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().state();
if state.is_blocked() { if state.is_blocked() {
let mut writer = pcb.sched_info_mut(); 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 alloc::{boxed::Box, sync::Arc, vec::Vec};
use crate::{ use crate::{
arch::CurrentIrqArch,
exception::InterruptArch,
include::bindings::bindings::MAX_CPU_NUM, include::bindings::bindings::MAX_CPU_NUM,
kBUG, kBUG,
libs::{ libs::{
@ -190,6 +192,8 @@ impl Scheduler for SchedulerCFS {
/// @brief 在当前cpu上进行调度。 /// @brief 在当前cpu上进行调度。
/// 请注意,进入该函数之前,需要关中断 /// 请注意,进入该函数之前,需要关中断
fn sched(&mut self) -> Option<Arc<ProcessControlBlock>> { fn sched(&mut self) -> Option<Arc<ProcessControlBlock>> {
assert!(CurrentIrqArch::is_irq_enabled() == false);
ProcessManager::current_pcb() ProcessManager::current_pcb()
.flags() .flags()
.remove(ProcessFlags::NEED_SCHEDULE); .remove(ProcessFlags::NEED_SCHEDULE);

View File

@ -23,8 +23,13 @@ impl Syscall {
let pcb = do_sched(); let pcb = do_sched();
if pcb.is_some() { if pcb.is_some() {
CPU_EXECUTING.set(smp_get_processor_id(), pcb.as_ref().unwrap().pid()); let next_pcb = pcb.unwrap();
unsafe { ProcessManager::switch_process(ProcessManager::current_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); drop(irq_guard);
return Ok(0); return Ok(0);