Track kernel buffers per-process
This commit is contained in:
parent
75814f3589
commit
4d908f1335
@ -332,7 +332,7 @@ extern "C" fn syscall_handler() {
|
|||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
TASKING.record_buf_dealloc(buffer.len());
|
TASKING.record_curr_buf_dealloc(buffer.len());
|
||||||
} else {
|
} else {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
@ -420,6 +420,12 @@ extern "C" fn syscall_handler() {
|
|||||||
SECOND_PORT.write_u32s(&[
|
SECOND_PORT.write_u32s(&[
|
||||||
total_len, // Total block length
|
total_len, // Total block length
|
||||||
]);
|
]);
|
||||||
|
TASKING.record_curr_buf_dealloc(buffer.len());
|
||||||
|
#[expect(
|
||||||
|
clippy::unwrap_used,
|
||||||
|
reason = "The PID is known valid due to using it in message_queue_mut in the if-let condition"
|
||||||
|
)]
|
||||||
|
TASKING.record_buf_alloc(pid, buffer.len()).unwrap();
|
||||||
let buffer = Box::into_raw(buffer);
|
let buffer = Box::into_raw(buffer);
|
||||||
#[expect(
|
#[expect(
|
||||||
clippy::unwrap_used,
|
clippy::unwrap_used,
|
||||||
@ -503,7 +509,7 @@ extern "C" fn syscall_handler() {
|
|||||||
}
|
}
|
||||||
15 => {
|
15 => {
|
||||||
if let Some(buf) = get_buffer(regs.rcx) {
|
if let Some(buf) = get_buffer(regs.rcx) {
|
||||||
TASKING.record_buf_dealloc(buf.len());
|
TASKING.record_curr_buf_dealloc(buf.len());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
16 => {
|
16 => {
|
||||||
@ -511,7 +517,7 @@ extern "C" fn syscall_handler() {
|
|||||||
let rounded_size = size.next_multiple_of(4096);
|
let rounded_size = size.next_multiple_of(4096);
|
||||||
KERNEL_SPACE.lock().alloc_force_user = true;
|
KERNEL_SPACE.lock().alloc_force_user = true;
|
||||||
let mut buffer = Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE);
|
let mut buffer = Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE);
|
||||||
TASKING.record_buf_alloc(rounded_size);
|
TASKING.record_curr_buf_alloc(rounded_size);
|
||||||
buffer.resize(rounded_size, 0);
|
buffer.resize(rounded_size, 0);
|
||||||
let buffer = buffer.into_boxed_slice();
|
let buffer = buffer.into_boxed_slice();
|
||||||
let buffer = Box::into_raw(buffer);
|
let buffer = Box::into_raw(buffer);
|
||||||
|
@ -101,6 +101,7 @@ struct Process {
|
|||||||
data_buffers: Mutex<Slab<*mut [u8]>>,
|
data_buffers: Mutex<Slab<*mut [u8]>>,
|
||||||
message_queue: Mutex<SegQueue<(usize, usize)>>,
|
message_queue: Mutex<SegQueue<(usize, usize)>>,
|
||||||
sleeping: RwLock<Option<SleepReason>>,
|
sleeping: RwLock<Option<SleepReason>>,
|
||||||
|
buf_allocated: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Process {}
|
unsafe impl Send for Process {}
|
||||||
@ -114,7 +115,6 @@ pub static TASKING: Lazy<Tasking> = Lazy::new(|| Tasking {
|
|||||||
ready_to_run: Mutex::new(VecDeque::new()),
|
ready_to_run: Mutex::new(VecDeque::new()),
|
||||||
current_pid: RwLock::new(None),
|
current_pid: RwLock::new(None),
|
||||||
freeable_kstacks: Mutex::new(Vec::new()),
|
freeable_kstacks: Mutex::new(Vec::new()),
|
||||||
buf_allocated: AtomicUsize::new(0),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -123,7 +123,6 @@ pub struct Tasking {
|
|||||||
ready_to_run: Mutex<VecDeque<usize>>,
|
ready_to_run: Mutex<VecDeque<usize>>,
|
||||||
current_pid: RwLock<Option<usize>>,
|
current_pid: RwLock<Option<usize>>,
|
||||||
freeable_kstacks: Mutex<Vec<Box<[usize], &'static ASpaceMutex>>>,
|
freeable_kstacks: Mutex<Vec<Box<[usize], &'static ASpaceMutex>>>,
|
||||||
buf_allocated: AtomicUsize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const KSTACK_SIZE: usize = 0x1_0000 / 8;
|
pub const KSTACK_SIZE: usize = 0x1_0000 / 8;
|
||||||
@ -211,6 +210,7 @@ impl Tasking {
|
|||||||
message_queue: Mutex::new(SegQueue::new()),
|
message_queue: Mutex::new(SegQueue::new()),
|
||||||
sleeping: RwLock::new(None),
|
sleeping: RwLock::new(None),
|
||||||
arguments: (user_arg_mem.cast(), arguments.len()),
|
arguments: (user_arg_mem.cast(), arguments.len()),
|
||||||
|
buf_allocated: AtomicUsize::new(0),
|
||||||
});
|
});
|
||||||
self.ready_to_run.lock().push_back(pid);
|
self.ready_to_run.lock().push_back(pid);
|
||||||
Ok(pid)
|
Ok(pid)
|
||||||
@ -291,10 +291,13 @@ impl Tasking {
|
|||||||
|| ACTIVE_SPACE.lock().get_bytes_allocated(),
|
|| ACTIVE_SPACE.lock().get_bytes_allocated(),
|
||||||
|space| space.get_bytes_allocated(),
|
|space| space.get_bytes_allocated(),
|
||||||
);
|
);
|
||||||
|
let buf_bytes_used = current_process.buf_allocated.load(Ordering::Relaxed);
|
||||||
println!(
|
println!(
|
||||||
"[TASKING] PID {current_pid} exiting, used {} ({}), this is being leaked.",
|
"[TASKING] PID {current_pid} exiting, used {} ({}) + {} ({}) of kernel buffers, this is being leaked.",
|
||||||
SizeFormatter::new(bytes_used, BINARY),
|
SizeFormatter::new(bytes_used, BINARY),
|
||||||
bytes_used / 4096
|
bytes_used / 4096,
|
||||||
|
SizeFormatter::new(buf_bytes_used, BINARY),
|
||||||
|
buf_bytes_used / 4096,
|
||||||
);
|
);
|
||||||
self.freeable_kstacks.lock().push(processes.remove(current_pid).kernel_stack);
|
self.freeable_kstacks.lock().push(processes.remove(current_pid).kernel_stack);
|
||||||
}
|
}
|
||||||
@ -392,32 +395,58 @@ impl Tasking {
|
|||||||
self.processes.read()[self.current_pid.read().unwrap()].arguments
|
self.processes.read()[self.current_pid.read().unwrap()].arguments
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn record_buf_alloc(&self, size: usize) {
|
pub fn record_curr_buf_alloc(&self, size: usize) {
|
||||||
self.buf_allocated.fetch_add(size, Ordering::Relaxed);
|
#[warn(clippy::unwrap_used, reason = "FIXME")]
|
||||||
|
#[warn(clippy::indexing_slicing, reason = "FIXME(?)")]
|
||||||
|
self.processes.read()[self.current_pid.read().unwrap()]
|
||||||
|
.buf_allocated
|
||||||
|
.fetch_add(size, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn record_buf_dealloc(&self, size: usize) {
|
pub fn record_curr_buf_dealloc(&self, size: usize) {
|
||||||
self.buf_allocated.fetch_sub(size, Ordering::Relaxed);
|
#[warn(clippy::unwrap_used, reason = "FIXME")]
|
||||||
|
#[warn(clippy::indexing_slicing, reason = "FIXME(?)")]
|
||||||
|
self.processes.read()[self.current_pid.read().unwrap()]
|
||||||
|
.buf_allocated
|
||||||
|
.fetch_sub(size, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn record_buf_alloc(&self, pid: usize, size: usize) -> Result<(), InvalidPid> {
|
||||||
|
self.processes
|
||||||
|
.read()
|
||||||
|
.get(pid)
|
||||||
|
.ok_or(InvalidPid)?
|
||||||
|
.buf_allocated
|
||||||
|
.fetch_add(size, Ordering::Relaxed);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn record_buf_dealloc(&self, pid: usize, size: usize) -> Result<(), InvalidPid> {
|
||||||
|
self.processes
|
||||||
|
.read()
|
||||||
|
.get(pid)
|
||||||
|
.ok_or(InvalidPid)?
|
||||||
|
.buf_allocated
|
||||||
|
.fetch_sub(size, Ordering::Relaxed);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_stats(&self) {
|
pub fn print_stats(&self) {
|
||||||
let mut total =
|
let mut total =
|
||||||
KERNEL_SPACE.lock().get_bytes_allocated() + self.buf_allocated.load(Ordering::Relaxed);
|
KERNEL_SPACE.lock().get_bytes_allocated();
|
||||||
println!(
|
println!(
|
||||||
"[TASKING] Kernel misc used {}",
|
"[TASKING] Kernel used {}",
|
||||||
SizeFormatter::new(KERNEL_SPACE.lock().get_bytes_allocated(), BINARY)
|
SizeFormatter::new(KERNEL_SPACE.lock().get_bytes_allocated(), BINARY)
|
||||||
);
|
);
|
||||||
println!(
|
|
||||||
"[TASKING] Kernel buffers used {}",
|
|
||||||
SizeFormatter::new(self.buf_allocated.load(Ordering::Relaxed), BINARY)
|
|
||||||
);
|
|
||||||
for (i, process) in self.processes.read().iter() {
|
for (i, process) in self.processes.read().iter() {
|
||||||
let bytes_used = process.address_space.as_ref().map_or_else(
|
let bytes_used = process.address_space.as_ref().map_or_else(
|
||||||
|| ACTIVE_SPACE.lock().get_bytes_allocated(),
|
|| ACTIVE_SPACE.lock().get_bytes_allocated(),
|
||||||
|space| space.get_bytes_allocated(),
|
|space| space.get_bytes_allocated(),
|
||||||
);
|
);
|
||||||
|
let buf_bytes_used = process.buf_allocated.load(Ordering::Relaxed);
|
||||||
total += bytes_used;
|
total += bytes_used;
|
||||||
println!("[TASKING] PID {} used {}", i, SizeFormatter::new(bytes_used, BINARY));
|
total += buf_bytes_used;
|
||||||
|
println!("[TASKING] PID {} used {} + {} of kernel buffers", i, SizeFormatter::new(bytes_used, BINARY), SizeFormatter::new(buf_bytes_used, BINARY));
|
||||||
}
|
}
|
||||||
println!("[TASKING] Total used {} ({})", SizeFormatter::new(total, BINARY), total / 4096);
|
println!("[TASKING] Total used {} ({})", SizeFormatter::new(total, BINARY), total / 4096);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user