mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 22:36:48 +00:00
修正由于init proc union导致的无法运行的问题 && 修正由于内核线程启动后默认sleep的行为导致init进程无法正常运行的bug (#381)
1. 修正由于init proc union导致的无法运行的问题 2. 修正由于内核线程启动后默认sleep的行为导致init进程无法正常运行的bug
This commit is contained in:
parent
1496ba7b24
commit
de71ec259c
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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对齐
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user