From 49ee9cadbd72b7b0185afc200dcbf598192c3d7f Mon Sep 17 00:00:00 2001 From: ZhiyuanSue <2262387848@qq.com> Date: Thu, 12 Dec 2024 22:40:50 +0800 Subject: [PATCH] try to fix more bugs of convert --- kernel/src/arch/aarch64/exception.rs | 2 +- kernel/src/interfaces_impl/cspace.rs | 51 ++++++++++-- kernel/src/syscall/invocation/invoke_sched.rs | 2 +- kernel/src/syscall/invocation/invoke_tcb.rs | 4 +- kernel/src/syscall/mod.rs | 18 ++--- sel4_ipc/src/notification.rs | 77 ++++++++++++++++--- sel4_ipc/src/transfer.rs | 4 +- sel4_task/src/sched_context.rs | 6 +- sel4_task/src/scheduler.rs | 20 +++-- 9 files changed, 146 insertions(+), 38 deletions(-) diff --git a/kernel/src/arch/aarch64/exception.rs b/kernel/src/arch/aarch64/exception.rs index 79addbb..f555868 100644 --- a/kernel/src/arch/aarch64/exception.rs +++ b/kernel/src/arch/aarch64/exception.rs @@ -116,7 +116,7 @@ pub fn handleVMFaultEvent(vm_faultType: usize) -> exception_t { if status != exception_t::EXCEPTION_NONE { handle_fault(get_currenct_thread()); } - // sel4_common::println!("handle vm fault event"); + // sel4_common::println!("handle vm fault event"); schedule(); activateThread(); exception_t::EXCEPTION_NONE diff --git a/kernel/src/interfaces_impl/cspace.rs b/kernel/src/interfaces_impl/cspace.rs index 30d0461..a325f05 100644 --- a/kernel/src/interfaces_impl/cspace.rs +++ b/kernel/src/interfaces_impl/cspace.rs @@ -1,3 +1,5 @@ +use core::usize; + use crate::config::CONFIG_MAX_NUM_WORK_UNITS_PER_PREEMPTION; // use crate::ffi::tcbDebugRemove; use crate::interrupt::{deletingIRQHandler, isIRQPending, setIRQState, IRQState}; @@ -6,12 +8,16 @@ use crate::syscall::safe_unbind_notification; use sel4_common::sel4_config::{tcbCNodeEntries, tcbCTable, tcbVTable}; use sel4_common::structures::exception_t; use sel4_common::structures_gen::{cap, cap_null_cap, cap_tag, endpoint, notification}; -use sel4_common::utils::convert_to_mut_type_ref; +use sel4_common::utils::{ + convert_to_mut_type_ref, convert_to_option_mut_type_ref, convert_to_option_type_ref, +}; use sel4_cspace::capability::cap_func; use sel4_cspace::compatibility::{ZombieType_ZombieTCB, Zombie_new}; use sel4_cspace::interface::finaliseCap_ret; use sel4_ipc::{endpoint_func, notification_func, Transfer}; -use sel4_task::{get_currenct_thread, ksWorkUnitsCompleted, tcb_t}; +use sel4_task::reply::reply_t; +use sel4_task::sched_context::sched_context_t; +use sel4_task::{get_currenct_thread, ksWorkUnitsCompleted, tcb_t, ThreadState}; #[cfg(target_arch = "riscv64")] use sel4_vspace::find_vspace_for_asid; #[cfg(target_arch = "aarch64")] @@ -190,6 +196,9 @@ pub fn finaliseCap(capability: &cap, _final: bool, _exposed: bool) -> finaliseCa let ntfn = convert_to_mut_type_ref::( cap::cap_notification_cap(capability).get_capNtfnPtr() as usize, ); + #[cfg(feature = "KERNEL_MCS")] + convert_to_mut_type_ref::(ntfn.get_ntfnSchedContext() as usize) + .schedContext_unbindNtfn(); ntfn.safe_unbind_tcb(); ntfn.cacncel_all_signal(); } @@ -198,9 +207,31 @@ pub fn finaliseCap(capability: &cap, _final: bool, _exposed: bool) -> finaliseCa return fc_ret; } cap_tag::cap_reply_cap => { - // TODO: MCS - } - cap_tag::cap_null_cap | cap_tag::cap_domain_cap => { + // TODO: MCS + if _final { + if let Some(reply) = convert_to_option_mut_type_ref::( + cap::cap_reply_cap(capability).get_capReplyPtr() as usize, + ) { + if reply.replyTCB != 0 { + match convert_to_mut_type_ref::(reply.replyTCB).get_state() { + ThreadState::ThreadStateBlockedOnReply => { + reply.remove(convert_to_mut_type_ref::(reply.replyTCB)); + } + ThreadState::ThreadStateBlockedOnReceive => { + convert_to_mut_type_ref::(reply.replyTCB).cancel_ipc(); + } + _ => { + panic!("invalid tcb state"); + } + } + } + } + } + fc_ret.remainder = cap_null_cap::new().unsplay(); + fc_ret.cleanupInfo = cap_null_cap::new().unsplay(); + return fc_ret; + } + cap_tag::cap_null_cap | cap_tag::cap_domain_cap => { fc_ret.remainder = cap_null_cap::new().unsplay(); fc_ret.cleanupInfo = cap_null_cap::new().unsplay(); return fc_ret; @@ -239,6 +270,16 @@ pub fn finaliseCap(capability: &cap, _final: bool, _exposed: bool) -> finaliseCa }; let cte_ptr = tcb.get_cspace_mut_ref(tcbCTable); safe_unbind_notification(tcb); + #[cfg(feature = "KERNEL_MCS")] + if let Some(sc) = + convert_to_option_mut_type_ref::(tcb.tcbSchedContext) + { + sc.schedContext_unbindTCB(tcb); + if sc.scYieldFrom != 0 { + convert_to_mut_type_ref::(sc.scYieldFrom) + .schedContext_completeYieldTo(); + } + } tcb.cancel_ipc(); tcb.suspend(); // #[cfg(feature="DEBUG_BUILD")] diff --git a/kernel/src/syscall/invocation/invoke_sched.rs b/kernel/src/syscall/invocation/invoke_sched.rs index 10ab34c..f60b224 100644 --- a/kernel/src/syscall/invocation/invoke_sched.rs +++ b/kernel/src/syscall/invocation/invoke_sched.rs @@ -69,7 +69,7 @@ pub fn invokeSchedControl_ConfigureFlags( convert_to_mut_type_ref::(target.scTcb).Release_Remove(); convert_to_mut_type_ref::(target.scTcb).sched_dequeue(); /* bill the current consumed amount before adjusting the params */ - if unsafe { ksCurSC } == target.get_ptr() { + if target.is_current() { assert!(checkBudget()); commitTime(); } diff --git a/kernel/src/syscall/invocation/invoke_tcb.rs b/kernel/src/syscall/invocation/invoke_tcb.rs index d68ef8b..3404f33 100644 --- a/kernel/src/syscall/invocation/invoke_tcb.rs +++ b/kernel/src/syscall/invocation/invoke_tcb.rs @@ -151,7 +151,9 @@ pub fn invoke_tcb_suspend(thread: &mut tcb_t) -> exception_t { #[inline] pub fn invoke_tcb_resume(thread: &mut tcb_t) -> exception_t { // cancel_ipc(thread); - thread.cancel_ipc(); + if thread.is_stopped() { + thread.cancel_ipc(); + } thread.restart(); exception_t::EXCEPTION_NONE } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 3aa9976..9dc4f71 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -71,12 +71,12 @@ use sel4_common::structures_gen::{ }; use sel4_common::utils::{convert_to_mut_type_ref, ptr_to_mut}; use sel4_ipc::{endpoint_func, notification_func, Transfer}; -#[cfg(feature = "KERNEL_MCS")] -use sel4_task::{mcs_preemption_point, chargeBudget, ksConsumed, ksCurSC}; use sel4_task::{ - activateThread, get_currenct_thread, rescheduleRequired, - schedule, set_thread_state, tcb_t, ThreadState, + activateThread, get_currenct_thread, rescheduleRequired, schedule, set_thread_state, tcb_t, + ThreadState, }; +#[cfg(feature = "KERNEL_MCS")] +use sel4_task::{chargeBudget, get_current_sc, ksConsumed, ksCurSC, mcs_preemption_point}; pub use utils::*; use crate::arch::restore_user_context; @@ -539,13 +539,9 @@ fn handle_yield() { #[cfg(feature = "KERNEL_MCS")] { unsafe { - let consumed = - convert_to_mut_type_ref::(ksCurSC).scConsumed + ksConsumed; - chargeBudget( - (*convert_to_mut_type_ref::(ksCurSC).refill_head()).rAmount, - false, - ); - convert_to_mut_type_ref::(ksCurSC).scConsumed = consumed; + let consumed = get_current_sc().scConsumed + ksConsumed; + chargeBudget((*get_current_sc().refill_head()).rAmount, false); + get_current_sc().scConsumed = consumed; } } #[cfg(not(feature = "KERNEL_MCS"))] diff --git a/sel4_ipc/src/notification.rs b/sel4_ipc/src/notification.rs index 27239a9..63886cc 100644 --- a/sel4_ipc/src/notification.rs +++ b/sel4_ipc/src/notification.rs @@ -1,7 +1,9 @@ use crate::transfer::Transfer; use sel4_common::arch::ArchReg; -use sel4_common::structures_gen::notification; +use sel4_common::structures_gen::{notification, notification_t}; use sel4_common::utils::{convert_to_mut_type_ref, convert_to_option_mut_type_ref}; +#[cfg(feature = "KERNEL_MCS")] +use sel4_task::sched_context::sched_context_t; use sel4_task::{ possible_switch_to, rescheduleRequired, set_thread_state, tcb_queue_t, tcb_t, ThreadState, }; @@ -141,7 +143,31 @@ impl notification_func for notification { tcb.cancel_ipc(); set_thread_state(tcb, ThreadState::ThreadStateRunning); tcb.tcbArch.set_register(ArchReg::Badge, badge); + #[cfg(feature = "KERNEL_MCS")] + { + maybeDonateSchedContext(tcb, self); + if tcb.is_schedulable() { + possible_switch_to(tcb); + } + } + #[cfg(not(feature = "KERNEL_MCS"))] possible_switch_to(tcb); + #[cfg(feature = "KERNEL_MCS")] + if let Some(tcbsc) = + convert_to_option_mut_type_ref::(tcb.tcbSchedContext) + { + if tcbsc.sc_active() { + let sc = convert_to_mut_type_ref::( + self.get_ntfnSchedContext() as usize, + ); + if tcbsc.get_ptr() == sc.get_ptr() + && sc.sc_sporadic() + && !tcbsc.is_current() + { + tcbsc.refill_unblock_check(); + } + } + } } else { self.active(badge); } @@ -159,7 +185,26 @@ impl notification_func for notification { } set_thread_state(dest, ThreadState::ThreadStateRunning); dest.tcbArch.set_register(ArchReg::Badge, badge); + #[cfg(feature = "KERNEL_MCS")] + { + maybeDonateSchedContext(dest, self); + if dest.is_schedulable() { + possible_switch_to(dest); + } + } + #[cfg(not(feature = "KERNEL_MCS"))] possible_switch_to(dest); + #[cfg(feature = "KERNEL_MCS")] + if let Some(sc) = + convert_to_option_mut_type_ref::(dest.tcbSchedContext) + { + if sc.sc_sporadic() { + assert!(!sc.is_current()); + if !sc.is_current() { + sc.refill_unblock_check(); + } + } + } } else { panic!("queue is empty!") } @@ -214,14 +259,28 @@ impl notification_func for notification { #[cfg(feature = "KERNEL_MCS")] #[inline] fn maybeReturnSchedContext(&mut self, thread: &mut tcb_t) { - use sel4_task::sched_context::sched_context_t; - - let sc = convert_to_mut_type_ref::(self.get_ntfnSchedContext() as usize); - if sc.get_ptr() != 0 && sc.get_ptr() == thread.tcbSchedContext { - thread.tcbSchedContext = 0; - sc.scTcb = 0; - if thread.is_current() { - rescheduleRequired(); + if let Some(sc) = + convert_to_option_mut_type_ref::(self.get_ntfnSchedContext() as usize) + { + if sc.get_ptr() == thread.tcbSchedContext { + thread.tcbSchedContext = 0; + sc.scTcb = 0; + if thread.is_current() { + rescheduleRequired(); + } + } + } + } +} +#[cfg(feature = "KERNEL_MCS")] +pub fn maybeDonateSchedContext(tcb: &mut tcb_t, ntfnptr: ¬ification_t) { + if tcb.tcbSchedContext == 0 { + if let Some(sc) = convert_to_option_mut_type_ref::( + ntfnptr.get_ntfnSchedContext() as usize, + ) { + if sc.scTcb == 0 { + sc.schedContext_donate(tcb); + sc.schedContext_resume(); } } } diff --git a/sel4_ipc/src/transfer.rs b/sel4_ipc/src/transfer.rs index 0dc8088..42d7dd4 100644 --- a/sel4_ipc/src/transfer.rs +++ b/sel4_ipc/src/transfer.rs @@ -340,7 +340,7 @@ impl Transfer for tcb_t { #[cfg(feature = "KERNEL_MCS")] fn do_reply(&mut self, reply: &mut reply_t, grant: bool) { use sel4_common::{ffi::current_fault, structures_gen::seL4_Fault_Timeout}; - use sel4_task::{handleTimeout, ksCurSC, sched_context::sched_context_t}; + use sel4_task::{handleTimeout, sched_context::sched_context_t}; if reply.replyTCB == 0 || convert_to_mut_type_ref::(reply.replyTCB) @@ -358,7 +358,7 @@ impl Transfer for tcb_t { assert!(reply.replyTCB == 0); let sc = convert_to_mut_type_ref::(receiver.tcbSchedContext); - if sc.sc_sporadic() && sc.get_ptr() != unsafe { ksCurSC } { + if sc.sc_sporadic() && !sc.is_current() { sc.refill_unblock_check(); } assert_eq!(receiver.get_state(), ThreadState::ThreadStateBlockedOnReply); diff --git a/sel4_task/src/sched_context.rs b/sel4_task/src/sched_context.rs index d07e347..3b81434 100644 --- a/sel4_task/src/sched_context.rs +++ b/sel4_task/src/sched_context.rs @@ -76,6 +76,10 @@ impl sched_context { self.scPeriod == 0 } #[inline] + pub fn is_current(&self) -> bool { + self.get_ptr() == unsafe { ksCurSC } + } + #[inline] pub fn sc_released(&mut self) -> bool { if self.sc_active() { assert!(self.refill_sufficient(0)); @@ -295,7 +299,7 @@ impl sched_context { assert!(tcb.tcbSchedContext == 0); tcb.tcbSchedContext = self.get_ptr(); self.scTcb = tcb.get_ptr(); - if self.sc_sporadic() && self.sc_active() && self.get_ptr() != unsafe { ksCurSC } { + if self.sc_sporadic() && self.sc_active() && !self.is_current() { self.refill_unblock_check() } self.schedContext_resume(); diff --git a/sel4_task/src/scheduler.rs b/sel4_task/src/scheduler.rs index 285dd22..442b1ce 100644 --- a/sel4_task/src/scheduler.rs +++ b/sel4_task/src/scheduler.rs @@ -451,12 +451,18 @@ fn chooseThread() { } }; assert_ne!(thread, 0); - assert!(convert_to_mut_type_ref::(thread).is_schedulable()); - #[cfg(feature="KERNEL_MCS")] - { - assert!(convert_to_mut_type_ref::(convert_to_mut_type_ref::(thread).tcbSchedContext).refill_sufficient(0)); - assert!(convert_to_mut_type_ref::(convert_to_mut_type_ref::(thread).tcbSchedContext).refill_ready()); - } + assert!(convert_to_mut_type_ref::(thread).is_schedulable()); + #[cfg(feature = "KERNEL_MCS")] + { + assert!(convert_to_mut_type_ref::( + convert_to_mut_type_ref::(thread).tcbSchedContext + ) + .refill_sufficient(0)); + assert!(convert_to_mut_type_ref::( + convert_to_mut_type_ref::(thread).tcbSchedContext + ) + .refill_ready()); + } convert_to_mut_type_ref::(thread).switch_to_this(); } else { #[cfg(target_arch = "aarch64")] @@ -883,7 +889,7 @@ pub fn activateThread() { ThreadState::ThreadStateRestart => { let pc = thread.tcbArch.get_register(ArchReg::FaultIP); // setNextPC(thread, pc); - // sel4_common::println!("restart pc is {:x}",pc); + // sel4_common::println!("restart pc is {:x}",pc); thread.tcbArch.set_register(ArchReg::NextIP, pc); // setThreadState(thread, ThreadStateRunning); set_thread_state(thread, ThreadState::ThreadStateRunning);