Partially solve missing wakeups after separate timers

This commit is contained in:
Wildan M
2026-07-17 13:27:43 +07:00
committed by Jeremy Soller
parent eb51898177
commit 4251102f0b
5 changed files with 31 additions and 21 deletions
+13 -10
View File
@@ -140,21 +140,19 @@ pub fn run_contexts_try(token: LockToken<'_, L0>) -> Option<MutexGuard<'_, L1, R
}
pub fn unblock_context(context_lock: &Arc<ContextLock>, 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<ContextLock>, token: &mut LockToken<'_
true
}
pub fn wakeup_context(context_lock: &Arc<ContextLock>) {
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)
+3 -3
View File
@@ -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());
}
}
+4 -2
View File
@@ -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::<usize>())
}
@@ -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::<usize>())
}
}
+7 -4
View File
@@ -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));
}
+4 -2
View File
@@ -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);