Skip to content

Commit 6316974

Browse files
committed
[feat] add borrowed_entries to avoid the dropping of shared entrys
1 parent 5ce026e commit 6316974

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

page_table_multiarch/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ rust-version.workspace = true
1616
log = "0.4"
1717
memory_addr = "0.3"
1818
page_table_entry = { path = "../page_table_entry", version = "0.5.2" }
19+
bitmaps = { version = "3.2", default-features = false }
1920

2021
[target.'cfg(any(target_arch = "x86_64", doc))'.dependencies]
2122
x86 = "0.52"

page_table_multiarch/src/bits64.rs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const fn p1_index(vaddr: usize) -> usize {
2727
/// When the [`PageTable64`] itself is dropped.
2828
pub struct PageTable64<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> {
2929
root_paddr: PhysAddr,
30+
borrowed_entries: bitmaps::Bitmap<ENTRY_COUNT>,
3031
_phantom: PhantomData<(M, PTE, H)>,
3132
}
3233

@@ -38,13 +39,15 @@ impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> PageTable64<M, PTE, H
3839
let root_paddr = Self::alloc_table()?;
3940
Ok(Self {
4041
root_paddr,
42+
borrowed_entries: bitmaps::Bitmap::new(),
4143
_phantom: PhantomData,
4244
})
4345
}
4446

4547
pub fn from_paddr(root_paddr: PhysAddr) -> Self {
4648
Self {
4749
root_paddr,
50+
borrowed_entries: bitmaps::Bitmap::new(),
4851
_phantom: PhantomData,
4952
}
5053
}
@@ -349,7 +352,14 @@ impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> PageTable64<M, PTE, H
349352
let end_idx = index_fn(start.into() + size - 1) + 1;
350353
assert!(start_idx < ENTRY_COUNT);
351354
assert!(end_idx <= ENTRY_COUNT);
352-
dst_table[start_idx..end_idx].copy_from_slice(&src_table[start_idx..end_idx]);
355+
// dst_table[start_idx..end_idx].copy_from_slice(&src_table[start_idx..end_idx]);
356+
for i in start_idx..end_idx {
357+
let entry = &mut dst_table[i];
358+
if !self.borrowed_entries.set(i, true) && self.next_table(entry).is_ok() {
359+
self.dealloc_tree(entry.paddr(), 1);
360+
}
361+
*entry = src_table[i];
362+
}
353363
}
354364
}
355365

@@ -527,22 +537,44 @@ impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> PageTable64<M, PTE, H
527537
}
528538
Ok(())
529539
}
540+
541+
fn dealloc_tree(&self, table_paddr: PhysAddr, level: usize) {
542+
// don't free the entries in last level, they are not array.
543+
if level < M::LEVELS - 1 {
544+
for entry in self.table_of(table_paddr) {
545+
if self.next_table(entry).is_ok() {
546+
self.dealloc_tree(entry.paddr(), level + 1);
547+
}
548+
}
549+
}
550+
H::dealloc_frame(table_paddr);
551+
}
530552
}
531553

532554
impl<M: PagingMetaData, PTE: GenericPTE, H: PagingHandler> Drop for PageTable64<M, PTE, H> {
533555
fn drop(&mut self) {
534556
warn!("Dropping page table @ {:#x}", self.root_paddr());
535557

536-
// don't free the entries in last level, they are not array.
537-
let _ = self.walk(
538-
usize::MAX,
539-
None,
540-
Some(&|level, _index, _vaddr, entry: &PTE| {
541-
if level < M::LEVELS - 1 && entry.is_present() && !entry.is_huge() {
542-
H::dealloc_frame(entry.paddr());
543-
}
544-
}),
545-
);
558+
// // don't free the entries in last level, they are not array.
559+
// let _ = self.walk(
560+
// usize::MAX,
561+
// None,
562+
// Some(&|level, _index, _vaddr, entry: &PTE| {
563+
// if level < M::LEVELS - 1 && entry.is_present() && !entry.is_huge() {
564+
// H::dealloc_frame(entry.paddr());
565+
// }
566+
// }),
567+
// );
568+
let root = self.table_of(self.root_paddr);
569+
#[allow(unused_variables)]
570+
for (i, entry) in root.iter().enumerate() {
571+
if self.borrowed_entries.get(i) {
572+
continue;
573+
}
574+
if self.next_table(entry).is_ok() {
575+
self.dealloc_tree(entry.paddr(), 1);
576+
}
577+
}
546578
H::dealloc_frame(self.root_paddr());
547579
}
548580
}

0 commit comments

Comments
 (0)