mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 18:03:25 +00:00
Optimize the clear procedure of the page table
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
4fa0e6334b
commit
8f50391a4e
@ -339,10 +339,8 @@ impl Vmar_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn clear_vm_space(&self) {
|
fn clear_vm_space(&self) {
|
||||||
let start = ROOT_VMAR_LOWEST_ADDR;
|
let mut cursor = self.vm_space.cursor_mut(&(0..ROOT_VMAR_CAP_ADDR)).unwrap();
|
||||||
let end = ROOT_VMAR_CAP_ADDR;
|
cursor.unmap(ROOT_VMAR_CAP_ADDR);
|
||||||
let mut cursor = self.vm_space.cursor_mut(&(start..end)).unwrap();
|
|
||||||
cursor.unmap(end - start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(&self, range: Range<usize>) -> Result<()> {
|
pub fn destroy(&self, range: Range<usize>) -> Result<()> {
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
//! table cursor should add additional entry point checks to prevent these defined
|
//! table cursor should add additional entry point checks to prevent these defined
|
||||||
//! behaviors if they are not wanted.
|
//! behaviors if they are not wanted.
|
||||||
|
|
||||||
use core::{any::TypeId, marker::PhantomData, ops::Range};
|
use core::{any::TypeId, marker::PhantomData, mem::ManuallyDrop, ops::Range};
|
||||||
|
|
||||||
use align_ext::AlignExt;
|
use align_ext::AlignExt;
|
||||||
|
|
||||||
@ -74,7 +74,10 @@ use super::{
|
|||||||
PageTableMode, PageTableNode, PagingConstsTrait, PagingLevel, UserMode,
|
PageTableMode, PageTableNode, PagingConstsTrait, PagingLevel, UserMode,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
mm::{page::DynPage, Paddr, PageProperty, Vaddr},
|
mm::{
|
||||||
|
page::{meta::PageTablePageMeta, DynPage, Page},
|
||||||
|
Paddr, PageProperty, Vaddr,
|
||||||
|
},
|
||||||
task::{disable_preempt, DisabledPreemptGuard},
|
task::{disable_preempt, DisabledPreemptGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -89,6 +92,9 @@ pub enum PageTableItem {
|
|||||||
page: DynPage,
|
page: DynPage,
|
||||||
prop: PageProperty,
|
prop: PageProperty,
|
||||||
},
|
},
|
||||||
|
PageTableNode {
|
||||||
|
page: DynPage,
|
||||||
|
},
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
MappedUntracked {
|
MappedUntracked {
|
||||||
va: Vaddr,
|
va: Vaddr,
|
||||||
@ -587,8 +593,21 @@ where
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Level down if the current PTE points to a page table.
|
if self.0.va % page_size::<C>(self.0.level) != 0
|
||||||
if !cur_pte.is_last(self.0.level) {
|
|| self.0.va + page_size::<C>(self.0.level) > end
|
||||||
|
{
|
||||||
|
if !is_tracked {
|
||||||
|
// Level down if we are removing part of a huge untracked page.
|
||||||
|
self.level_down_split();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if cur_pte.is_last(self.0.level) {
|
||||||
|
panic!("removing part of a huge page");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Level down if the current PTE points to a page table and we cannot
|
||||||
|
// unmap this page table node entirely.
|
||||||
self.0.level_down();
|
self.0.level_down();
|
||||||
|
|
||||||
// We have got down a level. If there's no mapped PTEs in
|
// We have got down a level. If there's no mapped PTEs in
|
||||||
@ -602,22 +621,9 @@ where
|
|||||||
self.0.level_up();
|
self.0.level_up();
|
||||||
self.0.move_forward();
|
self.0.move_forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Level down if we are removing part of a huge untracked page.
|
|
||||||
if self.0.va % page_size::<C>(self.0.level) != 0
|
|
||||||
|| self.0.va + page_size::<C>(self.0.level) > end
|
|
||||||
{
|
|
||||||
if !is_tracked {
|
|
||||||
self.level_down_split();
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
panic!("removing part of a huge page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmap the current page and return it.
|
// Unmap the current page and return it.
|
||||||
let idx = self.0.cur_idx();
|
let idx = self.0.cur_idx();
|
||||||
let ret = self
|
let ret = self
|
||||||
@ -640,7 +646,12 @@ where
|
|||||||
len: ret_page_size,
|
len: ret_page_size,
|
||||||
prop,
|
prop,
|
||||||
},
|
},
|
||||||
Child::None | Child::PageTable(_) => unreachable!(),
|
Child::PageTable(node) => {
|
||||||
|
let node = ManuallyDrop::new(node);
|
||||||
|
let page = Page::<PageTablePageMeta<E, C>>::from_raw(node.paddr());
|
||||||
|
PageTableItem::PageTableNode { page: page.into() }
|
||||||
|
}
|
||||||
|
Child::None => unreachable!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +333,15 @@ impl CursorMut<'_, '_> {
|
|||||||
self.flusher
|
self.flusher
|
||||||
.issue_tlb_flush_with(TlbFlushOp::Address(va), page);
|
.issue_tlb_flush_with(TlbFlushOp::Address(va), page);
|
||||||
}
|
}
|
||||||
|
PageTableItem::PageTableNode { page } => {
|
||||||
|
if !self.flusher.need_remote_flush() && tlb_prefer_flush_all {
|
||||||
|
// Only on single-CPU cases we can drop the page immediately before flushing.
|
||||||
|
drop(page);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// If we unmap an entire page table node, we prefer directly flushing all TLBs.
|
||||||
|
self.flusher.issue_tlb_flush_with(TlbFlushOp::All, page);
|
||||||
|
}
|
||||||
PageTableItem::NotMapped { .. } => {
|
PageTableItem::NotMapped { .. } => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -461,6 +470,9 @@ impl TryFrom<PageTableItem> for VmItem {
|
|||||||
PageTableItem::MappedUntracked { .. } => {
|
PageTableItem::MappedUntracked { .. } => {
|
||||||
Err("found untracked memory mapped into `VmSpace`")
|
Err("found untracked memory mapped into `VmSpace`")
|
||||||
}
|
}
|
||||||
|
PageTableItem::PageTableNode { .. } => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user