fix: bugs
This commit is contained in:
@@ -94,7 +94,6 @@ pub enum PMRequest {
|
||||
size_pages: usize,
|
||||
channel_id: u16,
|
||||
},
|
||||
/// Sentinel — never pushed onto the queue; result of unpack(0).
|
||||
None,
|
||||
}
|
||||
|
||||
@@ -160,30 +159,18 @@ impl PMRequest {
|
||||
|
||||
// Response type
|
||||
|
||||
/// Result returned by `PMActor::process_messages()` for each completed request.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PMResponse {
|
||||
/// Channel to route this response to. `0` = discard.
|
||||
pub channel_id: u16,
|
||||
/// The actual outcome.
|
||||
pub result: PMResult,
|
||||
}
|
||||
|
||||
/// Outcome of a single PM operation.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum PMResult {
|
||||
/// Memory was allocated. `cap` is the strong capability to the region.
|
||||
/// `order` is the buddy order — **must** be passed back to `Free`.
|
||||
Allocated { cap: Capability, order: usize },
|
||||
|
||||
/// The actor had insufficient free pages.
|
||||
/// Future: ballooning subsystem intercepts this and retries.
|
||||
OutOfMemory { size_pages: usize },
|
||||
|
||||
/// A fixed sub-region was carved successfully.
|
||||
Carved { cap: Capability },
|
||||
|
||||
/// Free completed (no capability issued — memory returned to buddy pool).
|
||||
Freed { pages_returned: usize },
|
||||
}
|
||||
|
||||
@@ -194,7 +181,6 @@ pub enum PMResult {
|
||||
/// `pop` — exactly one consumer, no locking on the read side.
|
||||
pub struct PMActorQueue {
|
||||
buffer: [AtomicU64; QUEUE_SIZE],
|
||||
/// Pad to separate producer-written `tail` from consumer-read `head`.
|
||||
_pad0: [u8; 64],
|
||||
head: AtomicUsize,
|
||||
_pad1: [u8; 64],
|
||||
@@ -269,15 +255,10 @@ impl PMActorQueue {
|
||||
/// Only `process_messages()` ever mutates `buddy` and `queue.head`.
|
||||
/// This is enforced by taking `&mut self` on `process_messages`.
|
||||
pub struct PMActor {
|
||||
/// Unique identity within the actor federation.
|
||||
pub actor_id: u64,
|
||||
/// Root strong capability over the entire managed physical range.
|
||||
pub root_untyped: Capability,
|
||||
/// `(inclusive_start, exclusive_end)` physical addresses.
|
||||
pub managed_range: (PhysAddr, PhysAddr),
|
||||
/// Inbox — producers write here, actor reads here.
|
||||
queue: PMActorQueue,
|
||||
/// Local buddy allocator. Only ever touched in `process_messages`.
|
||||
buddy: BuddyAllocator,
|
||||
}
|
||||
|
||||
@@ -325,10 +306,16 @@ impl PMActor {
|
||||
/// `buddy` and `queue.head` are mutated — no other thread touches them.
|
||||
/// The only shared state is the queue's `tail`, which is written by producers
|
||||
/// via `AtomicUsize::compare_exchange_weak`, never by this path.
|
||||
/// Maximum requests to process in a single `process_messages` call.
|
||||
/// Prevents kernel starvation when the inbox is deep.
|
||||
const MAX_MESSAGES_PER_CALL: usize = 64;
|
||||
|
||||
pub fn process_messages(&mut self) -> Vec<PMResponse> {
|
||||
let mut responses = Vec::new();
|
||||
let mut remaining = Self::MAX_MESSAGES_PER_CALL;
|
||||
|
||||
while let Some(req) = self.queue.pop() {
|
||||
remaining -= 1;
|
||||
let resp = match req {
|
||||
PMRequest::Allocate { size_pages, token_sig, channel_id } => {
|
||||
self.handle_allocate(size_pages, token_sig, channel_id)
|
||||
@@ -342,12 +329,13 @@ impl PMActor {
|
||||
PMRequest::None => continue,
|
||||
};
|
||||
|
||||
// Only push responses that need routing.
|
||||
// Free responses (channel_id == 0) are still pushed so callers can
|
||||
// audit completion if needed; they may simply drop them.
|
||||
if let Some(r) = resp {
|
||||
responses.push(r);
|
||||
}
|
||||
|
||||
if remaining == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
responses
|
||||
@@ -434,9 +422,6 @@ impl PMActor {
|
||||
|
||||
self.buddy.free(local_frame_idx, order);
|
||||
|
||||
// Free never needs routing — return None to skip Vec push, or push with
|
||||
// channel_id=0 for audit purposes. We skip to avoid unnecessary allocation.
|
||||
// Callers that need a Free-complete signal should use a separate mechanism.
|
||||
None
|
||||
}
|
||||
|
||||
@@ -446,7 +431,6 @@ impl PMActor {
|
||||
size_pages: usize,
|
||||
channel_id: u16,
|
||||
) -> Option<PMResponse> {
|
||||
// Validate offset + size within range.
|
||||
let range_pages = self.buddy.total_pages();
|
||||
if offset_pages >= range_pages
|
||||
|| size_pages == 0
|
||||
|
||||
Reference in New Issue
Block a user