From 4251102f0bc9a57d4de978028acd5ed820eafe8e Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 17 Jul 2026 13:27:43 +0700 Subject: [PATCH] Partially solve missing wakeups after separate timers --- src/context/mod.rs | 23 +++++++++++++---------- src/context/switch.rs | 6 +++--- src/scheme/proc.rs | 6 ++++-- src/scheme/user.rs | 11 +++++++---- src/startup/mod.rs | 6 ++++-- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index 7eb3e9199b..6999bc2802 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -140,21 +140,19 @@ pub fn run_contexts_try(token: LockToken<'_, L0>) -> Option, token: &mut LockToken<'_, L3>) -> bool { - let was_blocked = { + let cpu_id = { let mut guard = context_lock.write(token.token()); if !guard.unblock_no_ipi() { + if guard.status.is_runnable() { + // already set to runnable externally + wakeup_context(context_lock); + } return false; } - - true + guard.cpu_id }; - let percpu: &PercpuBlock = PercpuBlock::current(); - - let weak = WeakContextRef(Arc::downgrade(context_lock)); - let cpu_id = context_lock.write(token.token()).cpu_id; - - percpu.switch_internals.wakeup_list.borrow_mut().push(weak); + wakeup_context(context_lock); if let Some(cpu_id) = cpu_id && cpu_id != crate::cpu_id() @@ -165,6 +163,12 @@ pub fn unblock_context(context_lock: &Arc, token: &mut LockToken<'_ true } +pub fn wakeup_context(context_lock: &Arc) { + let percpu: &PercpuBlock = PercpuBlock::current(); + let weak = WeakContextRef(Arc::downgrade(context_lock)); + percpu.switch_internals.wakeup_list.borrow_mut().push(weak); +} + pub fn init(token: &mut CleanLockToken) { let owner = None; // kmain not owned by any fd let mut context = Context::new(owner).expect("failed to create kmain context"); @@ -291,7 +295,6 @@ pub fn spawn( let context_lock = Arc::new(ContextLock::new(context)); let context_ref = ContextRef(Arc::clone(&context_lock)); let run_ref = WeakContextRef(Arc::downgrade(&context_ref.0)); - idle_contexts(token.downgrade()).push_back(run_ref); contexts_mut(token.downgrade()).insert(context_ref); Ok(context_lock) diff --git a/src/context/switch.rs b/src/context/switch.rs index 915921a29f..d79db4a3de 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -217,9 +217,9 @@ pub fn switch(token: &mut CleanLockToken) -> SwitchResult { } // Drain from percpu - let mut percpu_wake = percpu.switch_internals.wakeup_list.replace(Vec::new()); - if percpu_wake.len() > 0 { - for context_ref in percpu_wake.iter() { + { + let mut percpu_wake = percpu.switch_internals.wakeup_list.borrow_mut(); + for context_ref in percpu_wake.drain(..) { wakeups.push(context_ref.clone()); } } diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index d8abeea4af..6dcc276375 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -4,7 +4,7 @@ use crate::{ context::{HardBlockedReason, LockedFdTbl, SignalState}, file::InternalFlags, memory::{handle_notify_files, AddrSpace, AddrSpaceWrapper, Grant, PageSpan, UnmapVec}, - unblock_context, Context, ContextLock, Status, + unblock_context, wakeup_context, Context, ContextLock, Status, }, memory::{Page, VirtualAddress, PAGE_SIZE}, ptrace, @@ -1132,6 +1132,7 @@ impl ContextHandle { reason: HardBlockedReason::NotYetStarted, } => { *status = Status::Runnable; + wakeup_context(&context); Ok(buf.len()) } _ => Err(Error::new(EINVAL)), @@ -1278,6 +1279,7 @@ impl ContextHandle { } = guard.status { guard.status = Status::Runnable; + wakeup_context(&context); } Ok(size_of::()) } @@ -1320,7 +1322,7 @@ impl ContextHandle { ctxt.status = context::Status::Runnable; ctxt.being_sigkilled = true; } - unblock_context(&context, &mut token.token().downgrade()); + wakeup_context(&context); Ok(size_of::()) } } diff --git a/src/scheme/user.rs b/src/scheme/user.rs index 0eb0afd8f0..e6e93d3048 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -22,10 +22,12 @@ use crate::{ handle_notify_files, AddrSpace, AddrSpaceWrapper, BorrowedFmapSource, Grant, GrantFileRef, MmapMode, PageSpan, UnmapVec, DANGLING, }, - unblock_context, BorrowedHtBuf, ContextLock, PreemptGuard, PreemptGuardL1, Status, + unblock_context, wakeup_context, BorrowedHtBuf, ContextLock, PreemptGuard, PreemptGuardL1, + Status, WeakContextRef, }, event, memory::{Frame, Page, VirtualAddress, PAGE_SIZE}, + percpu::PercpuBlock, scheme::SchemeId, sync::{CleanLockToken, LockToken, Mutex, RwLock, WaitQueue, L1}, syscall::{ @@ -873,7 +875,7 @@ impl UserInner { } }; - let context = context.upgrade().ok_or(Error::new(ESRCH))?; + let context_lock = context.upgrade().ok_or(Error::new(ESRCH))?; let mut lock_token = token.token(); let (frame, _) = AddrSpace::current()? @@ -884,12 +886,13 @@ impl UserInner { .ok_or(Error::new(EFAULT))?; { - let mut context = context.write(token.token()); + let mut context = context_lock.write(token.token()); if let Status::HardBlocked { reason: HardBlockedReason::AwaitingMmap { .. }, } = context.status { - context.status = Status::Runnable + context.status = Status::Runnable; + wakeup_context(&context_lock); } context.fmap_ret = Some(Frame::containing(frame)); } diff --git a/src/startup/mod.rs b/src/startup/mod.rs index 7b3f532fa4..b517d41672 100644 --- a/src/startup/mod.rs +++ b/src/startup/mod.rs @@ -7,7 +7,7 @@ use core::{ use crate::{ arch::interrupt, - context::{self, switch::SwitchResult}, + context::{self, switch::SwitchResult, wakeup_context, Status}, memory::{PhysicalAddress, RmmA, RmmArch}, profiling, scheme, sync::CleanLockToken, @@ -175,13 +175,15 @@ pub(crate) fn kmain(bootstrap: Bootstrap) -> ! { match context::spawn(true, owner, userspace_init, &mut token) { Ok(context_lock) => { let mut context = context_lock.write(token.token()); - context.status = context::Status::Runnable; + context.status = Status::Runnable; context.name.clear(); context.name.push_str("[bootstrap]"); // TODO: Remove these from kernel context.euid = 0; context.egid = 0; + + wakeup_context(&context_lock); } Err(err) => { panic!("failed to spawn userspace_init: {:?}", err);