fix(mm): 修复匿名共享页跨进程共享问题#1334
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR implements shared page caching for anonymous shared mappings (MAP_SHARED | MAP_ANONYMOUS) to prevent duplicate allocations and ensure proper page sharing across forked processes. The implementation uses a per-mapping HashMap with weak references to track allocated pages.
- Adds a page cache to
AnonSharedMappingusing weak references to prevent memory leaks - Implements atomic
get_or_create_pagemethod to prevent race conditions during concurrent page faults - Updates page fault handler to use shared backing for anonymous shared mappings
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| kernel/src/mm/ucontext.rs | Added HashMap-based page cache to AnonSharedMapping with weak references and atomic get_or_create_page method |
| kernel/src/mm/fault.rs | Modified anonymous page fault handler to check for shared anonymous mappings and use cached pages via map_phys |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }; | ||
|
|
||
| // Map the shared page into current process | ||
| let flags = vma.lock_irqsave().flags(); |
There was a problem hiding this comment.
The VMA lock is acquired twice: once on line 243 for checking and once on line 258 for getting flags. Consider storing the flags during the first lock acquisition on line 243 before dropping the guard, to avoid unnecessary lock contention.
- 修复 MAP_SHARED|ANON 语义,确保匿名共享页在跨进程间真正共享, 避免了由于匿名共享页面在尚未fault的时候,fork, 接着父子进程分别为这一区域分配了不同的物理页面. - 为 AnonSharedMapping 添加页面缓存,避免重复分配同一页面 - 实现原子性的页面获取或创建机制,防止竞态条件 Signed-off-by: longjin <longjin@DragonOS.org>
6790dc7 to
2c60d25
Compare
现象: ForkTest.SharedMapping 中子进程读取到 0(预期为 1)
根因: 匿名共享映射首次缺页为各进程各自分配零页,缺少共享的后备页对象,导致 fork 后父子进程不共享同一物理页
方案:
并发安全: 在 map 锁内分配与登记,确保原子;使用 Weak 避免强引用导致的泄漏,过期项会被清理
语义: 与 Linux 对 MAP_SHARED|ANON 的共享行为一致;futex 使用的稳定身份保持不变
影响范围: 仅影响匿名共享首次缺页路径;对 MAP_PRIVATE 和文件映射无破坏性影响
Note
Use a shared anon backing with per-page cache and atomic get-or-create to map the same physical page for VM_SHARED|ANON faults, falling back to private anon mapping otherwise.
do_anonymous_page, detectVM_SHAREDanonymous VMAs, compute per-VMApgoff, atomicallyget_or_create_pagefromAnonSharedMapping, andmap_physthe shared page; otherwise fallback tomapfor private anon.AnonSharedMappinginucontext.rswith per-pageHashMap<usize, Weak<Page>>cache andget_or_create_page(pgoff)allocating viaLockedFrameAllocatorto avoid double allocation races.map_anonymous, initializeVMA.shared_anonwhenVmFlags::VM_SHARED.Page,PageFlags,PageType,HashMap,LockedFrameAllocator) for the shared-page mechanism.Written by Cursor Bugbot for commit 2c60d25. This will update automatically on new commits. Configure here.