mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
parent
924d64de8d
commit
56cc4dbe27
@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags;
|
|||||||
use crate::arch::MMArch;
|
use crate::arch::MMArch;
|
||||||
|
|
||||||
use crate::mm::kernel_mapper::KernelMapper;
|
use crate::mm::kernel_mapper::KernelMapper;
|
||||||
use crate::mm::page::PageFlags;
|
use crate::mm::page::{page_manager_lock_irasave, PageFlags};
|
||||||
use crate::mm::{
|
use crate::mm::{
|
||||||
allocator::page_frame::{
|
allocator::page_frame::{
|
||||||
allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
|
allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
|
||||||
@ -57,7 +57,11 @@ pub unsafe fn dma_dealloc(paddr: usize, vaddr: NonNull<u8>, pages: usize) -> i32
|
|||||||
flusher.flush();
|
flusher.flush();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
deallocate_page_frames(PhysPageFrame::new(PhysAddr::new(paddr)), page_count);
|
deallocate_page_frames(
|
||||||
|
PhysPageFrame::new(PhysAddr::new(paddr)),
|
||||||
|
page_count,
|
||||||
|
&mut page_manager_lock_irasave(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags;
|
|||||||
use crate::arch::MMArch;
|
use crate::arch::MMArch;
|
||||||
|
|
||||||
use crate::mm::kernel_mapper::KernelMapper;
|
use crate::mm::kernel_mapper::KernelMapper;
|
||||||
use crate::mm::page::PageFlags;
|
use crate::mm::page::{page_manager_lock_irasave, PageFlags};
|
||||||
use crate::mm::{
|
use crate::mm::{
|
||||||
allocator::page_frame::{
|
allocator::page_frame::{
|
||||||
allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
|
allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
|
||||||
@ -68,7 +68,11 @@ unsafe impl Hal for HalImpl {
|
|||||||
flusher.flush();
|
flusher.flush();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
deallocate_page_frames(PhysPageFrame::new(PhysAddr::new(paddr)), page_count);
|
deallocate_page_frames(
|
||||||
|
PhysPageFrame::new(PhysAddr::new(paddr)),
|
||||||
|
page_count,
|
||||||
|
&mut page_manager_lock_irasave(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use core::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{mm::LockedFrameAllocator, MMArch},
|
arch::{mm::LockedFrameAllocator, MMArch},
|
||||||
|
libs::spinlock::SpinLockGuard,
|
||||||
mm::{MemoryManagementArch, PhysAddr, VirtAddr},
|
mm::{MemoryManagementArch, PhysAddr, VirtAddr},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -348,8 +349,20 @@ pub unsafe fn allocate_page_frames(count: PageFrameCount) -> Option<(PhysAddr, P
|
|||||||
///
|
///
|
||||||
/// @param frame 要释放的第一个页帧
|
/// @param frame 要释放的第一个页帧
|
||||||
/// @param count 要释放的页帧数量 (必须是2的n次幂)
|
/// @param count 要释放的页帧数量 (必须是2的n次幂)
|
||||||
pub unsafe fn deallocate_page_frames(frame: PhysPageFrame, count: PageFrameCount) {
|
pub unsafe fn deallocate_page_frames(
|
||||||
|
frame: PhysPageFrame,
|
||||||
|
count: PageFrameCount,
|
||||||
|
page_manager: &mut SpinLockGuard<'_, crate::mm::page::PageManager>,
|
||||||
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
LockedFrameAllocator.free(frame.phys_address(), count);
|
LockedFrameAllocator.free(frame.phys_address(), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将已回收的物理页面对应的Page从PAGE_MANAGER中删去
|
||||||
|
let mut frame = frame;
|
||||||
|
for _ in 0..count.data() {
|
||||||
|
let paddr = frame.phys_address();
|
||||||
|
page_manager.remove_page(&paddr);
|
||||||
|
frame = frame.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
use core::{fmt::Write, sync::atomic::Ordering};
|
use core::{fmt::Write, sync::atomic::Ordering};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::MMArch, driver::serial::serial8250::send_to_default_serial8250_port,
|
arch::MMArch,
|
||||||
filesystem::procfs::kmsg::kmsg_init, libs::printk::PrintkWriter, mm::mmio_buddy::mmio_init,
|
driver::serial::serial8250::send_to_default_serial8250_port,
|
||||||
|
filesystem::procfs::kmsg::kmsg_init,
|
||||||
|
libs::printk::PrintkWriter,
|
||||||
|
mm::{mmio_buddy::mmio_init, page::page_manager_init},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::MemoryManagementArch;
|
use super::MemoryManagementArch;
|
||||||
@ -44,6 +47,8 @@ pub unsafe fn mm_init() {
|
|||||||
mmio_init();
|
mmio_init();
|
||||||
// enable KMSG
|
// enable KMSG
|
||||||
kmsg_init();
|
kmsg_init();
|
||||||
|
// enable PAGE_MANAGER
|
||||||
|
page_manager_init();
|
||||||
|
|
||||||
MM_INIT
|
MM_INIT
|
||||||
.compare_exchange(
|
.compare_exchange(
|
||||||
|
@ -6,17 +6,102 @@ use core::{
|
|||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use hashbrown::{HashMap, HashSet};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{interrupt::ipi::send_ipi, MMArch},
|
arch::{interrupt::ipi::send_ipi, MMArch},
|
||||||
exception::ipi::{IpiKind, IpiTarget},
|
exception::ipi::{IpiKind, IpiTarget},
|
||||||
kerror, kwarn,
|
kerror, kwarn,
|
||||||
|
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
allocator::page_frame::FrameAllocator, syscall::ProtFlags, MemoryManagementArch, PageTableKind,
|
allocator::page_frame::FrameAllocator, syscall::ProtFlags, ucontext::LockedVMA,
|
||||||
PhysAddr, VirtAddr,
|
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// 全局物理页信息管理器
|
||||||
|
pub static mut PAGE_MANAGER: Option<SpinLock<PageManager>> = None;
|
||||||
|
|
||||||
|
/// 初始化PAGE_MANAGER
|
||||||
|
pub fn page_manager_init() {
|
||||||
|
kinfo!("page_manager_init");
|
||||||
|
let page_manager = SpinLock::new(PageManager::new());
|
||||||
|
|
||||||
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
unsafe { PAGE_MANAGER = Some(page_manager) };
|
||||||
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
|
kinfo!("page_manager_init done");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn page_manager_lock_irasave() -> SpinLockGuard<'static, PageManager> {
|
||||||
|
unsafe { PAGE_MANAGER.as_ref().unwrap().lock_irqsave() }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 物理页管理器
|
||||||
|
pub struct PageManager {
|
||||||
|
phys2page: HashMap<PhysAddr, Page>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PageManager {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
phys2page: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self, paddr: &PhysAddr) -> &mut Page {
|
||||||
|
self.phys2page.get_mut(paddr).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, paddr: PhysAddr, page: Page) {
|
||||||
|
self.phys2page.insert(paddr, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_page(&mut self, paddr: &PhysAddr) {
|
||||||
|
self.phys2page.remove(paddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 物理页面信息
|
||||||
|
pub struct Page {
|
||||||
|
/// 映射计数
|
||||||
|
map_count: usize,
|
||||||
|
/// 是否为共享页
|
||||||
|
shared: bool,
|
||||||
|
/// 映射到当前page的VMA
|
||||||
|
anon_vma: HashSet<Arc<LockedVMA>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Page {
|
||||||
|
pub fn new(shared: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
map_count: 0,
|
||||||
|
shared,
|
||||||
|
anon_vma: HashSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 将vma加入anon_vma
|
||||||
|
pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) {
|
||||||
|
self.anon_vma.insert(vma);
|
||||||
|
self.map_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 将vma从anon_vma中删去
|
||||||
|
pub fn remove_vma(&mut self, vma: &LockedVMA) {
|
||||||
|
self.anon_vma.remove(vma);
|
||||||
|
self.map_count -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 判断当前物理页是否能被回
|
||||||
|
pub fn can_deallocate(&self) -> bool {
|
||||||
|
self.map_count == 0 && !self.shared
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PageTable<Arch> {
|
pub struct PageTable<Arch> {
|
||||||
/// 当前页表表示的虚拟地址空间的起始地址
|
/// 当前页表表示的虚拟地址空间的起始地址
|
||||||
@ -591,6 +676,8 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
|||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
let phys: PhysAddr = self.frame_allocator.allocate_one()?;
|
let phys: PhysAddr = self.frame_allocator.allocate_one()?;
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
|
page_manager_lock_irasave().insert(phys, Page::new(false));
|
||||||
return self.map_phys(virt, phys, flags);
|
return self.map_phys(virt, phys, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ use alloc::{
|
|||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
|
use ida::IdAllocator;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -24,6 +25,7 @@ use crate::{
|
|||||||
rwlock::{RwLock, RwLockWriteGuard},
|
rwlock::{RwLock, RwLockWriteGuard},
|
||||||
spinlock::{SpinLock, SpinLockGuard},
|
spinlock::{SpinLock, SpinLockGuard},
|
||||||
},
|
},
|
||||||
|
mm::page::page_manager_lock_irasave,
|
||||||
process::ProcessManager,
|
process::ProcessManager,
|
||||||
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||||
};
|
};
|
||||||
@ -50,6 +52,9 @@ use super::{
|
|||||||
// protection by setting the value to 0.
|
// protection by setting the value to 0.
|
||||||
pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536;
|
pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536;
|
||||||
|
|
||||||
|
/// LockedVMA的id分配器
|
||||||
|
static LOCKEDVMA_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, usize::MAX);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AddressSpace {
|
pub struct AddressSpace {
|
||||||
inner: RwLock<InnerAddressSpace>,
|
inner: RwLock<InnerAddressSpace>,
|
||||||
@ -464,7 +469,7 @@ impl InnerAddressSpace {
|
|||||||
let r = r.lock().region;
|
let r = r.lock().region;
|
||||||
let r = self.mappings.remove_vma(&r).unwrap();
|
let r = self.mappings.remove_vma(&r).unwrap();
|
||||||
let intersection = r.lock().region().intersect(&to_unmap).unwrap();
|
let intersection = r.lock().region().intersect(&to_unmap).unwrap();
|
||||||
let split_result = r.extract(intersection).unwrap();
|
let split_result = r.extract(intersection, &self.user_mapper.utable).unwrap();
|
||||||
|
|
||||||
// TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑
|
// TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑
|
||||||
|
|
||||||
@ -519,7 +524,9 @@ impl InnerAddressSpace {
|
|||||||
let r = self.mappings.remove_vma(&r).unwrap();
|
let r = self.mappings.remove_vma(&r).unwrap();
|
||||||
|
|
||||||
let intersection = r.lock().region().intersect(®ion).unwrap();
|
let intersection = r.lock().region().intersect(®ion).unwrap();
|
||||||
let split_result = r.extract(intersection).expect("Failed to extract VMA");
|
let split_result = r
|
||||||
|
.extract(intersection, mapper)
|
||||||
|
.expect("Failed to extract VMA");
|
||||||
|
|
||||||
if let Some(before) = split_result.prev {
|
if let Some(before) = split_result.prev {
|
||||||
self.mappings.insert_vma(before);
|
self.mappings.insert_vma(before);
|
||||||
@ -663,6 +670,7 @@ impl Drop for UserMapper {
|
|||||||
deallocate_page_frames(
|
deallocate_page_frames(
|
||||||
PhysPageFrame::new(self.utable.table().phys()),
|
PhysPageFrame::new(self.utable.table().phys()),
|
||||||
PageFrameCount::new(1),
|
PageFrameCount::new(1),
|
||||||
|
&mut page_manager_lock_irasave(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -870,17 +878,21 @@ impl Default for UserMappings {
|
|||||||
///
|
///
|
||||||
/// 备注:进行性能测试,看看SpinLock和RwLock哪个更快。
|
/// 备注:进行性能测试,看看SpinLock和RwLock哪个更快。
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LockedVMA(SpinLock<VMA>);
|
pub struct LockedVMA {
|
||||||
|
/// 用于计算哈希值,避免总是获取vma锁来计算哈希值
|
||||||
|
id: usize,
|
||||||
|
vma: SpinLock<VMA>,
|
||||||
|
}
|
||||||
|
|
||||||
impl core::hash::Hash for LockedVMA {
|
impl core::hash::Hash for LockedVMA {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.0.lock().hash(state);
|
self.id.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for LockedVMA {
|
impl PartialEq for LockedVMA {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.0.lock().eq(&other.0.lock())
|
self.id.eq(&other.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,13 +901,16 @@ impl Eq for LockedVMA {}
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl LockedVMA {
|
impl LockedVMA {
|
||||||
pub fn new(vma: VMA) -> Arc<Self> {
|
pub fn new(vma: VMA) -> Arc<Self> {
|
||||||
let r = Arc::new(Self(SpinLock::new(vma)));
|
let r = Arc::new(Self {
|
||||||
r.0.lock().self_ref = Arc::downgrade(&r);
|
id: LOCKEDVMA_ID_ALLOCATOR.alloc().unwrap(),
|
||||||
|
vma: SpinLock::new(vma),
|
||||||
|
});
|
||||||
|
r.vma.lock().self_ref = Arc::downgrade(&r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lock(&self) -> SpinLockGuard<VMA> {
|
pub fn lock(&self) -> SpinLockGuard<VMA> {
|
||||||
return self.0.lock();
|
return self.vma.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 调整当前VMA的页面的标志位
|
/// 调整当前VMA的页面的标志位
|
||||||
@ -933,19 +948,28 @@ impl LockedVMA {
|
|||||||
|
|
||||||
let mut guard = self.lock();
|
let mut guard = self.lock();
|
||||||
assert!(guard.mapped);
|
assert!(guard.mapped);
|
||||||
|
|
||||||
|
// 获取物理页的anon_vma的守卫
|
||||||
|
let mut anon_vma_guard: SpinLockGuard<'_, crate::mm::page::PageManager> =
|
||||||
|
page_manager_lock_irasave();
|
||||||
for page in guard.region.pages() {
|
for page in guard.region.pages() {
|
||||||
let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) }
|
let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) }
|
||||||
.expect("Failed to unmap, beacuse of some page is not mapped");
|
.expect("Failed to unmap, beacuse of some page is not mapped");
|
||||||
|
|
||||||
// todo: 获取物理页的anon_vma的守卫
|
// 从anon_vma中删除当前VMA
|
||||||
|
let page = anon_vma_guard.get_mut(&paddr);
|
||||||
|
page.remove_vma(self);
|
||||||
|
|
||||||
// todo: 从anon_vma中删除当前VMA
|
// 如果物理页的anon_vma链表长度为0并且不是共享页,则释放物理页.
|
||||||
|
if page.can_deallocate() {
|
||||||
// todo: 如果物理页的anon_vma链表长度为0,则释放物理页.
|
unsafe {
|
||||||
|
deallocate_page_frames(
|
||||||
// 目前由于还没有实现共享页,所以直接释放物理页也没问题。
|
PhysPageFrame::new(paddr),
|
||||||
// 但是在实现共享页之后,就不能直接释放物理页了,需要在anon_vma链表长度为0的时候才能释放物理页
|
PageFrameCount::new(1),
|
||||||
unsafe { deallocate_page_frames(PhysPageFrame::new(paddr), PageFrameCount::new(1)) };
|
&mut anon_vma_guard,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
flusher.consume(flush);
|
flusher.consume(flush);
|
||||||
}
|
}
|
||||||
@ -953,7 +977,7 @@ impl LockedVMA {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn mapped(&self) -> bool {
|
pub fn mapped(&self) -> bool {
|
||||||
return self.0.lock().mapped;
|
return self.vma.lock().mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 将当前VMA进行切分,切分成3个VMA,分别是:
|
/// 将当前VMA进行切分,切分成3个VMA,分别是:
|
||||||
@ -961,7 +985,7 @@ impl LockedVMA {
|
|||||||
/// 1. 前面的VMA,如果没有则为None
|
/// 1. 前面的VMA,如果没有则为None
|
||||||
/// 2. 中间的VMA,也就是传入的Region
|
/// 2. 中间的VMA,也就是传入的Region
|
||||||
/// 3. 后面的VMA,如果没有则为None
|
/// 3. 后面的VMA,如果没有则为None
|
||||||
pub fn extract(&self, region: VirtRegion) -> Option<VMASplitResult> {
|
pub fn extract(&self, region: VirtRegion, utable: &PageMapper) -> Option<VMASplitResult> {
|
||||||
assert!(region.start().check_aligned(MMArch::PAGE_SIZE));
|
assert!(region.start().check_aligned(MMArch::PAGE_SIZE));
|
||||||
assert!(region.end().check_aligned(MMArch::PAGE_SIZE));
|
assert!(region.end().check_aligned(MMArch::PAGE_SIZE));
|
||||||
|
|
||||||
@ -1005,9 +1029,29 @@ impl LockedVMA {
|
|||||||
vma
|
vma
|
||||||
});
|
});
|
||||||
|
|
||||||
guard.region = region;
|
// 重新设置before、after这两个VMA里面的物理页的anon_vma
|
||||||
|
let mut anon_vma_guard = page_manager_lock_irasave();
|
||||||
|
if let Some(before) = before.clone() {
|
||||||
|
let virt_iter = before.lock().region.iter_pages();
|
||||||
|
for frame in virt_iter {
|
||||||
|
let paddr = utable.translate(frame.virt_address()).unwrap().0;
|
||||||
|
let page = anon_vma_guard.get_mut(&paddr);
|
||||||
|
page.insert_vma(before.clone());
|
||||||
|
page.remove_vma(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: 重新设置before、after这两个VMA里面的物理页的anon_vma
|
if let Some(after) = after.clone() {
|
||||||
|
let virt_iter = after.lock().region.iter_pages();
|
||||||
|
for frame in virt_iter {
|
||||||
|
let paddr = utable.translate(frame.virt_address()).unwrap().0;
|
||||||
|
let page = anon_vma_guard.get_mut(&paddr);
|
||||||
|
page.insert_vma(after.clone());
|
||||||
|
page.remove_vma(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guard.region = region;
|
||||||
|
|
||||||
return Some(VMASplitResult::new(
|
return Some(VMASplitResult::new(
|
||||||
before,
|
before,
|
||||||
@ -1017,6 +1061,12 @@ impl LockedVMA {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for LockedVMA {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
LOCKEDVMA_ID_ALLOCATOR.free(self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// VMA切分结果
|
/// VMA切分结果
|
||||||
pub struct VMASplitResult {
|
pub struct VMASplitResult {
|
||||||
pub prev: Option<Arc<LockedVMA>>,
|
pub prev: Option<Arc<LockedVMA>>,
|
||||||
@ -1194,27 +1244,22 @@ impl VMA {
|
|||||||
mapper: &mut PageMapper,
|
mapper: &mut PageMapper,
|
||||||
mut flusher: impl Flusher<MMArch>,
|
mut flusher: impl Flusher<MMArch>,
|
||||||
) -> Result<Arc<LockedVMA>, SystemError> {
|
) -> Result<Arc<LockedVMA>, SystemError> {
|
||||||
{
|
let mut cur_phy = phys;
|
||||||
let mut cur_phy = phys;
|
let mut cur_dest = destination;
|
||||||
let mut cur_dest = destination;
|
|
||||||
|
|
||||||
for _ in 0..count.data() {
|
for _ in 0..count.data() {
|
||||||
// 将物理页帧映射到虚拟页帧
|
// 将物理页帧映射到虚拟页帧
|
||||||
let r = unsafe {
|
let r =
|
||||||
mapper.map_phys(cur_dest.virt_address(), cur_phy.phys_address(), flags)
|
unsafe { mapper.map_phys(cur_dest.virt_address(), cur_phy.phys_address(), flags) }
|
||||||
}
|
.expect("Failed to map phys, may be OOM error");
|
||||||
.expect("Failed to map phys, may be OOM error");
|
|
||||||
|
|
||||||
// todo: 增加OOM处理
|
// todo: 增加OOM处理
|
||||||
|
|
||||||
// todo: 将VMA加入到anon_vma中
|
// 刷新TLB
|
||||||
|
flusher.consume(r);
|
||||||
|
|
||||||
// 刷新TLB
|
cur_phy = cur_phy.next();
|
||||||
flusher.consume(r);
|
cur_dest = cur_dest.next();
|
||||||
|
|
||||||
cur_phy = cur_phy.next();
|
|
||||||
cur_dest = cur_dest.next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let r: Arc<LockedVMA> = LockedVMA::new(VMA {
|
let r: Arc<LockedVMA> = LockedVMA::new(VMA {
|
||||||
@ -1226,6 +1271,17 @@ impl VMA {
|
|||||||
self_ref: Weak::default(),
|
self_ref: Weak::default(),
|
||||||
provider: Provider::Allocated,
|
provider: Provider::Allocated,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 将VMA加入到anon_vma中
|
||||||
|
let mut anon_vma_guard = page_manager_lock_irasave();
|
||||||
|
cur_phy = phys;
|
||||||
|
for _ in 0..count.data() {
|
||||||
|
let paddr = cur_phy.phys_address();
|
||||||
|
let page = anon_vma_guard.get_mut(&paddr);
|
||||||
|
page.insert_vma(r.clone());
|
||||||
|
cur_phy = cur_phy.next();
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(r);
|
return Ok(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,7 +1314,6 @@ impl VMA {
|
|||||||
// );
|
// );
|
||||||
let r = unsafe { mapper.map(cur_dest.virt_address(), flags) }
|
let r = unsafe { mapper.map(cur_dest.virt_address(), flags) }
|
||||||
.expect("Failed to map zero, may be OOM error");
|
.expect("Failed to map zero, may be OOM error");
|
||||||
// todo: 将VMA加入到anon_vma中
|
|
||||||
// todo: 增加OOM处理
|
// todo: 增加OOM处理
|
||||||
|
|
||||||
// 稍后再刷新TLB,这里取消刷新
|
// 稍后再刷新TLB,这里取消刷新
|
||||||
@ -1280,12 +1335,18 @@ impl VMA {
|
|||||||
drop(flusher);
|
drop(flusher);
|
||||||
// kdebug!("VMA::zeroed: flusher dropped");
|
// kdebug!("VMA::zeroed: flusher dropped");
|
||||||
|
|
||||||
// 清空这些内存
|
// 清空这些内存并将VMA加入到anon_vma中
|
||||||
|
let mut anon_vma_guard = page_manager_lock_irasave();
|
||||||
let virt_iter: VirtPageFrameIter =
|
let virt_iter: VirtPageFrameIter =
|
||||||
VirtPageFrameIter::new(destination, destination.add(page_count));
|
VirtPageFrameIter::new(destination, destination.add(page_count));
|
||||||
for frame in virt_iter {
|
for frame in virt_iter {
|
||||||
let paddr = mapper.translate(frame.virt_address()).unwrap().0;
|
let paddr = mapper.translate(frame.virt_address()).unwrap().0;
|
||||||
|
|
||||||
|
// 将VMA加入到anon_vma
|
||||||
|
let page = anon_vma_guard.get_mut(&paddr);
|
||||||
|
page.insert_vma(r.clone());
|
||||||
|
|
||||||
|
// 清空内存
|
||||||
unsafe {
|
unsafe {
|
||||||
let vaddr = MMArch::phys_2_virt(paddr).unwrap();
|
let vaddr = MMArch::phys_2_virt(paddr).unwrap();
|
||||||
MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE);
|
MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user