-
Notifications
You must be signed in to change notification settings - Fork 17
feat: support COW #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- support x86_64 refactor: improve page fault handling and page management - Fix whitespace in PageFaultErrorCode flags - Simplify page fault COW logic - Rename page ref count methods for clarity - Move page copy logic to Page struct - Add better documentation for page management refactor: improve copy_with_cow - use `insert_area` - add `MemorySet` patch fmt: fmt chore: update test workflow dependencies - Add memory_set crate dependency - Add memory_addr crate dependency refactor: copy_with_cow and add support alloc contiguous pages - Remove myself git dependencies for memory_set and memory_addr - Update Cargo.toml and Cargo.lock - Adjust page allocation to support contiguous pages - Improve COW handling with page size parameter
e35db1c
to
4468909
Compare
- Remove Arc and FrameTracker in favor of atomic ref counting - Add frameinfo module for physical frame management - Simplify COW fault handling with direct frame operations - Update backend allocator to use new frame tracking system - only support with x86
- Remove redundant backend matching in fork - Reorganize COW fault handling comments - Clean up page table update flow
- Replace ok() with expect() for protect/map operations - Simplify page copy with copy_nonoverlapping - Add physical address validation in phys_to_pfn
Update
For huge pages, the start address should be used to access the large table ProblemProblems were found in both loongarch64 and aarch64. loongarch64:
aarch64:
LoongArchIn
I made some changes: mingzi47/page_table_multiarch@cc5796c AArch64TLB FlushThis code is taken from the arm documentation STR X1, [X5] // Write to translation table entry
DSB ISH // Barrier instructions - not covered in this guide
TLBI VAAE1IS , X0 // Invalidate VA specified by X0, in EL0/1
// virtual address space for all ASIDs
DSB ISH // Barrier instructions - not covered in this guide
ISB // Synchronize context on this processor The description of the
Code in the current #[inline]
fn flush_tlb(vaddr: Option<memory_addr::VirtAddr>) {
unsafe {
if let Some(vaddr) = vaddr {
// TLB Invalidate by VA, All ASID, EL1, Inner Shareable
asm!("tlbi vaae1is, {}; dsb sy; isb", in(reg) vaddr.as_usize())
} else {
// TLB Invalidate by VMID, All at stage 1, EL1
asm!("tlbi vmalle1; dsb sy; isb")
}
}
} Code in the #[inline]
pub fn flush_vaddr(vaddr: VirtAddr) {
unsafe {
core::arch::asm!(
"
tlbi vaale1is, {}
dsb sy
isb
",
in(reg) ((vaddr.raw() >> 12) & 0xFFFF_FFFF_FFFF)
)
}
} For testing purposes, I made a few changes. mingzi47/page_table_multiarch@61b110f The kernel accesses user memoryThis happens in Accessing a stack frame without the https://github.com/Starry-OS/axsignal/blob/main/src/api/thread.rs#L70-L90 let sp = if stack.disabled() || !action.flags.contains(SignalActionFlags::ONSTACK) {
tf.sp()
} else {
stack.sp
};
drop(stack);
// TODO: check if stack is large enough
let aligned_sp = (sp - layout.size()) & !(layout.align() - 1);
let frame_ptr = aligned_sp as *mut SignalFrame;
// SAFETY: pointer is valid
let frame = unsafe { &mut *frame_ptr };
*frame = SignalFrame {
ucontext: UContext::new(tf, restore_blocked),
siginfo: sig.clone(),
tf: *tf,
}; |
…upport - Renamed `populate_area` to `ensure_region_mapped` - Refactored `handle_cow_fault` to take a mutable page table reference
Port the changes of huge page support(See #49) |
- Use align from backend for page iteration - Remove TODO and FIXME comments - Simplify page iteration logic
- Replace direct frame info access with FrameRefTable API - Remove redundant align parameter from protect() - Rename ensure_region_mapped to populate_area - Simplify COW handling logic - Consolidate frame info operations into FrameRefTable struct
…ered by the specified access interval
- Add conditional compilation for COW feature - Refactor clone_or_err into try_clone with COW support - Update frame allocation/deallocation logic - Move frameinfo module behind feature flag - Add new cow feature to Cargo.toml
updateAdd support for the COW feature in
testfn populate_area(mut start: usize, size: usize, areas: Vec<(usize, usize)>) {
let end = start + size;
for area in areas.iter() {
if start >= area.1 {
continue;
}
if start < area.0 {
panic!("area is not fully mapped")
}
start = area.1;
if start >= end {
return;
}
}
panic!("area is not fully mapped");
}
#[test]
fn test_populate_area_success() {
// 连续覆盖 [1000, 1300)
let areas = vec![(1000, 1100), (1100, 1200), (1200, 1300)];
populate_area(1000, 300, areas);
}
#[test]
#[should_panic(expected = "area is not fully mapped")]
fn test_populate_area_with_hole() {
// 缺失 [1100, 1200)
let areas = vec![(1000, 1100), (1200, 1300)];
populate_area(1000, 300, areas);
}
#[test]
#[should_panic(expected = "area is not fully mapped")]
fn test_populate_area_not_starting_correctly() {
// 开始位置是 1000,但第一个区域从 1100 开始
let areas = vec![(1100, 1300)];
populate_area(1000, 300, areas);
}
#[test]
#[should_panic(expected = "area is not fully mapped")]
fn test_populate_area_partial_coverage() {
// 覆盖只到 1250,目标是 1300
let areas = vec![(1000, 1100), (1100, 1250)];
populate_area(1000, 300, areas);
} |
- Consolidate COW fault handling logic - Replace LazyInit with lazy_static for frame table - Remove redundant frame table initialization - Clean up memory area copying logic
And fix the clippy warning(See https://github.com/oscomp/arceos/actions/runs/15662503512/job/44122261109) |
- Move PageIterWrapper to root module - Clean up unused imports - Simplify cow feature logic - Fix docstring alignment - Remove redundant page size handling
* Add basc COW - support x86_64 refactor: improve page fault handling and page management - Fix whitespace in PageFaultErrorCode flags - Simplify page fault COW logic - Rename page ref count methods for clarity - Move page copy logic to Page struct - Add better documentation for page management refactor: improve copy_with_cow - use `insert_area` - add `MemorySet` patch fmt: fmt chore: update test workflow dependencies - Add memory_set crate dependency - Add memory_addr crate dependency refactor: copy_with_cow and add support alloc contiguous pages - Remove myself git dependencies for memory_set and memory_addr - Update Cargo.toml and Cargo.lock - Adjust page allocation to support contiguous pages - Improve COW handling with page size parameter * Squash merge cow-backend into cow * refactor: replace Arc-based frame tracking with frame info table - Remove Arc and FrameTracker in favor of atomic ref counting - Add frameinfo module for physical frame management - Simplify COW fault handling with direct frame operations - Update backend allocator to use new frame tracking system - only support with x86 * refactor: simplify address space handling logic - Remove redundant backend matching in fork - Reorganize COW fault handling comments - Clean up page table update flow * refactor: improve memory management safety - Replace ok() with expect() for protect/map operations - Simplify page copy with copy_nonoverlapping - Add physical address validation in phys_to_pfn * chore: clean up * refactor: Rename `populate_area` to `ensure_region_mapped` with COW support - Renamed `populate_area` to `ensure_region_mapped` - Refactored `handle_cow_fault` to take a mutable page table reference * chore: Modify according to comment * refactor: replace PageIter4K with PageIterWrapper in AddrSpace - Use align from backend for page iteration - Remove TODO and FIXME comments - Simplify page iteration logic * refactor: simplify frame reference counting - Replace direct frame info access with FrameRefTable API - Remove redundant align parameter from protect() - Rename ensure_region_mapped to populate_area - Simplify COW handling logic - Consolidate frame info operations into FrameRefTable struct * refactor: (populate_area) use a iterator to walk through the area covered by the specified access interval * feat: add COW feature for memory management - Add conditional compilation for COW feature - Refactor clone_or_err into try_clone with COW support - Update frame allocation/deallocation logic - Move frameinfo module behind feature flag - Add new cow feature to Cargo.toml * refactor: simplify COW handling and frame table initialization - Consolidate COW fault handling logic - Replace LazyInit with lazy_static for frame table - Remove redundant frame table initialization - Clean up memory area copying logic * refactor: reorganize memory management modules - Move PageIterWrapper to root module - Clean up unused imports - Simplify cow feature logic - Fix docstring alignment - Remove redundant page size handling * doc: fix doc link
* Add basc COW - support x86_64 refactor: improve page fault handling and page management - Fix whitespace in PageFaultErrorCode flags - Simplify page fault COW logic - Rename page ref count methods for clarity - Move page copy logic to Page struct - Add better documentation for page management refactor: improve copy_with_cow - use `insert_area` - add `MemorySet` patch fmt: fmt chore: update test workflow dependencies - Add memory_set crate dependency - Add memory_addr crate dependency refactor: copy_with_cow and add support alloc contiguous pages - Remove myself git dependencies for memory_set and memory_addr - Update Cargo.toml and Cargo.lock - Adjust page allocation to support contiguous pages - Improve COW handling with page size parameter * Squash merge cow-backend into cow * refactor: replace Arc-based frame tracking with frame info table - Remove Arc and FrameTracker in favor of atomic ref counting - Add frameinfo module for physical frame management - Simplify COW fault handling with direct frame operations - Update backend allocator to use new frame tracking system - only support with x86 * refactor: simplify address space handling logic - Remove redundant backend matching in fork - Reorganize COW fault handling comments - Clean up page table update flow * refactor: improve memory management safety - Replace ok() with expect() for protect/map operations - Simplify page copy with copy_nonoverlapping - Add physical address validation in phys_to_pfn * chore: clean up * refactor: Rename `populate_area` to `ensure_region_mapped` with COW support - Renamed `populate_area` to `ensure_region_mapped` - Refactored `handle_cow_fault` to take a mutable page table reference * chore: Modify according to comment * refactor: replace PageIter4K with PageIterWrapper in AddrSpace - Use align from backend for page iteration - Remove TODO and FIXME comments - Simplify page iteration logic * refactor: simplify frame reference counting - Replace direct frame info access with FrameRefTable API - Remove redundant align parameter from protect() - Rename ensure_region_mapped to populate_area - Simplify COW handling logic - Consolidate frame info operations into FrameRefTable struct * refactor: (populate_area) use a iterator to walk through the area covered by the specified access interval * feat: add COW feature for memory management - Add conditional compilation for COW feature - Refactor clone_or_err into try_clone with COW support - Update frame allocation/deallocation logic - Move frameinfo module behind feature flag - Add new cow feature to Cargo.toml * refactor: simplify COW handling and frame table initialization - Consolidate COW fault handling logic - Replace LazyInit with lazy_static for frame table - Remove redundant frame table initialization - Clean up memory area copying logic * refactor: reorganize memory management modules - Move PageIterWrapper to root module - Clean up unused imports - Simplify cow feature logic - Fix docstring alignment - Remove redundant page size handling * doc: fix doc link
* Add basc COW - support x86_64 refactor: improve page fault handling and page management - Fix whitespace in PageFaultErrorCode flags - Simplify page fault COW logic - Rename page ref count methods for clarity - Move page copy logic to Page struct - Add better documentation for page management refactor: improve copy_with_cow - use `insert_area` - add `MemorySet` patch fmt: fmt chore: update test workflow dependencies - Add memory_set crate dependency - Add memory_addr crate dependency refactor: copy_with_cow and add support alloc contiguous pages - Remove myself git dependencies for memory_set and memory_addr - Update Cargo.toml and Cargo.lock - Adjust page allocation to support contiguous pages - Improve COW handling with page size parameter * Squash merge cow-backend into cow * refactor: replace Arc-based frame tracking with frame info table - Remove Arc and FrameTracker in favor of atomic ref counting - Add frameinfo module for physical frame management - Simplify COW fault handling with direct frame operations - Update backend allocator to use new frame tracking system - only support with x86 * refactor: simplify address space handling logic - Remove redundant backend matching in fork - Reorganize COW fault handling comments - Clean up page table update flow * refactor: improve memory management safety - Replace ok() with expect() for protect/map operations - Simplify page copy with copy_nonoverlapping - Add physical address validation in phys_to_pfn * chore: clean up * refactor: Rename `populate_area` to `ensure_region_mapped` with COW support - Renamed `populate_area` to `ensure_region_mapped` - Refactored `handle_cow_fault` to take a mutable page table reference * chore: Modify according to comment * refactor: replace PageIter4K with PageIterWrapper in AddrSpace - Use align from backend for page iteration - Remove TODO and FIXME comments - Simplify page iteration logic * refactor: simplify frame reference counting - Replace direct frame info access with FrameRefTable API - Remove redundant align parameter from protect() - Rename ensure_region_mapped to populate_area - Simplify COW handling logic - Consolidate frame info operations into FrameRefTable struct * refactor: (populate_area) use a iterator to walk through the area covered by the specified access interval * feat: add COW feature for memory management - Add conditional compilation for COW feature - Refactor clone_or_err into try_clone with COW support - Update frame allocation/deallocation logic - Move frameinfo module behind feature flag - Add new cow feature to Cargo.toml * refactor: simplify COW handling and frame table initialization - Consolidate COW fault handling logic - Replace LazyInit with lazy_static for frame table - Remove redundant frame table initialization - Clean up memory area copying logic * refactor: reorganize memory management modules - Move PageIterWrapper to root module - Clean up unused imports - Simplify cow feature logic - Fix docstring alignment - Remove redundant page size handling * doc: fix doc link
fn err_code_to_flags(err_code: u64) -> Result<MappingFlags, u64> { | ||
let code = PageFaultErrorCode::from_bits_truncate(err_code); | ||
let reserved_bits = (PageFaultErrorCode::CAUSED_BY_WRITE | ||
| PageFaultErrorCode::PROTECTION_VIOLATION |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mingzi47 Sorry to bother you, I was wondering if this change is necessary? Because I'm porting these to axcpu
.
* Add basc COW - support x86_64 refactor: improve page fault handling and page management - Fix whitespace in PageFaultErrorCode flags - Simplify page fault COW logic - Rename page ref count methods for clarity - Move page copy logic to Page struct - Add better documentation for page management refactor: improve copy_with_cow - use `insert_area` - add `MemorySet` patch fmt: fmt chore: update test workflow dependencies - Add memory_set crate dependency - Add memory_addr crate dependency refactor: copy_with_cow and add support alloc contiguous pages - Remove myself git dependencies for memory_set and memory_addr - Update Cargo.toml and Cargo.lock - Adjust page allocation to support contiguous pages - Improve COW handling with page size parameter * Squash merge cow-backend into cow * refactor: replace Arc-based frame tracking with frame info table - Remove Arc and FrameTracker in favor of atomic ref counting - Add frameinfo module for physical frame management - Simplify COW fault handling with direct frame operations - Update backend allocator to use new frame tracking system - only support with x86 * refactor: simplify address space handling logic - Remove redundant backend matching in fork - Reorganize COW fault handling comments - Clean up page table update flow * refactor: improve memory management safety - Replace ok() with expect() for protect/map operations - Simplify page copy with copy_nonoverlapping - Add physical address validation in phys_to_pfn * chore: clean up * refactor: Rename `populate_area` to `ensure_region_mapped` with COW support - Renamed `populate_area` to `ensure_region_mapped` - Refactored `handle_cow_fault` to take a mutable page table reference * chore: Modify according to comment * refactor: replace PageIter4K with PageIterWrapper in AddrSpace - Use align from backend for page iteration - Remove TODO and FIXME comments - Simplify page iteration logic * refactor: simplify frame reference counting - Replace direct frame info access with FrameRefTable API - Remove redundant align parameter from protect() - Rename ensure_region_mapped to populate_area - Simplify COW handling logic - Consolidate frame info operations into FrameRefTable struct * refactor: (populate_area) use a iterator to walk through the area covered by the specified access interval * feat: add COW feature for memory management - Add conditional compilation for COW feature - Refactor clone_or_err into try_clone with COW support - Update frame allocation/deallocation logic - Move frameinfo module behind feature flag - Add new cow feature to Cargo.toml * refactor: simplify COW handling and frame table initialization - Consolidate COW fault handling logic - Replace LazyInit with lazy_static for frame table - Remove redundant frame table initialization - Clean up memory area copying logic * refactor: reorganize memory management modules - Move PageIterWrapper to root module - Clean up unused imports - Simplify cow feature logic - Fix docstring alignment - Remove redundant page size handling * doc: fix doc link
Description
The COW mechanism for fork
Implementation Details
目前存在两种方案,当前 pr 使用的是方案1。
方案 1
将在
Backend
中管理当前 vma 的物理页帧的引用计数,使用Arc
完成计数。这种方案使用了类似
Arc<Mutex<Vec<Mutex<GlobalPage>>>
的结构来管理分配的页。目前的实现存在一些问题(边界问题)。优点:
使用 RAII 的方式管理引用计数
查找页面时,没有全局的锁
缺点:
需要额外为
Backend
实现clone
, 为了内部可变性,对Vec
使用Arc<Mutex>
进行了包裹,因此默认的clone
并不能使GlobalPage
的引用计数增加。为
Backend::Alloc
中增加了复杂的结构。方案 2
使用全局的页管理器来管理物理页帧的引用计数,使用原子变量计数。
https://github.com/mingzi47/arceos/tree/cow-global
优点:
相对方案 2,实现更简单
全部页放在一块,没有其他地方引用,内存占用更小
缺点:
全局大锁
手动进行引用计数
How to Test
Here is a log of copying
Addrspace
whenfork
:Only physical pages are alloced for the root and intermediate page tables