mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-30 14:33:56 +00:00
Do some miscellaneous page table cleanups
This commit is contained in:
@ -2,8 +2,6 @@
|
||||
|
||||
//! This module provides accessors to the page table entries in a node.
|
||||
|
||||
use core::mem::ManuallyDrop;
|
||||
|
||||
use super::{Child, ChildRef, PageTableEntryTrait, PageTableGuard, PageTableNode};
|
||||
use crate::{
|
||||
mm::{
|
||||
@ -78,8 +76,8 @@ impl<'a, 'rcu, C: PageTableConfig> Entry<'a, 'rcu, C> {
|
||||
// SAFETY:
|
||||
// 1. The index is within the bounds.
|
||||
// 2. We replace the PTE with a new one, which differs only in
|
||||
// `PageProperty`, so the level still matches the current
|
||||
// page table node.
|
||||
// `PageProperty`, so it's in `C` and at the correct paging level.
|
||||
// 3. The child is still owned by the page table node.
|
||||
unsafe { self.node.write_pte(self.idx, self.pte) };
|
||||
}
|
||||
|
||||
@ -117,7 +115,8 @@ impl<'a, 'rcu, C: PageTableConfig> Entry<'a, 'rcu, C> {
|
||||
|
||||
// SAFETY:
|
||||
// 1. The index is within the bounds.
|
||||
// 2. The new PTE is a valid child whose level matches the current page table node.
|
||||
// 2. The new PTE is a child in `C` and at the correct paging level.
|
||||
// 3. The ownership of the child is passed to the page table node.
|
||||
unsafe { self.node.write_pte(self.idx, new_pte) };
|
||||
|
||||
self.pte = new_pte;
|
||||
@ -138,28 +137,28 @@ impl<'a, 'rcu, C: PageTableConfig> Entry<'a, 'rcu, C> {
|
||||
}
|
||||
|
||||
let level = self.node.level();
|
||||
let new_page = PageTableNode::<C>::alloc(level - 1);
|
||||
let new_page = RcuDrop::new(PageTableNode::<C>::alloc(level - 1));
|
||||
|
||||
let paddr = new_page.start_paddr();
|
||||
let _ = ManuallyDrop::new(new_page.borrow().lock(guard));
|
||||
// SAFETY: The page table won't be dropped before the RCU grace period
|
||||
// ends, so it outlives `'rcu`.
|
||||
let pt_ref = unsafe { PageTableNodeRef::borrow_paddr(paddr) };
|
||||
|
||||
// Lock before writing the PTE, so no one else can operate on it.
|
||||
let pt_lock_guard = pt_ref.lock(guard);
|
||||
|
||||
// SAFETY:
|
||||
// 1. The index is within the bounds.
|
||||
// 2. The new PTE is a valid child whose level matches the current page table node.
|
||||
// 2. The new PTE is a child in `C` and at the correct paging level.
|
||||
// 3. The ownership of the child is passed to the page table node.
|
||||
unsafe {
|
||||
self.node.write_pte(
|
||||
self.idx,
|
||||
Child::PageTable(RcuDrop::new(new_page)).into_pte(),
|
||||
)
|
||||
self.node
|
||||
.write_pte(self.idx, Child::PageTable(new_page).into_pte())
|
||||
};
|
||||
|
||||
*self.node.nr_children_mut() += 1;
|
||||
|
||||
// SAFETY: The page table won't be dropped before the RCU grace period
|
||||
// ends, so it outlives `'rcu`.
|
||||
let pt_ref = unsafe { PageTableNodeRef::borrow_paddr(paddr) };
|
||||
// SAFETY: The node is locked and there are no other guards.
|
||||
Some(unsafe { pt_ref.make_guard_unchecked(guard) })
|
||||
Some(pt_lock_guard)
|
||||
}
|
||||
|
||||
/// Splits the entry to smaller pages if it maps to a huge page.
|
||||
@ -183,8 +182,15 @@ impl<'a, 'rcu, C: PageTableConfig> Entry<'a, 'rcu, C> {
|
||||
let pa = self.pte.paddr();
|
||||
let prop = self.pte.prop();
|
||||
|
||||
let new_page = PageTableNode::<C>::alloc(level - 1);
|
||||
let mut pt_lock_guard = new_page.borrow().lock(guard);
|
||||
let new_page = RcuDrop::new(PageTableNode::<C>::alloc(level - 1));
|
||||
|
||||
let paddr = new_page.start_paddr();
|
||||
// SAFETY: The page table won't be dropped before the RCU grace period
|
||||
// ends, so it outlives `'rcu`.
|
||||
let pt_ref = unsafe { PageTableNodeRef::borrow_paddr(paddr) };
|
||||
|
||||
// Lock before writing the PTE, so no one else can operate on it.
|
||||
let mut pt_lock_guard = pt_ref.lock(guard);
|
||||
|
||||
for i in 0..nr_subpage_per_huge::<C>() {
|
||||
let small_pa = pa + i * page_size::<C>(level - 1);
|
||||
@ -193,24 +199,16 @@ impl<'a, 'rcu, C: PageTableConfig> Entry<'a, 'rcu, C> {
|
||||
debug_assert!(old.is_none());
|
||||
}
|
||||
|
||||
let paddr = new_page.start_paddr();
|
||||
let _ = ManuallyDrop::new(pt_lock_guard);
|
||||
|
||||
// SAFETY:
|
||||
// 1. The index is within the bounds.
|
||||
// 2. The new PTE is a valid child whose level matches the current page table node.
|
||||
// 2. The new PTE is a child in `C` and at the correct paging level.
|
||||
// 3. The ownership of the child is passed to the page table node.
|
||||
unsafe {
|
||||
self.node.write_pte(
|
||||
self.idx,
|
||||
Child::PageTable(RcuDrop::new(new_page)).into_pte(),
|
||||
)
|
||||
self.node
|
||||
.write_pte(self.idx, Child::PageTable(new_page).into_pte())
|
||||
};
|
||||
|
||||
// SAFETY: The page table won't be dropped before the RCU grace period
|
||||
// ends, so it outlives `'rcu`.
|
||||
let pt_ref = unsafe { PageTableNodeRef::borrow_paddr(paddr) };
|
||||
// SAFETY: The node is locked and there are no other guards.
|
||||
Some(unsafe { pt_ref.make_guard_unchecked(guard) })
|
||||
Some(pt_lock_guard)
|
||||
}
|
||||
|
||||
/// Create a new entry at the node with guard.
|
||||
|
Reference in New Issue
Block a user