From 867d9cf2a8bbb2387f300f1e78c7f6bc59d42c64 Mon Sep 17 00:00:00 2001 From: bunnie Date: Mon, 2 Feb 2026 01:15:55 +0800 Subject: [PATCH] fix connection allocation the kernel is supposed to first search for an existing connection before allocating a new one. this patch fixes the order of search so that it meets this spec. previously it was preferring to allocate a new connection before re-using an old one. I think we got away with this because we just didn't have that many connections. it'll be interesting to see if this causes any regressions on Precursor. --- kernel/src/services.rs | 58 ++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/kernel/src/services.rs b/kernel/src/services.rs index 142cd7d43..1ccd9cadc 100644 --- a/kernel/src/services.rs +++ b/kernel/src/services.rs @@ -1964,35 +1964,36 @@ impl SystemServices { ArchProcess::with_inner_mut(|process_inner| { assert_eq!(pid, process_inner.pid); let mut slot_idx = None; - // Look through the connection map for (1) a free slot, and (2) an - // existing connection + // Look through the connection map for (1) an existing connection, and (2) a free slot + for (connection_idx, server_idx) in process_inner.connection_map.iter().enumerate() { + if let Some(server_idx) = server_idx { + let server_idx = server_idx.get() as usize; + // Tombstone or unallocated server index + if server_idx < 2 { + continue; + } + // If a connection to this server ID exists already, return it. + let server_idx = server_idx - 2; + if let Some(allocated_server) = &self.servers[server_idx] { + if allocated_server.sid == sid { + // println!( + // "KERNEL({}): Existing connection to SID {:x?} found in this process @ {}, + // process connection map is: {:?}", pid.get(), + // sid, + // (connection_idx as CID) + 2, + // process_inner.connection_map, + // ); + return Ok((connection_idx as CID) + 2); + } + } + } + } for (connection_idx, server_idx) in process_inner.connection_map.iter().enumerate() { // If we find an empty slot, use it - let Some(server_idx) = server_idx else { - if slot_idx.is_none() { - slot_idx = Some(connection_idx); - } - continue; - }; - let server_idx = server_idx.get() as usize; - - // Tombstone or unallocated server index - if server_idx < 2 { - continue; - } - - // If a connection to this server ID exists already, return it. - let server_idx = server_idx - 2; - if let Some(allocated_server) = &self.servers[server_idx] { - if allocated_server.sid == sid { - // println!("KERNEL({}): Existing connection to SID {:?} found in this process @ {}, - // process connection map is: {:?}", _pid.get(), - // sid, - // (connection_idx as CID) + 2, - // process_inner.connection_map, - // ); - return Ok((connection_idx as CID) + 2); - } + if server_idx.is_none() { + assert!(slot_idx.is_none()); + slot_idx = Some(connection_idx); + break; } } let slot_idx = slot_idx.ok_or(Error::OutOfMemory)?; @@ -2004,7 +2005,7 @@ impl SystemServices { process_inner.connection_map[slot_idx] = Some(NonZeroU8::new((server_idx as u8) + 2).unwrap()); // println!( - // "KERNEL({}): New connection to {:?}. After connection, cid is {} and process + // "KERNEL({}): New connection to {:x?}. After connection, cid is {} and process // connection map is: {:?}", pid.get(), // sid, // slot_idx + 2, @@ -2049,6 +2050,7 @@ impl SystemServices { // Nullify this connection ID. It may now be reused. *idx = None; + // println!("***** disconnected {} {:?}", slot_idx, process_inner.connection_map); klog!("Removing server from table"); Ok(()) })