Partially solve missing wakeups after separate timers
This commit is contained in:
+13
-10
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user