-
Notifications
You must be signed in to change notification settings - Fork 15
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 processorThe 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
Addrspacewhenfork:Only physical pages are alloced for the root and intermediate page tables