From baf46a3555300a04ed82480a960d2cd5d06c71f4 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Wed, 1 Nov 2023 11:29:30 +0100 Subject: [PATCH] Far more progress --- src/memory/mod.rs | 69 ++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/src/memory/mod.rs b/src/memory/mod.rs index b62b4155cb..8d2eb0542e 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -48,14 +48,17 @@ pub fn allocate_frame() -> Option { allocate_frames(1) } pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, min: usize) -> Option<(Frame, usize)> { - let before = get_freelist_pagecount(); - //debug_freelist(); - // TODO: Split into sub-power of two allocations. let min_order = min.next_power_of_two().trailing_zeros(); let _req_order = count.next_power_of_two().trailing_zeros(); - log::info!("PREALLOC 2^{min_order}"); + /*if DEBUG.load(Ordering::Relaxed) > 0 { + log::info!("BEFORE"); + log::info!("PREALLOC 2^{min_order}"); + debug_freelist(); + }*/ + //let before = get_freelist_pagecount(); + //debug_freelist(); let mut freelist = FREELIST.lock(); @@ -74,6 +77,7 @@ pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, mi //log::info!("FREE {frame:?} ORDER {frame_order} NEXT_FREE {next_free:?}"); if let Some(next) = next_free.frame() { + assert_ne!(next, frame); assert!(next.is_aligned_to_order(frame_order), "NEXT {next:?} UNALIGNED"); get_free_alloc_page_info(next).set_prev(P2Frame::new(None, frame_order)); } @@ -90,10 +94,9 @@ pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, mi let hi = frame.next_by(order_page_count); //log::info!("SPLIT INTO {frame:?}:{hi:?} ORDER {order}"); - if let Some(old_head) = freelist[order as usize].replace(hi) { - let hi_info = get_page_info(hi).expect("sub-p2frame of split p2flame lacked PageInfo").make_free(order); - assert!(!hi.is_aligned_to_order(frame_order)); + assert_eq!(freelist[order as usize], None); + /*if let Some(old_head) = freelist[order as usize].replace(hi) { hi_info.set_next(P2Frame::new(Some(old_head), order)); hi_info.set_prev(P2Frame::new(None, order)); // @@ -103,13 +106,20 @@ pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, mi let old_head_info = get_free_alloc_page_info(old_head); assert_eq!(old_head_info.prev().frame(), None); old_head_info.set_prev(P2Frame::new(Some(hi), order)); - } + }*/ + let hi_info = get_page_info(hi).expect("sub-p2frame of split p2flame lacked PageInfo").make_free(order); + assert!(!hi.is_aligned_to_order(frame_order)); + hi_info.set_next(P2Frame::new(None, order)); + hi_info.set_prev(P2Frame::new(None, order)); + freelist[order as usize] = Some(hi); } drop(freelist); - _get_freelist_pagecount(false, min_order, frame_order); + /*_get_freelist_pagecount(false, min_order, frame_order, true); + _get_freelist_pagecount(false, min_order, frame_order, false);*/ info.mark_used(); - _get_freelist_pagecount(false, min_order, frame_order); + /*_get_freelist_pagecount(false, min_order, frame_order, false); + _get_freelist_pagecount(false, min_order, frame_order, true);*/ unsafe { (RmmA::phys_to_virt(frame.start_address()).data() as *mut u8).write_bytes(0, PAGE_SIZE << min_order); @@ -128,23 +138,27 @@ pub fn allocate_frames_complex(count: usize, flags: (), strategy: Option<()>, mi } assert!(found); }*/ - let after = _get_freelist_pagecount(false, min_order, frame_order); + /*let after = _get_freelist_pagecount(false, min_order, frame_order, false); assert_eq!(after, before - (1 << min_order)); - log::info!("ALLOCED {frame:?}+2^{min_order}"); + if DEBUG.load(Ordering::Relaxed) > 0 { + log::info!("ALLOCED {frame:?}+2^{min_order}"); + log::info!("AFTER"); + debug_freelist(); + }*/ Some((frame, PAGE_SIZE << min_order)) } /// Deallocate a range of frames pub unsafe fn deallocate_frames(frame: Frame, count: usize) { - log::info!("DEALLOC{frame:?}+{count}"); + /*log::info!("DEALLOC{frame:?}+{count}"); let before = get_freelist_pagecount(); - debug_freelist(); + debug_freelist();*/ deallocate_frames_inner(frame, count); - debug_freelist(); + /*debug_freelist(); //loop {} - let after = get_freelist_pagecount(); + let after = get_freelist_pagecount();*/ } unsafe fn deallocate_frames_inner(frame: Frame, count: usize) { if count == 0 { @@ -184,9 +198,10 @@ unsafe fn deallocate_frames_inner(frame: Frame, count: usize) { } } fn get_freelist_pagecount() -> usize { - _get_freelist_pagecount(false, 100, 100) + _get_freelist_pagecount(false, 100, 100, false) } -fn _get_freelist_pagecount(debug: bool, o: u32, f: u32) -> usize { +pub static DEBUG: AtomicUsize = AtomicUsize::new(0); +fn _get_freelist_pagecount(debug: bool, o: u32, f: u32, set_not_clear: bool) -> usize { let mut pagecount = 0; let freelist = FREELIST.lock(); @@ -214,10 +229,16 @@ fn _get_freelist_pagecount(debug: bool, o: u32, f: u32) -> usize { drop(freelist); if !debug { log::info!("M{o}F{f}"); - _get_freelist_pagecount(true, o, f); + //_get_freelist_pagecount(true, o, f, false); + debug_freelist(); } panic!("i{i}o{order}"); }; + if set_not_clear { + assert!(next_info.next.fetch_or(RC_USED_NOT_FREE, Ordering::Relaxed) & RC_USED_NOT_FREE == 0); + } else { + next_info.next.fetch_and(!RC_USED_NOT_FREE, Ordering::Relaxed); + } let next_frame = next_info.next().frame(); /*if next_info.order() != order { log::info!("BAD ORDER FOR {next_frame:?}"); @@ -282,7 +303,7 @@ unsafe fn deallocate_p2frame(mut frame: Frame, order: u32) { if lo_info.next().order() != merge_order || hi_info.next().order() != merge_order { break; } - log::info!("MERGED {lo:?} WITH {hi:?} ORDER {order}"); + //log::info!("MERGED {lo:?} WITH {hi:?} ORDER {order}"); let lo_next = lo_info.next(); let lo_prev = lo_info.prev(); @@ -356,7 +377,7 @@ unsafe fn deallocate_p2frame(mut frame: Frame, order: u32) { old_head_info.set_prev(P2Frame::new(Some(new_head), largest_order)); } - log::info!("FREED {frame:?}+2^{order}"); + //log::info!("FREED {frame:?}+2^{order}"); } pub unsafe fn deallocate_frame(frame: Frame) { @@ -387,9 +408,9 @@ impl P2Frame { ) } fn get(self) -> (Option, u32) { - assert_ne!(self.0 & RC_USED_NOT_FREE, RC_USED_NOT_FREE); + //assert_ne!(self.0 & RC_USED_NOT_FREE, RC_USED_NOT_FREE); let page_off_mask = PAGE_SIZE - 1; - (NonZeroUsize::new(self.0 & !page_off_mask).map(|physaddr| Frame { physaddr }), (self.0 & page_off_mask) as u32) + (NonZeroUsize::new(self.0 & !page_off_mask & !(RC_USED_NOT_FREE)).map(|physaddr| Frame { physaddr }), (self.0 & page_off_mask) as u32) } fn frame(self) -> Option { self.get().0 @@ -996,7 +1017,7 @@ pub fn get_page_info(frame: Frame) -> Option<&'static PageInfo> { #[track_caller] fn get_free_alloc_page_info(frame: Frame) -> PageInfoFree<'static> { let i = get_page_info(frame).unwrap_or_else(|| panic!("allocator-owned frames need a PageInfo, but none for {frame:?}")); - i.as_free().unwrap_or_else(|| panic!("expected frame to be free, but {frame:?} wasn't, in {i:?}")) + i.as_free().unwrap()//.unwrap_or_else(|| panic!("expected frame to be free, but {frame:?} wasn't, in {i:?}")) } pub struct Segv;