From cb64bc56fe04cbeff01d9aa338a498995fa6231e Mon Sep 17 00:00:00 2001 From: luozhixian Date: Fri, 10 Jul 2026 17:58:05 +0800 Subject: [PATCH 1/4] fix mem leak when exe shmat1 Signed-off-by: luozhixian --- fs/filesystems/memfs/src/shmem.rs | 25 +++++++++++++++++++++++-- mm/kalloc/src/lib.rs | 22 ++++++++++++++++++++++ posix/ipc/src/shm.rs | 26 +++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/fs/filesystems/memfs/src/shmem.rs b/fs/filesystems/memfs/src/shmem.rs index 539c6443d..7fffb0830 100644 --- a/fs/filesystems/memfs/src/shmem.rs +++ b/fs/filesystems/memfs/src/shmem.rs @@ -236,6 +236,12 @@ impl ShmemObject { } } +use ksync::static_lock; + +static_lock! { + static KERNEL_SHM_FS: Mutex, Path)>> = Mutex::new(None); +} + /// Creates an anonymous tmpfs-backed file object. /// /// The returned object is not inserted into a process-visible pathname @@ -247,8 +253,23 @@ fn create_anonymous_file( permission: NodePermission, initial_seals: ShmemSealSet, ) -> VfsResult { - let fs = new_tmpfs(kvfs::StatFsFlags::empty()); - let root = Path::new(Mount::new_root(&fs), fs.root_dir()); + // Kernel-owned shm files share a single tmpfs instance to avoid + // leaking Mount/SuperBlock references on each create/destroy cycle. + let root = match kind { + ShmemObjectKind::Kernel => { + let mut guard = KERNEL_SHM_FS.lock(); + if guard.is_none() { + let fs = new_tmpfs(kvfs::StatFsFlags::empty()); + let root = Path::new(Mount::new_root(&fs), fs.root_dir()); + *guard = Some((fs, root.clone())); + } + guard.as_ref().unwrap().1.clone() + } + ShmemObjectKind::Memfd => { + let fs = new_tmpfs(kvfs::StatFsFlags::empty()); + Path::new(Mount::new_root(&fs), fs.root_dir()) + } + }; let file = kvfs::Filename::new(name).open_with_flags_at(&root, &root, O_CREAT | O_EXCL, permission)?; let location = file.path().clone(); diff --git a/mm/kalloc/src/lib.rs b/mm/kalloc/src/lib.rs index d2259132a..7dfdcf06c 100644 --- a/mm/kalloc/src/lib.rs +++ b/mm/kalloc/src/lib.rs @@ -254,6 +254,18 @@ impl GlobalAllocator { Err(err) => { req_size /= 2; if req_size < min_size { + error!( + "kalloc heap expand failed: layout {:?}, req_size={}, \ + min_size={}, heap_ready={}, balloc_used={}, balloc_total={}, \ + err={:?}", + layout, + req_size * 2, // original req_size before halving + min_size, + heap_ready, + balloc.used_bytes(), + balloc.total_bytes(), + err + ); return Err(err); } continue; @@ -535,6 +547,16 @@ unsafe impl GlobalAlloc for GlobalAllocator { if let Ok(ptr) = GlobalAllocator::alloc(self, layout) { ptr.as_ptr() } else { + let used = self.used_bytes(); + let avail = self.available_bytes(); + error!( + "kalloc OOM: layout {:?} (size={}, align={}), heap used={:#x} avail={:#x}", + layout, + layout.size(), + layout.align(), + used, + avail + ); alloc::alloc::handle_alloc_error(layout) } }; diff --git a/posix/ipc/src/shm.rs b/posix/ipc/src/shm.rs index fc26411be..75393d294 100644 --- a/posix/ipc/src/shm.rs +++ b/posix/ipc/src/shm.rs @@ -69,11 +69,19 @@ impl ShmInner { pid: Pid, ) -> KResult { let page_num = memaddr::align_up_4k(size) / PAGE_SIZE_4K; - let file = create_kernel_file( + let shm_obj = create_kernel_file( &format!("SYSV{shmid:x}"), kvfs::NodePermission::from_bits_truncate(0o600), - )? - .into_file()?; + )?; + // Unlink the backing file from tmpfs so the inode's lifetime is + // tied solely to the returned VfsFile; when the last reference + // drops the page cache is freed. + shm_obj + .location() + .mount() + .root_path() + .unlink(shm_obj.location().name())?; + let file = shm_obj.into_file()?; file.path().truncate((page_num * PAGE_SIZE_4K) as u64)?; Ok(ShmInner { @@ -488,6 +496,18 @@ pub fn sys_shmctl(shmid: i32, cmd: u32, buf: UserPtr) -> KResult Date: Mon, 13 Jul 2026 10:13:09 +0800 Subject: [PATCH 2/4] update Signed-off-by: luozhixian --- fs/filesystems/memfs/src/shmem.rs | 4 +--- mm/kalloc/src/lib.rs | 12 ------------ posix/ipc/src/shm.rs | 27 ++++++++++++--------------- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/fs/filesystems/memfs/src/shmem.rs b/fs/filesystems/memfs/src/shmem.rs index 7fffb0830..58dc99878 100644 --- a/fs/filesystems/memfs/src/shmem.rs +++ b/fs/filesystems/memfs/src/shmem.rs @@ -6,7 +6,7 @@ use alloc::{string::String, sync::Arc}; -use ksync::Mutex; +use ksync::{Mutex, static_lock}; use kvfs::{Mount, NodePermission, Path, SuperBlock, VfsFile, VfsResult, dentry_open}; use linux_raw_sys::general::{ F_SEAL_FUTURE_WRITE, F_SEAL_GROW, F_SEAL_SEAL, F_SEAL_SHRINK, F_SEAL_WRITE, O_CREAT, O_EXCL, @@ -236,8 +236,6 @@ impl ShmemObject { } } -use ksync::static_lock; - static_lock! { static KERNEL_SHM_FS: Mutex, Path)>> = Mutex::new(None); } diff --git a/mm/kalloc/src/lib.rs b/mm/kalloc/src/lib.rs index 7dfdcf06c..5ccf6fb3d 100644 --- a/mm/kalloc/src/lib.rs +++ b/mm/kalloc/src/lib.rs @@ -254,18 +254,6 @@ impl GlobalAllocator { Err(err) => { req_size /= 2; if req_size < min_size { - error!( - "kalloc heap expand failed: layout {:?}, req_size={}, \ - min_size={}, heap_ready={}, balloc_used={}, balloc_total={}, \ - err={:?}", - layout, - req_size * 2, // original req_size before halving - min_size, - heap_ready, - balloc.used_bytes(), - balloc.total_bytes(), - err - ); return Err(err); } continue; diff --git a/posix/ipc/src/shm.rs b/posix/ipc/src/shm.rs index 75393d294..4cd18baff 100644 --- a/posix/ipc/src/shm.rs +++ b/posix/ipc/src/shm.rs @@ -474,13 +474,13 @@ pub fn sys_shmat(shmid: i32, addr: usize, shmflg: u32) -> KResult { } pub fn sys_shmctl(shmid: i32, cmd: u32, buf: UserPtr) -> KResult { - let shm_inner = { + let shm_inner_arc = { let shm_manager = SHM_MANAGER.lock(); shm_manager .get_inner_by_shmid(shmid) .ok_or(KError::InvalidInput)? }; - let mut shm_inner = shm_inner.lock(); + let mut shm_inner = shm_inner_arc.lock(); let cmd = cmd as i32; if cmd == IPC_SET { @@ -488,26 +488,23 @@ pub fn sys_shmctl(shmid: i32, cmd: u32, buf: UserPtr) -> KResult Date: Mon, 13 Jul 2026 10:34:42 +0800 Subject: [PATCH 3/4] update Signed-off-by: luozhixian --- posix/ipc/src/shm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix/ipc/src/shm.rs b/posix/ipc/src/shm.rs index 4cd18baff..ddd711217 100644 --- a/posix/ipc/src/shm.rs +++ b/posix/ipc/src/shm.rs @@ -80,7 +80,7 @@ impl ShmInner { .location() .mount() .root_path() - .unlink(shm_obj.location().name())?; + .unlink(&shm_obj.location().name())?; let file = shm_obj.into_file()?; file.path().truncate((page_num * PAGE_SIZE_4K) as u64)?; -- Gitee From ff063b5f06faf5955b3963d164c9c45355a6a494 Mon Sep 17 00:00:00 2001 From: luozhixian Date: Mon, 13 Jul 2026 10:46:51 +0800 Subject: [PATCH 4/4] update Signed-off-by: luozhixian --- posix/ipc/src/shm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix/ipc/src/shm.rs b/posix/ipc/src/shm.rs index ddd711217..1d3f19dce 100644 --- a/posix/ipc/src/shm.rs +++ b/posix/ipc/src/shm.rs @@ -485,10 +485,10 @@ pub fn sys_shmctl(shmid: i32, cmd: u32, buf: UserPtr) -> KResult