Skip to content
Snippets Groups Projects
Commit 800e6c6d authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Free page tables during unmap, if empty

parent 1e8df4b9
No related branches found
No related tags found
No related merge requests found
...@@ -133,29 +133,69 @@ impl Mapper { ...@@ -133,29 +133,69 @@ impl Mapper {
self.map_to(page, frame, flags) self.map_to(page, frame, flags)
} }
fn unmap_inner(&mut self, page: &Page) -> Frame {
let frame;
let p4 = self.p4_mut();
{
let p3 = p4.next_table_mut(page.p4_index()).expect("unmap_inner: p3 not found");
{
let p2 = p3.next_table_mut(page.p3_index()).expect("unmap_inner: p2 not found");
{
let p1 = p2.next_table_mut(page.p2_index()).expect("unmap_inner: p1 not found");
frame = p1[page.p1_index()].pointed_frame().expect("unmap_inner: frame not found");
p1[page.p1_index()].set_unused();
if ! p1.is_unused() {
return frame;
}
}
{
let p1_frame = p2[page.p2_index()].pointed_frame().expect("unmap_inner: p1 frame not found");
println!("Free p1 {:?}", p1_frame);
p2[page.p2_index()].set_unused();
deallocate_frames(p1_frame, 1);
}
if ! p2.is_unused() {
return frame;
}
}
{
let p2_frame = p3[page.p3_index()].pointed_frame().expect("unmap_inner: p2 frame not found");
println!("Free p2 {:?}", p2_frame);
p3[page.p3_index()].set_unused();
deallocate_frames(p2_frame, 1);
}
if ! p3.is_unused() {
return frame;
}
}
{
let p3_frame = p4[page.p4_index()].pointed_frame().expect("unmap_inner: p3 frame not found");
println!("Free p3 {:?}", p3_frame);
p4[page.p2_index()].set_unused();
deallocate_frames(p3_frame, 1);
}
frame
}
/// Unmap a page /// Unmap a page
pub fn unmap(&mut self, page: Page) -> MapperFlush { pub fn unmap(&mut self, page: Page) -> MapperFlush {
let p1 = self.p4_mut() let frame = self.unmap_inner(&page);
.next_table_mut(page.p4_index())
.and_then(|p3| p3.next_table_mut(page.p3_index()))
.and_then(|p2| p2.next_table_mut(page.p2_index()))
.expect("unmap does not support huge pages");
let frame = p1[page.p1_index()].pointed_frame().unwrap();
p1[page.p1_index()].set_unused();
// TODO free p(1,2,3) table if empty
deallocate_frames(frame, 1); deallocate_frames(frame, 1);
MapperFlush::new(page) MapperFlush::new(page)
} }
/// Unmap a page, return frame without free /// Unmap a page, return frame without free
pub fn unmap_return(&mut self, page: Page) -> (MapperFlush, Frame) { pub fn unmap_return(&mut self, page: Page) -> (MapperFlush, Frame) {
let p1 = self.p4_mut() let frame = self.unmap_inner(&page);
.next_table_mut(page.p4_index())
.and_then(|p3| p3.next_table_mut(page.p3_index()))
.and_then(|p2| p2.next_table_mut(page.p2_index()))
.expect("unmap_return does not support huge pages");
let frame = p1[page.p1_index()].pointed_frame().unwrap();
p1[page.p1_index()].set_unused();
(MapperFlush::new(page), frame) (MapperFlush::new(page), frame)
} }
......
...@@ -45,6 +45,16 @@ pub struct Table<L: TableLevel> { ...@@ -45,6 +45,16 @@ pub struct Table<L: TableLevel> {
} }
impl<L> Table<L> where L: TableLevel { impl<L> Table<L> where L: TableLevel {
pub fn is_unused(&self) -> bool {
for entry in self.entries.iter() {
if ! entry.is_unused() {
return false;
}
}
true
}
pub fn zero(&mut self) { pub fn zero(&mut self) {
for entry in self.entries.iter_mut() { for entry in self.entries.iter_mut() {
entry.set_unused(); entry.set_unused();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment