diff --git a/framework/jinux-frame/src/vm/frame.rs b/framework/jinux-frame/src/vm/frame.rs index 94155d43a..4d11c8636 100644 --- a/framework/jinux-frame/src/vm/frame.rs +++ b/framework/jinux-frame/src/vm/frame.rs @@ -33,18 +33,20 @@ impl VmFrameVec { /// For more information, see `VmAllocOptions`. pub fn allocate(options: &VmAllocOptions) -> Result { let page_size = options.page_size; - let mut frame_list = Vec::new(); - if options.is_contiguous { - let frames = frame_allocator::alloc_continuous(options.page_size); - if frames.is_none() { - return Err(Error::NoMemory); + let frames = if options.is_contiguous { + frame_allocator::alloc_continuous(options.page_size).ok_or(Error::NoMemory)? + } else { + let mut frame_list = Vec::new(); + for _ in 0..page_size { + frame_list.push(frame_allocator::alloc().ok_or(Error::NoMemory)?); } - return Ok(Self(frames.unwrap())); + frame_list + }; + let frame_vec = Self(frames); + if !options.uninit { + frame_vec.zero(); } - for i in 0..page_size { - frame_list.push(frame_allocator::alloc().unwrap()); - } - Ok(Self(frame_list)) + Ok(frame_vec) } pub fn get(&self, index: usize) -> Option<&VmFrame> { @@ -201,6 +203,7 @@ impl<'a> Iterator for VmFrameVecIter<'a> { pub struct VmAllocOptions { page_size: usize, is_contiguous: bool, + uninit: bool, } impl VmAllocOptions { @@ -209,6 +212,7 @@ impl VmAllocOptions { Self { page_size: len, is_contiguous: false, + uninit: false, } } @@ -222,6 +226,17 @@ impl VmAllocOptions { self } + /// Sets whether the allocated frames should be uninitialized. + /// + /// If `uninit` is set as `false`, the frame will be zeroed once allocated. + /// If `uninit` is set as `true`, the frame will **NOT** be zeroed and should *NOT* be read before writing. + /// + /// The default value is false. + pub fn uninit(&mut self, uninit: bool) -> &mut Self { + self.uninit = uninit; + self + } + /// Sets whether the pages can be accessed by devices through /// Direct Memory Access (DMA). /// diff --git a/framework/jinux-frame/src/vm/frame_allocator.rs b/framework/jinux-frame/src/vm/frame_allocator.rs index 386d8b3a0..bcf3016f8 100644 --- a/framework/jinux-frame/src/vm/frame_allocator.rs +++ b/framework/jinux-frame/src/vm/frame_allocator.rs @@ -31,10 +31,8 @@ pub fn alloc_continuous(frame_count: usize) -> Option> { let mut vector = Vec::new(); unsafe { for i in 0..frame_count { - vector.push(VmFrame::new( - (start + i) * PAGE_SIZE, - VmFrameFlags::NEED_DEALLOC, - )) + let frame = VmFrame::new((start + i) * PAGE_SIZE, VmFrameFlags::NEED_DEALLOC); + vector.push(frame); } } vector diff --git a/services/libs/jinux-std/src/fs/utils/page_cache.rs b/services/libs/jinux-std/src/fs/utils/page_cache.rs index 021cbe1bc..5b088add8 100644 --- a/services/libs/jinux-std/src/fs/utils/page_cache.rs +++ b/services/libs/jinux-std/src/fs/utils/page_cache.rs @@ -112,7 +112,8 @@ struct Page { impl Page { pub fn alloc() -> Result { let frame = { - let vm_alloc_option = VmAllocOptions::new(1); + let mut vm_alloc_option = VmAllocOptions::new(1); + vm_alloc_option.uninit(true); let mut frames = VmFrameVec::allocate(&vm_alloc_option)?; frames.pop().unwrap() }; @@ -126,7 +127,6 @@ impl Page { let frame = { let vm_alloc_option = VmAllocOptions::new(1); let mut frames = VmFrameVec::allocate(&vm_alloc_option)?; - frames.zero(); frames.pop().unwrap() }; Ok(Self { diff --git a/services/libs/jinux-std/src/vm/vmo/mod.rs b/services/libs/jinux-std/src/vm/vmo/mod.rs index eb7bffd69..a2fbfb9c0 100644 --- a/services/libs/jinux-std/src/vm/vmo/mod.rs +++ b/services/libs/jinux-std/src/vm/vmo/mod.rs @@ -204,9 +204,7 @@ impl Vmo_ { let frames = match &inner.pager { None => { let vm_alloc_option = VmAllocOptions::new(1); - let frames = VmFrameVec::allocate(&vm_alloc_option)?; - frames.iter().for_each(|frame| frame.zero()); - frames + VmFrameVec::allocate(&vm_alloc_option)? } Some(pager) => { let frame = pager.commit_page(offset)?;