Revise the cache page allocation for PageCacheManager

This commit is contained in:
Shaowei Song 2025-02-10 07:24:07 +00:00 committed by Tate, Hongliang Tian
parent 55713b88c4
commit fecf766771

View File

@ -14,7 +14,7 @@ use aster_rights::Full;
use lru::LruCache; use lru::LruCache;
use ostd::{ use ostd::{
impl_untyped_frame_meta_for, impl_untyped_frame_meta_for,
mm::{Frame, FrameAllocOptions, UFrame, UntypedMem, VmIo}, mm::{Frame, FrameAllocOptions, UFrame, VmIo},
}; };
use crate::{ use crate::{
@ -311,7 +311,7 @@ impl ReadaheadState {
return_errno!(Errno::EINVAL) return_errno!(Errno::EINVAL)
}; };
for async_idx in window.readahead_range() { for async_idx in window.readahead_range() {
let mut async_page = CachePage::alloc()?; let mut async_page = CachePage::alloc_uninit()?;
let pg_waiter = backend.read_page_async(async_idx, &async_page)?; let pg_waiter = backend.read_page_async(async_idx, &async_page)?;
if pg_waiter.nreqs() > 0 { if pg_waiter.nreqs() > 0 {
self.waiter.concat(pg_waiter); self.waiter.concat(pg_waiter);
@ -416,12 +416,12 @@ impl PageCacheManager {
// Cond 3. // Cond 3.
// Conducts the sync read operation. // Conducts the sync read operation.
let page = if idx < backend.npages() { let page = if idx < backend.npages() {
let mut page = CachePage::alloc()?; let mut page = CachePage::alloc_uninit()?;
backend.read_page(idx, &page)?; backend.read_page(idx, &page)?;
page.store_state(PageState::UpToDate); page.store_state(PageState::UpToDate);
page page
} else { } else {
CachePage::alloc_zero()? CachePage::alloc_zero(PageState::Uninit)?
}; };
let frame = page.clone(); let frame = page.clone();
pages.put(idx, page); pages.put(idx, page);
@ -481,7 +481,7 @@ impl Pager for PageCacheManager {
return Ok(page.clone().into()); return Ok(page.clone().into());
} }
let page = CachePage::alloc_zero()?; let page = CachePage::alloc_uninit()?;
Ok(self.pages.lock().get_or_insert(idx, || page).clone().into()) Ok(self.pages.lock().get_or_insert(idx, || page).clone().into())
} }
} }
@ -499,13 +499,13 @@ pub struct CachePageMeta {
impl_untyped_frame_meta_for!(CachePageMeta); impl_untyped_frame_meta_for!(CachePageMeta);
pub trait CachePageExt { pub trait CachePageExt {
/// Gets the metadata associated with the cache page.
fn metadata(&self) -> &CachePageMeta; fn metadata(&self) -> &CachePageMeta;
fn alloc() -> Result<CachePage> { /// Allocates a new cache page which content and state are uninitialized.
fn alloc_uninit() -> Result<CachePage> {
let meta = CachePageMeta { let meta = CachePageMeta {
state: AtomicPageState { state: AtomicPageState::new(PageState::Uninit),
state: AtomicU8::new(PageState::Uninit as u8),
},
}; };
let page = FrameAllocOptions::new() let page = FrameAllocOptions::new()
.zeroed(false) .zeroed(false)
@ -513,16 +513,23 @@ pub trait CachePageExt {
Ok(page) Ok(page)
} }
fn alloc_zero() -> Result<CachePage> { /// Allocates a new zeroed cache page with the wanted state.
let page = Self::alloc()?; fn alloc_zero(state: PageState) -> Result<CachePage> {
page.writer().fill(0); let meta = CachePageMeta {
state: AtomicPageState::new(state),
};
let page = FrameAllocOptions::new()
.zeroed(true)
.alloc_frame_with(meta)?;
Ok(page) Ok(page)
} }
/// Loads the current state of the cache page.
fn load_state(&self) -> PageState { fn load_state(&self) -> PageState {
self.metadata().state.load(Ordering::Relaxed) self.metadata().state.load(Ordering::Relaxed)
} }
/// Stores a new state for the cache page.
fn store_state(&mut self, new_state: PageState) { fn store_state(&mut self, new_state: PageState) {
self.metadata().state.store(new_state, Ordering::Relaxed); self.metadata().state.store(new_state, Ordering::Relaxed);
} }
@ -555,6 +562,12 @@ pub struct AtomicPageState {
} }
impl AtomicPageState { impl AtomicPageState {
pub fn new(state: PageState) -> Self {
Self {
state: AtomicU8::new(state as _),
}
}
pub fn load(&self, order: Ordering) -> PageState { pub fn load(&self, order: Ordering) -> PageState {
let val = self.state.load(order); let val = self.state.load(order);
match val { match val {