From ac913e49f9666548ae877b1ead007f9000dc89b7 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 24 Feb 2023 23:05:11 +0100 Subject: [PATCH] Pin kmain contexts to corresponding CPUs. --- src/context/list.rs | 19 +++++++++++++++---- src/context/mod.rs | 4 +++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/context/list.rs b/src/context/list.rs index 7d2973a9..efca76da 100644 --- a/src/context/list.rs +++ b/src/context/list.rs @@ -50,10 +50,23 @@ impl ContextList { self.map.range(range) } + pub(crate) fn insert_context_raw(&mut self, id: ContextId) -> Result<&Arc<RwLock<Context>>> { + assert!(self.map.insert(id, Arc::new(RwLock::new(Context::new(id)?))).is_none()); + + Ok(self.map.get(&id).expect("Failed to insert new context. ID is out of bounds.")) + } + /// Create a new context. pub fn new_context(&mut self) -> Result<&Arc<RwLock<Context>>> { + // Zero is not a valid context ID, therefore add 1. + // + // FIXME: Ensure the number of CPUs can't switch between new_context calls. + let min = crate::cpu_count() + 1; + + self.next_id = core::cmp::max(self.next_id, min); + if self.next_id >= super::CONTEXT_MAX_CONTEXTS { - self.next_id = 1; + self.next_id = min; } while self.map.contains_key(&ContextId::from(self.next_id)) { @@ -67,9 +80,7 @@ impl ContextList { let id = ContextId::from(self.next_id); self.next_id += 1; - assert!(self.map.insert(id, Arc::new(RwLock::new(Context::new(id)?))).is_none()); - - Ok(self.map.get(&id).expect("Failed to insert new context. ID is out of bounds.")) + self.insert_context_raw(id) } /// Spawn a context from a function. diff --git a/src/context/mod.rs b/src/context/mod.rs index c3296d4f..7f5fc849 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -65,8 +65,10 @@ pub use self::arch::empty_cr3; pub fn init() { let mut contexts = contexts_mut(); - let context_lock = contexts.new_context().expect("could not initialize first context"); + let id = ContextId::from(crate::cpu_id() + 1); + let context_lock = contexts.insert_context_raw(id).expect("could not initialize first context"); let mut context = context_lock.write(); + context.sched_affinity = Some(crate::cpu_id()); self::arch::EMPTY_CR3.call_once(|| unsafe { RmmA::table(TableKind::User) }); -- GitLab