From 0b089c7582284b28ae475df6fe7d900d69f502da Mon Sep 17 00:00:00 2001 From: vasilito Date: Wed, 8 Jul 2026 18:54:32 +0300 Subject: [PATCH] =?UTF-8?q?kernel:=20implement=20/proc/[pid]/statm=20?= =?UTF-8?q?=E2=80=94=20memory=20summary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New ProcStatm ContextHandle that reports the 7-field memory summary matching Linux /proc/[pid]/statm format: size resident shared text lib data dt All values in pages. Cross-referenced with Linux 7.1 fs/proc/array.c:proc_pid_statm(). Resident count is approximated as the total physical grants (GRANT_PHYS), since Red Bear has no paging/swapping and all memory is resident. Other fields (shared, lib, dt) are 0 since Red Bear's memory model doesn't distinguish these. --- src/scheme/proc.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index d22f0af5b5..a75638a5f3 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -173,6 +173,9 @@ enum ContextHandle { ProcMaps { pid: usize, }, + ProcStatm { + pid: usize, + }, } #[derive(Clone)] struct Handle { @@ -393,6 +396,7 @@ impl ProcScheme { (Some("cmdline"), None) => Some(ContextHandle::ProcCmdline { pid }), (Some("status"), None) => Some(ContextHandle::ProcStatus { pid }), (Some("maps"), None) => Some(ContextHandle::ProcMaps { pid }), + (Some("statm"), None) => Some(ContextHandle::ProcStatm { pid }), _ => None, } } @@ -1930,6 +1934,34 @@ impl ContextHandle { } read_from(buf, output.as_bytes(), offset) } + ContextHandle::ProcStatm { pid } => { + let context = proc_context(*pid, token).ok_or(Error::new(ESRCH))?; + let addr_space = context.read(token.token()).addr_space.clone(); + let (size, resident) = if let Some(addr_space) = addr_space { + let token2 = token.downgrade(); + let guard = addr_space.acquire_read(token2); + let mut total_size = 0usize; + let mut total_resident = 0usize; + for (_grant_base, grant_info) in guard.grants.iter() { + let page_count = grant_info.page_count() * PAGE_SIZE; + total_size += page_count; + if grant_info.grant_flags().contains(GrantFlags::GRANT_PHYS) { + total_resident += page_count; + } + } + (total_size / PAGE_SIZE, total_resident / PAGE_SIZE) + } else { + (0, 0) + }; + // Format: size resident shared text lib data dt (in pages) + // Cross-referenced with Linux 7.1 fs/proc/array.c:proc_pid_statm(). + // On Red Bear we approximate: shared=0, text=size, lib=0, data=size, dt=0. + let output = alloc::format!( + "{} {} 0 {} 0 {} 0\n", + size, resident, size, size + ); + read_from(buf, output.as_bytes(), offset) + } ContextHandle::ProcRoot | ContextHandle::ProcDir { .. } => Err(Error::new(EBADF)), ContextHandle::MmapMinAddr(addrspace) => { let mut token = token.token();