From a12be1b17266f2df893d08d7dd917b0da6875f5c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 9 Sep 2020 20:19:28 -0600 Subject: [PATCH] Keep track of last free page --- src/allocator/frame/buddy.rs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/allocator/frame/buddy.rs b/src/allocator/frame/buddy.rs index 1dfa1fba72..2b9a6685ea 100644 --- a/src/allocator/frame/buddy.rs +++ b/src/allocator/frame/buddy.rs @@ -34,7 +34,7 @@ impl BuddyEntry { #[repr(packed)] struct BuddyMapFooter { next: PhysicalAddress, - //TODO: index of last known free bit + skip: usize, } pub struct BuddyAllocator { @@ -104,6 +104,7 @@ impl BuddyAllocator { let map_virt = A::phys_to_virt(map_phys); A::write(map_virt.add(Self::MAP_PAGE_BYTES), BuddyMapFooter { next: entry.map, + skip: Self::MAP_PAGE_BYTES, }); entry.map = map_phys; } @@ -151,7 +152,11 @@ impl FrameAllocator for BuddyAllocator { let mut offset = start_offset; 'find: while map_phys.data() != 0 { let map_virt = A::phys_to_virt(map_phys); - for i in 0 .. Self::MAP_PAGE_BYTES { + let footer_virt = map_virt.add(Self::MAP_PAGE_BYTES); + let mut footer = A::read::(footer_virt); + offset += footer.skip * A::PAGE_SIZE * 8; + + for i in footer.skip .. Self::MAP_PAGE_BYTES { let map_byte_virt = map_virt.add(i); let value: u8 = A::read(map_byte_virt); if (value & u8::MAX) != 0 { @@ -166,19 +171,31 @@ impl FrameAllocator for BuddyAllocator { } found += 1; if found == count.data() { + // If skip is set to the start of the newly allocated frames + if footer.skip == start_i && footer.skip != i { + // Set it to the end of the newly allocated frames + footer.skip = i; + A::write(footer_virt, footer); + } break 'find; } } else { found = 0; } } + } else { + // If skip is set to the current 8 frames, and they are already used + if footer.skip == i { + // Set skip to the next current frame + footer.skip = i + 1; + A::write(footer_virt, footer); + } found = 0; } offset += A::PAGE_SIZE * 8; } - let footer = A::read::(map_virt.add(Self::MAP_PAGE_BYTES)); map_phys = footer.next; } @@ -217,7 +234,8 @@ impl FrameAllocator for BuddyAllocator { } start_i = 0; - let footer = A::read::(map_virt.add(Self::MAP_PAGE_BYTES)); + let footer_virt = map_virt.add(Self::MAP_PAGE_BYTES); + let footer = A::read::(footer_virt); map_phys = footer.next; } } @@ -247,14 +265,20 @@ impl FrameAllocator for BuddyAllocator { loop { if map_phys.data() == 0 { unimplemented!("map_phys.data() == 0") } let map_virt = A::phys_to_virt(map_phys); + let footer_virt = map_virt.add(Self::MAP_PAGE_BYTES); + let mut footer = A::read::(footer_virt); if map_page == 0 { - let map_byte_virt = map_virt.add(map_bit / 8); + let map_byte = map_bit / 8; + if map_byte < footer.skip { + footer.skip = map_byte; + A::write(footer_virt, footer); + } + let map_byte_virt = map_virt.add(map_byte); let mut value: u8 = A::read(map_byte_virt); value |= 1 << (map_bit % 8); A::write(map_byte_virt, value); break; } else { - let footer = A::read::(map_virt.add(Self::MAP_PAGE_BYTES)); map_phys = footer.next; map_page -= 1; }