From a0ec6873157136d0b4ce053d62f9dd712b85ee4f Mon Sep 17 00:00:00 2001 From: rikosellic Date: Fri, 30 Aug 2024 17:32:50 +0800 Subject: [PATCH] Page::inc_ref_count conforms to the reference counting invariant format code Add detailed annotations Typo fixed --- ostd/src/mm/page/mod.rs | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/ostd/src/mm/page/mod.rs b/ostd/src/mm/page/mod.rs index 458b8f9a..d3663e6a 100644 --- a/ostd/src/mm/page/mod.rs +++ b/ostd/src/mm/page/mod.rs @@ -123,11 +123,18 @@ impl Page { /// /// # Safety /// - /// The physical address must represent a valid page and the caller must already hold one - /// reference count. + /// The physical address must represent a valid page and the caller must ensure the corresponding + /// virtual address points to an initialized metadata slot by holding a reference count priorly. pub(in crate::mm) unsafe fn inc_ref_count(paddr: Paddr) { - let page = unsafe { ManuallyDrop::new(Self::from_raw(paddr)) }; - let _page = page.clone(); + debug_assert!(paddr % PAGE_SIZE == 0); + debug_assert!(paddr < MAX_PADDR.load(Ordering::Relaxed) as Paddr); + let vaddr: Vaddr = mapping::page_to_meta::(paddr); + // SAFETY: The virtual address points to an initialized metadata slot. The caller can ensure + // it is initialized by holding a reference count before calling this function, preventing + // adding a reference count to an unused page. + (*(vaddr as *const MetaSlot)) + .ref_count + .fetch_add(1, Ordering::Relaxed); } /// Get the physical address. @@ -229,11 +236,18 @@ impl DynPage { /// /// # Safety /// - /// The physical address must represent a valid page and the caller must already hold one - /// reference count. + /// The physical address must represent a valid page and the caller must ensure the corresponding + /// virtual address points to an initialized metadata slot by holding a reference count priorly. pub(in crate::mm) unsafe fn inc_ref_count(paddr: Paddr) { - let page = unsafe { ManuallyDrop::new(Self::from_raw(paddr)) }; - let _page = page.clone(); + debug_assert!(paddr % PAGE_SIZE == 0); + debug_assert!(paddr < MAX_PADDR.load(Ordering::Relaxed) as Paddr); + let vaddr: Vaddr = mapping::page_to_meta::(paddr); + // SAFETY: The virtual address points to an initialized metadata slot. The caller can ensure + // it is initialized by holding a reference count before calling this function, preventing + // adding a reference count to an unused page. + (*(vaddr as *const MetaSlot)) + .ref_count + .fetch_add(1, Ordering::Relaxed); } /// Get the physical address of the start of the page