From add9d4bbf0a915c6ab8a4a0a60a9226a8bdfb3e9 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Sun, 20 Oct 2024 00:35:17 +0800 Subject: [PATCH 01/38] =?UTF-8?q?=E5=AE=9E=E7=8E=B0read=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E8=AF=BB=E5=8F=96pagecache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/Cargo.toml | 2 +- kernel/src/filesystem/fat/fs.rs | 47 +++++- kernel/src/filesystem/vfs/file.rs | 232 +++++++++++++++++++++++++++++- kernel/src/mm/fault.rs | 2 +- 4 files changed, 268 insertions(+), 15 deletions(-) diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 3156e1147..b784123b4 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -89,4 +89,4 @@ debug = true # Controls whether the compiler passes `-g` # The release profile, used for `cargo build --release` [profile.release] -debug = false +debug = true diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 49b68222b..a2411c3fa 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1392,13 +1392,46 @@ impl IndexNode for LockedFATInode { let mut guard: SpinLockGuard = self.0.lock(); match &guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { - let r = f.read( - &guard.fs.upgrade().unwrap(), - &mut buf[0..len], - offset as u64, - ); - guard.update_metadata(); - return r; + if let Some(page_cache) = &guard.page_cache { + let (len, rest) = page_cache.read(offset, buf); + if rest.is_empty() { + return Ok(len); + } else { + let mut err = None; + let mut ret = len; + for (file_offset, len) in rest { + let buf_offset = file_offset - offset; + match f.read( + &guard.fs.upgrade().unwrap(), + &mut buf[buf_offset..(buf_offset + len)], + file_offset as u64, + ) { + Ok(size) => { + ret += size; + // page_cache.create_pages(offset, &buf[offset..(offset + len)]); + } + Err(e) => { + err = Some(e); + break; + } + } + } + guard.update_metadata(); + if let Some(e) = err { + return Err(e); + } else { + return Ok(ret); + } + } + } else { + let r = f.read( + &guard.fs.upgrade().unwrap(), + &mut buf[0..len], + offset as u64, + ); + guard.update_metadata(); + return r; + } } FATDirEntry::Dir(_) => { return Err(SystemError::EISDIR); diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index d15167bad..7226a1b62 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -1,4 +1,7 @@ -use core::sync::atomic::{AtomicUsize, Ordering}; +use core::{ + cmp::min, + sync::atomic::{AtomicUsize, Ordering}, +}; use alloc::{ string::String, @@ -10,7 +13,6 @@ use log::error; use system_error::SystemError; use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData}; -use crate::filesystem::eventfd::EventFdInode; use crate::{ arch::MMArch, driver::{ @@ -20,13 +22,20 @@ use crate::{ filesystem::procfs::ProcfsFilePrivateData, ipc::pipe::{LockedPipeInode, PipeFsPrivateData}, libs::{rwlock::RwLock, spinlock::SpinLock}, - mm::{page::Page, MemoryManagementArch}, + mm::{ + allocator::page_frame::FrameAllocator, + page::{page_manager_lock_irqsave, page_reclaimer_lock_irqsave, Page, PageFlags}, + ucontext::AddressSpace, + MemoryManagementArch, + }, net::{ event_poll::{EPollItem, EPollPrivateData, EventPoll}, socket::SocketInode, }, process::{cred::Cred, ProcessManager}, + syscall::user_access::{UserBufferReader, UserBufferWriter}, }; +use crate::{filesystem::eventfd::EventFdInode, libs::align::page_align_up}; /// 文件私有信息的枚举类型 #[derive(Debug, Clone)] @@ -126,6 +135,7 @@ impl FileMode { pub struct PageCache { xarray: SpinLock>>, inode: Option>, + self_ref: Weak, } impl core::fmt::Debug for PageCache { @@ -146,11 +156,11 @@ impl core::fmt::Debug for PageCache { impl PageCache { pub fn new(inode: Option>) -> Arc { - let page_cache = Self { + Arc::new_cyclic(|weak| Self { xarray: SpinLock::new(XArray::new()), inode, - }; - Arc::new(page_cache) + self_ref: weak.clone(), + }) } pub fn inode(&self) -> Option> { @@ -179,6 +189,216 @@ impl PageCache { pub fn set_inode(&mut self, inode: Weak) { self.inode = Some(inode) } + + pub fn create_pages(&self, offset: usize, buf: &[u8]) { + let address_space = AddressSpace::current().unwrap(); + // TODO 这里直接加锁会死锁,后续需要排查一下 + let mut guard = if let Some(guard) = address_space.try_write_irqsave() { + guard + } else { + return; + }; + let mapper = &mut guard.user_mapper.utable; + let allocator = mapper.allocator_mut(); + + let len = buf.len(); + if len == 0 { + return; + } + let start_page_offset = offset >> MMArch::PAGE_SHIFT; + let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; + let mut guard = self.xarray.lock(); + let mut cursor = guard.cursor_mut(start_page_offset as u64); + + let mut buf_offset = 0; + for i in 0..page_num { + // 第一个页可能需要计算页内偏移 + let page_offset = if i == 0 { + offset % MMArch::PAGE_SIZE + } else { + 0 + }; + + // 第一个页和最后一个页可能不满 + let sub_len = if i == 0 { + min(len, MMArch::PAGE_SIZE - page_offset) + } else if i == page_num - 1 { + (offset + len - 1) % MMArch::PAGE_SIZE + 1 + } else { + MMArch::PAGE_SIZE + }; + + if let Some(cache_page) = unsafe { allocator.allocate_one() } { + unsafe { + core::slice::from_raw_parts_mut( + MMArch::phys_2_virt(cache_page).unwrap().data() as *mut u8, + MMArch::PAGE_SIZE, + )[page_offset..page_offset + sub_len] + .copy_from_slice(&buf[buf_offset..(buf_offset + sub_len)]); + } + let page = Arc::new(Page::new(true, cache_page)); + + page.write_irqsave().add_flags(PageFlags::PG_LRU); + page_manager_lock_irqsave().insert(cache_page, &page); + page_reclaimer_lock_irqsave().insert_page(cache_page, &page); + cursor.store(page.clone()); + + page.write_irqsave().set_page_cache_index( + self.self_ref.upgrade(), + Some(offset >> MMArch::PAGE_SHIFT), + ); + } + + buf_offset += sub_len; + cursor.next(); + } + } + + /// 从PageCache中读取数据。 + /// + /// ## 参数 + /// + /// - `offset` 偏移量 + /// - `buf` 缓冲区 + /// + /// ## 返回值 + /// + /// - `usize` 成功读取的长度 + /// - `Vec<(usize, usize)>` 未成功读取的区间的偏移量和长度集合 + pub fn read(&self, offset: usize, buf: &mut [u8]) -> (usize, Vec<(usize, usize)>) { + let mut not_exist = Vec::new(); + let len = buf.len(); + if len == 0 { + return (0, not_exist); + } + let start_page_offset = offset >> MMArch::PAGE_SHIFT; + let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; + + let mut guard = self.xarray.lock(); + let mut cursor = guard.cursor_mut(start_page_offset as u64); + + let mut byte_num = 0; + let mut buf_offset = 0; + for i in 0..page_num { + // 第一个页可能需要计算页内偏移 + let page_offset = if i == 0 { + offset % MMArch::PAGE_SIZE + } else { + 0 + }; + + // 第一个页和最后一个页可能不满 + let sub_len = if i == 0 { + min(len, MMArch::PAGE_SIZE - page_offset) + } else if i == page_num - 1 { + (offset + len - 1) % MMArch::PAGE_SIZE + 1 + } else { + MMArch::PAGE_SIZE + }; + + if let Some(page) = cursor.load() { + let vaddr = + unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; + let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; + + if let Ok(user_reader) = + UserBufferReader::new((vaddr.data() + page_offset) as *const u8, sub_len, false) + { + if let Ok(size) = user_reader.copy_from_user(sub_buf, 0) { + byte_num += size; + } + } + } else { + let page_offset = (start_page_offset + i) * MMArch::PAGE_SIZE + page_offset; + if let Some((offset, len)) = not_exist.last_mut() { + if *offset + *len == page_offset { + *len += sub_len; + } else { + not_exist.push((page_offset, sub_len)); + } + } else { + not_exist.push((page_offset, sub_len)); + } + } + + buf_offset += sub_len; + cursor.next(); + } + (byte_num, not_exist) + } + + /// 向PageCache中写入数据。 + /// + /// ## 参数 + /// + /// - `offset` 偏移量 + /// - `buf` 缓冲区 + /// + /// ## 返回值 + /// + /// - `usize` 成功写入的长度 + /// - `Vec<(usize, usize)>` 未成功写入的区间的偏移量和长度集合 + pub fn write(&self, offset: usize, buf: &[u8]) -> (usize, Vec<(usize, usize)>) { + let mut not_exist = Vec::new(); + let len = buf.len(); + if len == 0 { + return (0, not_exist); + } + let start_page_offset = offset >> MMArch::PAGE_SHIFT; + let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; + + let mut guard = self.xarray.lock(); + let mut cursor = guard.cursor_mut(start_page_offset as u64); + + let mut byte_num = 0; + let mut buf_offset = 0; + for i in 0..page_num { + // 第一个页可能需要计算页内偏移 + let page_offset = if i == 0 { + offset % MMArch::PAGE_SIZE + } else { + 0 + }; + + // 第一个页和最后一个页可能不满 + let sub_len = if i == 0 { + min(len, MMArch::PAGE_SIZE - page_offset) + } else if i == page_num - 1 { + (offset + len - 1) % MMArch::PAGE_SIZE + 1 + } else { + MMArch::PAGE_SIZE + }; + + if let Some(page) = cursor.load() { + let vaddr = + unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; + let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; + + if let Ok(mut user_writer) = + UserBufferWriter::new((vaddr.data() + page_offset) as *mut u8, sub_len, false) + { + if let Ok(size) = user_writer.copy_to_user(sub_buf, 0) { + byte_num += size; + } + } + } else { + let page_offset = (start_page_offset + i) * MMArch::PAGE_SIZE + page_offset; + if let Some((offset, len)) = not_exist.last_mut() { + if *offset + *len == page_offset { + *len += sub_len; + } else { + not_exist.push((page_offset, sub_len)); + } + } else { + not_exist.push((page_offset, sub_len)); + } + } + + buf_offset += sub_len; + cursor.next(); + } + (byte_num, not_exist) + } } /// @brief 抽象文件结构体 diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index 457b911f3..9bd0f1429 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -55,7 +55,7 @@ pub struct PageFaultMessage<'a> { flags: FaultFlags, /// 页表映射器 mapper: &'a mut PageMapper, - /// 缺页的文件页在文件中的偏移量 + /// 缺页的文件页在文件中的偏移页号 file_pgoff: Option, /// 缺页对应PageCache中的文件页 page: Option>, From d2ad6084295378e95a1c6158537df687ed6a1103 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 21 Oct 2024 02:30:04 +0800 Subject: [PATCH 02/38] =?UTF-8?q?=E5=AE=8C=E5=96=84read=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 115 ++++++++++++++++++++++-------- kernel/src/filesystem/vfs/file.rs | 26 +++---- 2 files changed, 98 insertions(+), 43 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index a2411c3fa..06bc4c4a5 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -12,6 +12,7 @@ use alloc::{ vec::Vec, }; +use crate::arch::MMArch; use crate::driver::base::block::gendisk::GenDisk; use crate::driver::base::device::device_number::DeviceNumber; use crate::filesystem::vfs::file::PageCache; @@ -19,7 +20,7 @@ use crate::filesystem::vfs::utils::DName; use crate::filesystem::vfs::{Magic, SpecialNodeData, SuperBlock}; use crate::ipc::pipe::LockedPipeInode; use crate::mm::fault::{PageFaultHandler, PageFaultMessage}; -use crate::mm::VmFaultReason; +use crate::mm::{MemoryManagementArch, VmFaultReason}; use crate::{ driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom}, filesystem::vfs::{ @@ -1392,37 +1393,57 @@ impl IndexNode for LockedFATInode { let mut guard: SpinLockGuard = self.0.lock(); match &guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { + let len = core::cmp::min(f.size() as usize, offset + len) - offset; + let buf = &mut buf[0..len]; + if let Some(page_cache) = &guard.page_cache { - let (len, rest) = page_cache.read(offset, buf); + let (cache_len, rest) = page_cache.read(offset, buf); + if rest.is_empty() { - return Ok(len); - } else { - let mut err = None; - let mut ret = len; - for (file_offset, len) in rest { - let buf_offset = file_offset - offset; - match f.read( - &guard.fs.upgrade().unwrap(), - &mut buf[buf_offset..(buf_offset + len)], - file_offset as u64, - ) { - Ok(size) => { - ret += size; - // page_cache.create_pages(offset, &buf[offset..(offset + len)]); - } - Err(e) => { - err = Some(e); - break; - } - } - } - guard.update_metadata(); - if let Some(e) = err { - return Err(e); + return Ok(cache_len); + } + + log::debug!("rest: {:?}", rest); + + let mut err = None; + for (page_index, count) in rest { + let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; + let page_buf: &mut [u8] = page_buf.as_mut(); + + if let Err(e) = f.read( + &guard.fs.upgrade().unwrap(), + page_buf, + (page_index * MMArch::PAGE_SIZE) as u64, + ) { + err = Some(e); + break; + }; + + // 实际要拷贝的内容在文件中的偏移量 + let copy_offset = core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); + // 实际要拷贝的内容的长度 + let copy_len = + core::cmp::min((page_index + count) * MMArch::PAGE_SIZE, offset + len) + - core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); + + let page_buf_offset = if page_index * MMArch::PAGE_SIZE < copy_offset { + copy_offset - page_index * MMArch::PAGE_SIZE } else { - return Ok(ret); - } + 0 + }; + + let buf_offset = if offset < copy_offset { + copy_offset - offset + } else { + 0 + }; + + buf[buf_offset..buf_offset + copy_len].copy_from_slice( + &page_buf[page_buf_offset..page_buf_offset + copy_len], + ); } + + return if let Some(e) = err { Err(e) } else { Ok(len) }; } else { let r = f.read( &guard.fs.upgrade().unwrap(), @@ -1451,17 +1472,49 @@ impl IndexNode for LockedFATInode { _data: SpinLockGuard, ) -> Result { let mut guard: SpinLockGuard = self.0.lock(); + let page_cache = guard.page_cache.clone(); let fs: &Arc = &guard.fs.upgrade().unwrap(); match &mut guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { - let r = f.write(fs, &buf[0..len], offset as u64); - guard.update_metadata(); - return r; + if let Some(page_cache) = page_cache { + let (len, rest) = page_cache.write(offset, buf); + if rest.is_empty() { + return Ok(len); + } else { + let mut err = None; + let mut ret = len; + for (file_offset, len) in rest { + let buf_offset = file_offset - offset; + let sub_buf = &buf[buf_offset..(buf_offset + len)]; + match f.write(fs, sub_buf, file_offset as u64) { + Ok(size) => { + ret += size; + } + Err(e) => { + err = Some(e); + break; + } + } + } + guard.update_metadata(); + if let Some(e) = err { + return Err(e); + } else { + return Ok(ret); + } + } + } else { + let r = f.write(fs, &buf[0..len], offset as u64); + guard.update_metadata(); + return r; + } } + FATDirEntry::Dir(_) => { return Err(SystemError::EISDIR); } + FATDirEntry::UnInit => { error!("FATFS: param: Inode_type uninitialized."); return Err(SystemError::EROFS); diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 7226a1b62..3f4a236c2 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -191,6 +191,7 @@ impl PageCache { } pub fn create_pages(&self, offset: usize, buf: &[u8]) { + log::debug!("create_pages, offset:{offset}, buf_len:{}", buf.len()); let address_space = AddressSpace::current().unwrap(); // TODO 这里直接加锁会死锁,后续需要排查一下 let mut guard = if let Some(guard) = address_space.try_write_irqsave() { @@ -229,6 +230,10 @@ impl PageCache { }; if let Some(cache_page) = unsafe { allocator.allocate_one() } { + // log::debug!( + // "page_offset:{page_offset}, buf_offset:{buf_offset}, sub_len:{sub_len}, buf_len:{len}" + // ); + log::debug!("create page: {:?}", cache_page); unsafe { core::slice::from_raw_parts_mut( MMArch::phys_2_virt(cache_page).unwrap().data() as *mut u8, @@ -237,12 +242,10 @@ impl PageCache { .copy_from_slice(&buf[buf_offset..(buf_offset + sub_len)]); } let page = Arc::new(Page::new(true, cache_page)); - page.write_irqsave().add_flags(PageFlags::PG_LRU); page_manager_lock_irqsave().insert(cache_page, &page); page_reclaimer_lock_irqsave().insert_page(cache_page, &page); cursor.store(page.clone()); - page.write_irqsave().set_page_cache_index( self.self_ref.upgrade(), Some(offset >> MMArch::PAGE_SHIFT), @@ -264,8 +267,9 @@ impl PageCache { /// ## 返回值 /// /// - `usize` 成功读取的长度 - /// - `Vec<(usize, usize)>` 未成功读取的区间的偏移量和长度集合 + /// - `Vec<(usize, usize)>` 未成功读取的区间的起始页号和长度的集合 pub fn read(&self, offset: usize, buf: &mut [u8]) -> (usize, Vec<(usize, usize)>) { + // log::debug!("read offset:{offset}, buf_len:{}", buf.len()); let mut not_exist = Vec::new(); let len = buf.len(); if len == 0 { @@ -297,6 +301,7 @@ impl PageCache { }; if let Some(page) = cursor.load() { + log::debug!("load success: {:?}", page.read_irqsave().phys_address()); let vaddr = unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; @@ -308,17 +313,14 @@ impl PageCache { byte_num += size; } } - } else { - let page_offset = (start_page_offset + i) * MMArch::PAGE_SIZE + page_offset; - if let Some((offset, len)) = not_exist.last_mut() { - if *offset + *len == page_offset { - *len += sub_len; - } else { - not_exist.push((page_offset, sub_len)); - } + } else if let Some((page_offset, count)) = not_exist.last_mut() { + if *page_offset + *count == start_page_offset + i { + *count += 1; } else { - not_exist.push((page_offset, sub_len)); + not_exist.push((start_page_offset + i, 1)); } + } else { + not_exist.push((start_page_offset + i, 1)); } buf_offset += sub_len; From 60e36cadb9720023674b9eba8adaa6b0497f2abb Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 21 Oct 2024 21:36:32 +0800 Subject: [PATCH 03/38] =?UTF-8?q?=E5=AE=8C=E5=96=84create=5Fpages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 50 ++++++++++++++----------- kernel/src/filesystem/vfs/file.rs | 62 +++++++++++-------------------- 2 files changed, 49 insertions(+), 63 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 06bc4c4a5..f43086652 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1419,6 +1419,8 @@ impl IndexNode for LockedFATInode { break; }; + page_cache.create_pages(page_index, page_buf); + // 实际要拷贝的内容在文件中的偏移量 let copy_offset = core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); // 实际要拷贝的内容的长度 @@ -1454,6 +1456,7 @@ impl IndexNode for LockedFATInode { return r; } } + FATDirEntry::Dir(_) => { return Err(SystemError::EISDIR); } @@ -1478,32 +1481,35 @@ impl IndexNode for LockedFATInode { match &mut guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { if let Some(page_cache) = page_cache { - let (len, rest) = page_cache.write(offset, buf); + let (cache_len, rest) = page_cache.write(offset, buf); + if rest.is_empty() { - return Ok(len); - } else { - let mut err = None; - let mut ret = len; - for (file_offset, len) in rest { - let buf_offset = file_offset - offset; - let sub_buf = &buf[buf_offset..(buf_offset + len)]; - match f.write(fs, sub_buf, file_offset as u64) { - Ok(size) => { - ret += size; - } - Err(e) => { - err = Some(e); - break; - } - } - } - guard.update_metadata(); - if let Some(e) = err { - return Err(e); + return Ok(cache_len); + } + + let mut err = None; + for (page_index, count) in rest { + // 实际要写入的内容在文件中的偏移量 + let write_offset = core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); + // 实际要写入的内容的长度 + let write_len = + core::cmp::min((page_index + count) * MMArch::PAGE_SIZE, offset + len) + - core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); + + let buf_offset = if offset < write_offset { + write_offset - offset } else { - return Ok(ret); + 0 + }; + + if let Err(e) = + f.write(fs, &buf[buf_offset..write_len], write_offset as u64) + { + err = Some(e); } } + + return if let Some(e) = err { Err(e) } else { Ok(len) }; } else { let r = f.write(fs, &buf[0..len], offset as u64); guard.update_metadata(); diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 3f4a236c2..797a3063c 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -190,13 +190,17 @@ impl PageCache { self.inode = Some(inode) } - pub fn create_pages(&self, offset: usize, buf: &[u8]) { - log::debug!("create_pages, offset:{offset}, buf_len:{}", buf.len()); + pub fn create_pages(&self, page_index: usize, buf: &[u8]) { + assert!(buf.len() % MMArch::PAGE_SIZE == 0); + + let page_num = buf.len() / MMArch::PAGE_SIZE; + let address_space = AddressSpace::current().unwrap(); // TODO 这里直接加锁会死锁,后续需要排查一下 let mut guard = if let Some(guard) = address_space.try_write_irqsave() { guard } else { + log::debug!("address_space lock failed"); return; }; let mapper = &mut guard.user_mapper.utable; @@ -206,53 +210,31 @@ impl PageCache { if len == 0 { return; } - let start_page_offset = offset >> MMArch::PAGE_SHIFT; - let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; let mut guard = self.xarray.lock(); - let mut cursor = guard.cursor_mut(start_page_offset as u64); + let mut cursor = guard.cursor_mut(page_index as u64); - let mut buf_offset = 0; for i in 0..page_num { - // 第一个页可能需要计算页内偏移 - let page_offset = if i == 0 { - offset % MMArch::PAGE_SIZE - } else { - 0 - }; - - // 第一个页和最后一个页可能不满 - let sub_len = if i == 0 { - min(len, MMArch::PAGE_SIZE - page_offset) - } else if i == page_num - 1 { - (offset + len - 1) % MMArch::PAGE_SIZE + 1 - } else { - MMArch::PAGE_SIZE - }; + let buf_offset = i * MMArch::PAGE_SIZE; if let Some(cache_page) = unsafe { allocator.allocate_one() } { - // log::debug!( - // "page_offset:{page_offset}, buf_offset:{buf_offset}, sub_len:{sub_len}, buf_len:{len}" - // ); log::debug!("create page: {:?}", cache_page); unsafe { core::slice::from_raw_parts_mut( MMArch::phys_2_virt(cache_page).unwrap().data() as *mut u8, MMArch::PAGE_SIZE, - )[page_offset..page_offset + sub_len] - .copy_from_slice(&buf[buf_offset..(buf_offset + sub_len)]); + ) + .copy_from_slice(&buf[buf_offset..buf_offset + MMArch::PAGE_SIZE]); } + let page = Arc::new(Page::new(true, cache_page)); page.write_irqsave().add_flags(PageFlags::PG_LRU); page_manager_lock_irqsave().insert(cache_page, &page); page_reclaimer_lock_irqsave().insert_page(cache_page, &page); + page.write_irqsave() + .set_page_cache_index(self.self_ref.upgrade(), Some(cursor.index() as usize)); + cursor.store(page.clone()); - page.write_irqsave().set_page_cache_index( - self.self_ref.upgrade(), - Some(offset >> MMArch::PAGE_SHIFT), - ); } - - buf_offset += sub_len; cursor.next(); } } @@ -341,6 +323,7 @@ impl PageCache { /// - `usize` 成功写入的长度 /// - `Vec<(usize, usize)>` 未成功写入的区间的偏移量和长度集合 pub fn write(&self, offset: usize, buf: &[u8]) -> (usize, Vec<(usize, usize)>) { + // log::debug!("read offset:{offset}, buf_len:{}", buf.len()); let mut not_exist = Vec::new(); let len = buf.len(); if len == 0 { @@ -383,17 +366,14 @@ impl PageCache { byte_num += size; } } - } else { - let page_offset = (start_page_offset + i) * MMArch::PAGE_SIZE + page_offset; - if let Some((offset, len)) = not_exist.last_mut() { - if *offset + *len == page_offset { - *len += sub_len; - } else { - not_exist.push((page_offset, sub_len)); - } + } else if let Some((page_offset, count)) = not_exist.last_mut() { + if *page_offset + *count == start_page_offset + i { + *count += 1; } else { - not_exist.push((page_offset, sub_len)); + not_exist.push((start_page_offset + i, 1)); } + } else { + not_exist.push((start_page_offset + i, 1)); } buf_offset += sub_len; From 773e36d91f8355fcbb6d4da8cbee9047922dc4fe Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 21 Oct 2024 22:32:31 +0800 Subject: [PATCH 04/38] =?UTF-8?q?=E6=B7=BB=E5=8A=A0read=5Fdirect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 29 ++++++++++++++++++++++++ kernel/src/filesystem/vfs/mod.rs | 38 ++++++++++++++++++++++++++++++++ kernel/src/mm/fault.rs | 18 ++++++++------- 3 files changed, 77 insertions(+), 8 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index f43086652..ae3f255fe 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1946,6 +1946,35 @@ impl IndexNode for LockedFATInode { fn page_cache(&self) -> Option> { self.0.lock().page_cache.clone() } + + fn read_direct( + &self, + offset: usize, + len: usize, + buf: &mut [u8], + _data: SpinLockGuard, + ) -> Result { + let mut guard: SpinLockGuard = self.0.lock(); + match &guard.inode_type { + FATDirEntry::File(f) | FATDirEntry::VolId(f) => { + let r = f.read( + &guard.fs.upgrade().unwrap(), + &mut buf[0..len], + offset as u64, + ); + guard.update_metadata(); + return r; + } + + FATDirEntry::Dir(_) => { + return Err(SystemError::EISDIR); + } + FATDirEntry::UnInit => { + error!("FATFS: param: Inode_type uninitialized."); + return Err(SystemError::EROFS); + } + } + } } impl Default for FATFsInfo { diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 00ce6ba50..c4b2dd949 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -570,6 +570,44 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { ); None } + + /// @brief 在inode的指定偏移量开始,读取指定大小的数据 + /// + /// @param offset 起始位置在Inode中的偏移量 + /// @param len 要读取的字节数 + /// @param buf 缓冲区. 请注意,必须满足@buf.len()>=@len + /// @param _data 各文件系统系统所需私有信息 + /// + /// @return 成功:Ok(读取的字节数) + /// 失败:Err(Posix错误码) + /// + + /// # 在inode的指定偏移量开始,读取指定大小的数据,忽略PageCache + /// + /// ## 参数 + /// + /// - `offset`: 起始位置在Inode中的偏移量 + /// - `len`: 要读取的字节数 + /// - `buf`: 缓冲区 + /// - `_data`: 各文件系统系统所需私有信息 + /// + /// ## 返回值 + /// + /// - `Ok(usize)``: Ok(读取的字节数) + /// - `Err(SystemError)``: Err(Posix错误码) + fn read_direct( + &self, + offset: usize, + len: usize, + buf: &mut [u8], + data: SpinLockGuard, + ) -> Result { + if self.page_cache().is_none() { + return self.read_at(offset, len, buf, data); + } else { + return Err(SystemError::ENOSYS); + } + } } impl DowncastArc for dyn IndexNode { diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index 9bd0f1429..623fb8022 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -659,15 +659,17 @@ impl PageFaultHandler { let new_cache_page = allocator.allocate_one().unwrap(); // (MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8) // .copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE); - file.pread( - file_pgoff * MMArch::PAGE_SIZE, - MMArch::PAGE_SIZE, - core::slice::from_raw_parts_mut( - MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8, + file.inode() + .read_direct( + file_pgoff * MMArch::PAGE_SIZE, MMArch::PAGE_SIZE, - ), - ) - .expect("failed to read file to create pagecache page"); + core::slice::from_raw_parts_mut( + MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8, + MMArch::PAGE_SIZE, + ), + file.private_data.lock(), + ) + .expect("failed to read file to create pagecache page"); let page = Arc::new(Page::new(true, new_cache_page)); pfm.page = Some(page.clone()); From f99aec516cc0b454ff8b6eab6a1f58d947df6859 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 21 Oct 2024 23:52:22 +0800 Subject: [PATCH 05/38] =?UTF-8?q?=E8=A7=A3=E5=86=B3create=5Fpages=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E6=AD=BB=E9=94=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/vfs/file.rs | 78 +++++++++++++++++----------- kernel/src/filesystem/vfs/mount.rs | 10 ++++ kernel/src/filesystem/vfs/syscall.rs | 6 +-- kernel/src/libs/elf.rs | 6 +-- kernel/src/process/exec.rs | 2 +- 5 files changed, 65 insertions(+), 37 deletions(-) diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 797a3063c..4d0d736de 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -196,13 +196,7 @@ impl PageCache { let page_num = buf.len() / MMArch::PAGE_SIZE; let address_space = AddressSpace::current().unwrap(); - // TODO 这里直接加锁会死锁,后续需要排查一下 - let mut guard = if let Some(guard) = address_space.try_write_irqsave() { - guard - } else { - log::debug!("address_space lock failed"); - return; - }; + let mut guard = address_space.write_irqsave(); let mapper = &mut guard.user_mapper.utable; let allocator = mapper.allocator_mut(); @@ -428,29 +422,41 @@ impl File { return Ok(f); } - /// @brief 从文件中读取指定的字节数到buffer中 + /// ## 从文件中读取指定的字节数到buffer中 /// - /// @param len 要读取的字节数 - /// @param buf 目标buffer + /// ### 参数 + /// - `len`: 要读取的字节数 + /// - `buf`: 缓冲区 + /// - `read_direct`: 忽略缓存,直接读取磁盘 /// - /// @return Ok(usize) 成功读取的字节数 - /// @return Err(SystemError) 错误码 - pub fn read(&self, len: usize, buf: &mut [u8]) -> Result { + /// ### 返回值 + /// - `Ok(usize)`: 成功读取的字节数 + /// - `Err(SystemError)`: 错误码 + pub fn read( + &self, + len: usize, + buf: &mut [u8], + read_direct: bool, + ) -> Result { self.do_read( self.offset.load(core::sync::atomic::Ordering::SeqCst), len, buf, true, + read_direct, ) } - /// @brief 从buffer向文件写入指定的字节数的数据 + /// ## 从buffer向文件写入指定的字节数的数据 /// - /// @param len 要写入的字节数 - /// @param buf 源数据buffer + /// ### 参数 + /// - `offset`: 文件偏移量 + /// - `len`: 要写入的字节数 + /// - `buf`: 写入缓冲区 /// - /// @return Ok(usize) 成功写入的字节数 - /// @return Err(SystemError) 错误码 + /// ### 返回值 + /// - `Ok(usize)`: 成功写入的字节数 + /// - `Err(SystemError)`: 错误码 pub fn write(&self, len: usize, buf: &[u8]) -> Result { self.do_write( self.offset.load(core::sync::atomic::Ordering::SeqCst), @@ -469,8 +475,14 @@ impl File { /// /// ### 返回值 /// - `Ok(usize)`: 成功读取的字节数 - pub fn pread(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result { - self.do_read(offset, len, buf, false) + pub fn pread( + &self, + offset: usize, + len: usize, + buf: &mut [u8], + read_direct: bool, + ) -> Result { + self.do_read(offset, len, buf, false, read_direct) } /// ## 从buf向文件中指定的偏移处写入指定的字节数的数据 @@ -492,6 +504,7 @@ impl File { len: usize, buf: &mut [u8], update_offset: bool, + read_direct: bool, ) -> Result { // 先检查本文件在权限等规则下,是否可读取。 self.readable()?; @@ -499,16 +512,21 @@ impl File { return Err(SystemError::ENOBUFS); } - let len = self - .inode - .read_at(offset, len, buf, self.private_data.lock()) - .map_err(|e| { - if e == SystemError::ERESTARTSYS { - SystemError::EINTR - } else { - e - } - })?; + let r = if read_direct { + self.inode + .read_direct(offset, len, buf, self.private_data.lock()) + } else { + self.inode + .read_at(offset, len, buf, self.private_data.lock()) + }; + + let len = r.map_err(|e| { + if e == SystemError::ERESTARTSYS { + SystemError::EINTR + } else { + e + } + })?; if update_offset { self.offset diff --git a/kernel/src/filesystem/vfs/mount.rs b/kernel/src/filesystem/vfs/mount.rs index cc479883b..5cda84e27 100644 --- a/kernel/src/filesystem/vfs/mount.rs +++ b/kernel/src/filesystem/vfs/mount.rs @@ -508,6 +508,16 @@ impl IndexNode for MountFSInode { fn page_cache(&self) -> Option> { self.inner_inode.page_cache() } + + fn read_direct( + &self, + offset: usize, + len: usize, + buf: &mut [u8], + data: SpinLockGuard, + ) -> Result { + self.inner_inode.read_direct(offset, len, buf, data) + } } impl FileSystem for MountFS { diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index 53e674f47..37ba0124f 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -567,7 +567,7 @@ impl Syscall { drop(fd_table_guard); let file = file.unwrap(); - return file.read(buf.len(), buf); + return file.read(buf.len(), buf, false); } /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。 @@ -636,7 +636,7 @@ impl Syscall { drop(fd_table_guard); let file = file.unwrap(); - return file.pread(offset, len, buf); + return file.pread(offset, len, buf, false); } /// # sys_pwrite64 系统调用的实际执行函数 @@ -1552,7 +1552,7 @@ impl Syscall { let file = File::new(inode, FileMode::O_RDONLY)?; - let len = file.read(buf_size, ubuf)?; + let len = file.read(buf_size, ubuf, false)?; return Ok(len); } diff --git a/kernel/src/libs/elf.rs b/kernel/src/libs/elf.rs index 7cbfdb918..a39b107cb 100644 --- a/kernel/src/libs/elf.rs +++ b/kernel/src/libs/elf.rs @@ -341,7 +341,7 @@ impl ElfLoader { while remain > 0 { let read_size = min(remain, buf_size); - file.read(read_size, &mut buf[..read_size])?; + file.read(read_size, &mut buf[..read_size], true)?; // debug!("copy_to_user: vaddr={:?}, read_size = {read_size}", vaddr); unsafe { copy_to_user(vaddr, &buf[..read_size]).map_err(|_| SystemError::EFAULT)?; @@ -448,7 +448,7 @@ impl ElfLoader { .map_err(|_| elf::ParseError::BadOffset(shoff as u64))?; let shdr_buf_size = ehdr.e_shentsize * 2; let mut shdr_buf = vec![0u8; shdr_buf_size as usize]; - file.read(shdr_buf_size as usize, &mut shdr_buf) + file.read(shdr_buf_size as usize, &mut shdr_buf, true) .map_err(|_| elf::ParseError::BadOffset(shoff as u64))?; let mut offset = 0; @@ -481,7 +481,7 @@ impl ElfLoader { data_buf.clear(); data_buf.resize(size, 0); - file.read(size, data_buf) + file.read(size, data_buf, true) .expect("read program header table failed"); let buf = data_buf.get_bytes(0..size)?; diff --git a/kernel/src/process/exec.rs b/kernel/src/process/exec.rs index 12af4c339..dfaacd536 100644 --- a/kernel/src/process/exec.rs +++ b/kernel/src/process/exec.rs @@ -166,7 +166,7 @@ pub fn load_binary_file(param: &mut ExecParam) -> Result Date: Tue, 22 Oct 2024 01:33:24 +0800 Subject: [PATCH 06/38] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=83=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9C=AA=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/Cargo.toml | 2 +- kernel/src/filesystem/fat/fs.rs | 16 +++++++++++++--- kernel/src/filesystem/vfs/file.rs | 4 ---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index b784123b4..3156e1147 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -89,4 +89,4 @@ debug = true # Controls whether the compiler passes `-g` # The release profile, used for `cargo build --release` [profile.release] -debug = true +debug = false diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index ae3f255fe..311146269 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1403,7 +1403,7 @@ impl IndexNode for LockedFATInode { return Ok(cache_len); } - log::debug!("rest: {:?}", rest); + // log::debug!("read rest: {:?}", rest); let mut err = None; for (page_index, count) in rest { @@ -1445,7 +1445,12 @@ impl IndexNode for LockedFATInode { ); } - return if let Some(e) = err { Err(e) } else { Ok(len) }; + return if let Some(e) = err { + Err(e) + } else { + guard.update_metadata(); + Ok(len) + }; } else { let r = f.read( &guard.fs.upgrade().unwrap(), @@ -1509,7 +1514,12 @@ impl IndexNode for LockedFATInode { } } - return if let Some(e) = err { Err(e) } else { Ok(len) }; + return if let Some(e) = err { + Err(e) + } else { + guard.update_metadata(); + Ok(len) + }; } else { let r = f.write(fs, &buf[0..len], offset as u64); guard.update_metadata(); diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 4d0d736de..e181da2de 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -211,7 +211,6 @@ impl PageCache { let buf_offset = i * MMArch::PAGE_SIZE; if let Some(cache_page) = unsafe { allocator.allocate_one() } { - log::debug!("create page: {:?}", cache_page); unsafe { core::slice::from_raw_parts_mut( MMArch::phys_2_virt(cache_page).unwrap().data() as *mut u8, @@ -245,7 +244,6 @@ impl PageCache { /// - `usize` 成功读取的长度 /// - `Vec<(usize, usize)>` 未成功读取的区间的起始页号和长度的集合 pub fn read(&self, offset: usize, buf: &mut [u8]) -> (usize, Vec<(usize, usize)>) { - // log::debug!("read offset:{offset}, buf_len:{}", buf.len()); let mut not_exist = Vec::new(); let len = buf.len(); if len == 0 { @@ -277,7 +275,6 @@ impl PageCache { }; if let Some(page) = cursor.load() { - log::debug!("load success: {:?}", page.read_irqsave().phys_address()); let vaddr = unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; @@ -317,7 +314,6 @@ impl PageCache { /// - `usize` 成功写入的长度 /// - `Vec<(usize, usize)>` 未成功写入的区间的偏移量和长度集合 pub fn write(&self, offset: usize, buf: &[u8]) -> (usize, Vec<(usize, usize)>) { - // log::debug!("read offset:{offset}, buf_len:{}", buf.len()); let mut not_exist = Vec::new(); let len = buf.len(); if len == 0 { From 8365ca34a1971f6d71d30769ed4c40f355285d5c Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Sun, 27 Oct 2024 01:34:10 +0800 Subject: [PATCH 07/38] =?UTF-8?q?=E9=87=8D=E6=9E=84read=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 83 +++++++++++-------------------- kernel/src/filesystem/vfs/file.rs | 59 +++++++++++++++++++--- 2 files changed, 81 insertions(+), 61 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index cb529a0a4..15813c6e7 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1395,64 +1395,39 @@ impl IndexNode for LockedFATInode { let mut guard: SpinLockGuard = self.0.lock(); match &guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { - let len = core::cmp::min(f.size() as usize, offset + len) - offset; - let buf = &mut buf[0..len]; - - if let Some(page_cache) = &guard.page_cache { - let (cache_len, rest) = page_cache.read(offset, buf); - - if rest.is_empty() { - return Ok(cache_len); - } - - // log::debug!("read rest: {:?}", rest); - - let mut err = None; - for (page_index, count) in rest { - let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; - let page_buf: &mut [u8] = page_buf.as_mut(); - - if let Err(e) = f.read( - &guard.fs.upgrade().unwrap(), - page_buf, - (page_index * MMArch::PAGE_SIZE) as u64, - ) { - err = Some(e); - break; - }; - - page_cache.create_pages(page_index, page_buf); - - // 实际要拷贝的内容在文件中的偏移量 - let copy_offset = core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); - // 实际要拷贝的内容的长度 - let copy_len = - core::cmp::min((page_index + count) * MMArch::PAGE_SIZE, offset + len) - - core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); + // let r = f.read( + // &guard.fs.upgrade().unwrap(), + // &mut buf[0..len], + // offset as u64, + // ); + // log::debug!("buf: {buf:?}"); + // guard.update_metadata(); + // return r; + + let len = if offset < f.size() as usize { + core::cmp::min(f.size() as usize, offset + len) - offset + } else { + 0 + }; - let page_buf_offset = if page_index * MMArch::PAGE_SIZE < copy_offset { - copy_offset - page_index * MMArch::PAGE_SIZE - } else { - 0 - }; + if len == 0 { + return Ok(0); + } - let buf_offset = if offset < copy_offset { - copy_offset - offset - } else { - 0 - }; + let buf = &mut buf[0..len]; + // log::debug!( + // "read_at len: {len}, offset: {offset}, f_len:{}", + // f.size() + // ); - buf[buf_offset..buf_offset + copy_len].copy_from_slice( - &page_buf[page_buf_offset..page_buf_offset + copy_len], - ); - } + let read_func = |file_offset: usize, buf: &mut [u8]| { + f.read(&guard.fs.upgrade().unwrap(), buf, file_offset as u64) + }; - return if let Some(e) = err { - Err(e) - } else { - guard.update_metadata(); - Ok(len) - }; + if let Some(page_cache) = &guard.page_cache { + let r = page_cache.read(offset, buf, read_func); + log::debug!("r:{r:?}"); + return r; } else { let r = f.read( &guard.fs.upgrade().unwrap(), diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index e181da2de..56b7116c3 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -204,6 +204,7 @@ impl PageCache { if len == 0 { return; } + let mut guard = self.xarray.lock(); let mut cursor = guard.cursor_mut(page_index as u64); @@ -243,20 +244,27 @@ impl PageCache { /// /// - `usize` 成功读取的长度 /// - `Vec<(usize, usize)>` 未成功读取的区间的起始页号和长度的集合 - pub fn read(&self, offset: usize, buf: &mut [u8]) -> (usize, Vec<(usize, usize)>) { + pub fn read( + &self, + offset: usize, + buf: &mut [u8], + read_func: impl Fn(usize, &mut [u8]) -> Result, + ) -> Result { let mut not_exist = Vec::new(); let len = buf.len(); + log::debug!("offset:{offset}, len:{len}"); if len == 0 { - return (0, not_exist); + return Ok(0); } + let start_page_offset = offset >> MMArch::PAGE_SHIFT; let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; let mut guard = self.xarray.lock(); let mut cursor = guard.cursor_mut(start_page_offset as u64); - let mut byte_num = 0; let mut buf_offset = 0; + let mut ret = 0; for i in 0..page_num { // 第一个页可能需要计算页内偏移 let page_offset = if i == 0 { @@ -282,9 +290,8 @@ impl PageCache { if let Ok(user_reader) = UserBufferReader::new((vaddr.data() + page_offset) as *const u8, sub_len, false) { - if let Ok(size) = user_reader.copy_from_user(sub_buf, 0) { - byte_num += size; - } + user_reader.copy_from_user(sub_buf, 0)?; + ret += sub_len; } } else if let Some((page_offset, count)) = not_exist.last_mut() { if *page_offset + *count == start_page_offset + i { @@ -299,7 +306,45 @@ impl PageCache { buf_offset += sub_len; cursor.next(); } - (byte_num, not_exist) + + drop(cursor); + drop(guard); + + for (page_offset, count) in not_exist { + let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; + read_func(page_offset * MMArch::PAGE_SIZE, page_buf.as_mut())?; + + self.create_pages(page_offset, page_buf.as_mut()); + + // 实际要拷贝的内容在文件中的偏移量 + let copy_offset = core::cmp::max(page_offset * MMArch::PAGE_SIZE, offset); + // 实际要拷贝的内容的长度 + let copy_len = core::cmp::min((page_offset + count) * MMArch::PAGE_SIZE, offset + len) + - copy_offset; + + let page_buf_offset = if page_offset * MMArch::PAGE_SIZE < copy_offset { + copy_offset - page_offset * MMArch::PAGE_SIZE + } else { + 0 + }; + + let buf_offset = if offset < copy_offset { + copy_offset - offset + } else { + 0 + }; + + buf[buf_offset..buf_offset + copy_len] + .copy_from_slice(&page_buf[page_buf_offset..page_buf_offset + copy_len]); + + ret += copy_len; + + // log::debug!("page_offset:{page_offset}, count:{count}"); + // log::debug!("copy_offset:{copy_offset}, copy_len:{copy_len}"); + // log::debug!("buf_offset:{buf_offset}, page_buf_offset:{page_buf_offset}"); + } + + Ok(ret) } /// 向PageCache中写入数据。 From acc821a1faa29e46ca0e842d2c75275362e281f5 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Sun, 27 Oct 2024 03:11:07 +0800 Subject: [PATCH 08/38] =?UTF-8?q?=E9=87=8D=E5=86=99write=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 62 ++++++---------------------- kernel/src/filesystem/vfs/file.rs | 68 ++++++++++++++++++------------- 2 files changed, 51 insertions(+), 79 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 15813c6e7..7fad400fc 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -12,7 +12,6 @@ use alloc::{ vec::Vec, }; -use crate::arch::MMArch; use crate::driver::base::block::gendisk::GenDisk; use crate::driver::base::device::device_number::DeviceNumber; use crate::filesystem::vfs::file::PageCache; @@ -20,7 +19,7 @@ use crate::filesystem::vfs::utils::DName; use crate::filesystem::vfs::{Magic, SpecialNodeData, SuperBlock}; use crate::ipc::pipe::LockedPipeInode; use crate::mm::fault::{PageFaultHandler, PageFaultMessage}; -use crate::mm::{MemoryManagementArch, VmFaultReason}; +use crate::mm::VmFaultReason; use crate::{ driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom}, filesystem::vfs::{ @@ -1395,17 +1394,15 @@ impl IndexNode for LockedFATInode { let mut guard: SpinLockGuard = self.0.lock(); match &guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { - // let r = f.read( - // &guard.fs.upgrade().unwrap(), - // &mut buf[0..len], - // offset as u64, + // log::debug!( + // "read_at len: {len}, offset: {offset}, file_size:{:?}", + // guard.metadata.size // ); - // log::debug!("buf: {buf:?}"); - // guard.update_metadata(); - // return r; - let len = if offset < f.size() as usize { - core::cmp::min(f.size() as usize, offset + len) - offset + let file_size = guard.metadata.size; + + let len = if offset < file_size as usize { + core::cmp::min(file_size as usize, offset + len) - offset } else { 0 }; @@ -1415,10 +1412,6 @@ impl IndexNode for LockedFATInode { } let buf = &mut buf[0..len]; - // log::debug!( - // "read_at len: {len}, offset: {offset}, f_len:{}", - // f.size() - // ); let read_func = |file_offset: usize, buf: &mut [u8]| { f.read(&guard.fs.upgrade().unwrap(), buf, file_offset as u64) @@ -1426,7 +1419,6 @@ impl IndexNode for LockedFATInode { if let Some(page_cache) = &guard.page_cache { let r = page_cache.read(offset, buf, read_func); - log::debug!("r:{r:?}"); return r; } else { let r = f.read( @@ -1463,40 +1455,10 @@ impl IndexNode for LockedFATInode { match &mut guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { if let Some(page_cache) = page_cache { - let (cache_len, rest) = page_cache.write(offset, buf); - - if rest.is_empty() { - return Ok(cache_len); - } - - let mut err = None; - for (page_index, count) in rest { - // 实际要写入的内容在文件中的偏移量 - let write_offset = core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); - // 实际要写入的内容的长度 - let write_len = - core::cmp::min((page_index + count) * MMArch::PAGE_SIZE, offset + len) - - core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); - - let buf_offset = if offset < write_offset { - write_offset - offset - } else { - 0 - }; - - if let Err(e) = - f.write(fs, &buf[buf_offset..write_len], write_offset as u64) - { - err = Some(e); - } - } - - return if let Some(e) = err { - Err(e) - } else { - guard.update_metadata(); - Ok(len) - }; + let write_len = page_cache.write(offset, buf)?; + let old_size = guard.metadata.size; + guard.metadata.size = core::cmp::max(old_size, (offset + write_len) as i64); + return Ok(write_len); } else { let r = f.write(fs, &buf[0..len], offset as u64); guard.update_metadata(); diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 56b7116c3..dd2b1c4b8 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -242,8 +242,8 @@ impl PageCache { /// /// ## 返回值 /// - /// - `usize` 成功读取的长度 - /// - `Vec<(usize, usize)>` 未成功读取的区间的起始页号和长度的集合 + /// - `Ok(usize)` 成功读取的长度 + /// - `Err(SystemError)` 失败返回错误码 pub fn read( &self, offset: usize, @@ -252,7 +252,7 @@ impl PageCache { ) -> Result { let mut not_exist = Vec::new(); let len = buf.len(); - log::debug!("offset:{offset}, len:{len}"); + // log::debug!("offset:{offset}, len:{len}"); if len == 0 { return Ok(0); } @@ -356,22 +356,22 @@ impl PageCache { /// /// ## 返回值 /// - /// - `usize` 成功写入的长度 - /// - `Vec<(usize, usize)>` 未成功写入的区间的偏移量和长度集合 - pub fn write(&self, offset: usize, buf: &[u8]) -> (usize, Vec<(usize, usize)>) { - let mut not_exist = Vec::new(); + /// - `Ok(usize)` 成功读取的长度 + /// - `Err(SystemError)` 失败返回错误码 + pub fn write(&self, offset: usize, buf: &[u8]) -> Result { let len = buf.len(); if len == 0 { - return (0, not_exist); + return Ok(0); } + + // log::debug!("offset:{offset}, len:{len}"); + let start_page_offset = offset >> MMArch::PAGE_SHIFT; let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; - let mut guard = self.xarray.lock(); - let mut cursor = guard.cursor_mut(start_page_offset as u64); - - let mut byte_num = 0; let mut buf_offset = 0; + let mut ret = 0; + for i in 0..page_num { // 第一个页可能需要计算页内偏移 let page_offset = if i == 0 { @@ -389,32 +389,42 @@ impl PageCache { MMArch::PAGE_SIZE }; + let mut guard = self.xarray.lock(); + let mut cursor = guard.cursor_mut(start_page_offset as u64); + + let exist = cursor.load().is_some(); + + drop(cursor); + drop(guard); + + if !exist { + let page_buf = vec![0u8; MMArch::PAGE_SIZE]; + self.create_pages(start_page_offset + i, &page_buf); + } + + let mut guard = self.xarray.lock(); + let mut cursor = guard.cursor_mut(start_page_offset as u64); if let Some(page) = cursor.load() { let vaddr = unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; - if let Ok(mut user_writer) = - UserBufferWriter::new((vaddr.data() + page_offset) as *mut u8, sub_len, false) - { - if let Ok(size) = user_writer.copy_to_user(sub_buf, 0) { - byte_num += size; - } - } - } else if let Some((page_offset, count)) = not_exist.last_mut() { - if *page_offset + *count == start_page_offset + i { - *count += 1; - } else { - not_exist.push((start_page_offset + i, 1)); - } + let mut user_writer = + UserBufferWriter::new((vaddr.data() + page_offset) as *mut u8, sub_len, false)?; + + user_writer.copy_to_user(sub_buf, 0)?; + ret += sub_len; + + // log::debug!( + // "page_offset:{page_offset}, buf_offset:{buf_offset}, sub_len:{sub_len}" + // ); } else { - not_exist.push((start_page_offset + i, 1)); - } + return Err(SystemError::ENOMEM); + }; buf_offset += sub_len; - cursor.next(); } - (byte_num, not_exist) + Ok(ret) } } From 7d13a5b1d5d34762dc267ef6730051fe469d9f70 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Sun, 27 Oct 2024 03:44:01 +0800 Subject: [PATCH 09/38] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=9B=9E=E5=86=99=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 4 ++++ kernel/src/mm/page.rs | 22 +++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 7fad400fc..14bf00c42 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1391,6 +1391,8 @@ impl IndexNode for LockedFATInode { buf: &mut [u8], _data: SpinLockGuard, ) -> Result { + let len = core::cmp::min(len, buf.len()); + let buf = &mut buf[0..len]; let mut guard: SpinLockGuard = self.0.lock(); match &guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { @@ -1448,6 +1450,8 @@ impl IndexNode for LockedFATInode { buf: &[u8], _data: SpinLockGuard, ) -> Result { + let len = core::cmp::min(len, buf.len()); + let buf = &buf[0..len]; let mut guard: SpinLockGuard = self.0.lock(); let page_cache = guard.page_cache.clone(); let fs: &Arc = &guard.fs.upgrade().unwrap(); diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index f3d900697..32612521e 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -245,6 +245,7 @@ impl PageReclaimer { }; } } + let inode = page .read_irqsave() .page_cache @@ -255,16 +256,31 @@ impl PageReclaimer { .unwrap() .upgrade() .unwrap(); + + let len = if let Ok(metadata) = inode.metadata() { + let page_index = page.read_irqsave().index().unwrap(); + let size = metadata.size as usize; + if size < page_index * MMArch::PAGE_SIZE { + 0 + } else { + size - page_index * MMArch::PAGE_SIZE + } + } else { + MMArch::PAGE_SIZE + }; + + // log::debug!("page writeback"); + inode .write_at( - page.read_irqsave().index().unwrap(), - MMArch::PAGE_SIZE, + page.read_irqsave().index().unwrap() * MMArch::PAGE_SIZE, + len, unsafe { core::slice::from_raw_parts( MMArch::phys_2_virt(page.read_irqsave().phys_addr) .unwrap() .data() as *mut u8, - MMArch::PAGE_SIZE, + len, ) }, SpinLock::new(FilePrivateData::Unused).lock(), From 055302128812ecfe420cf2f5cbcfebb2a349cbb7 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 28 Oct 2024 00:05:06 +0800 Subject: [PATCH 10/38] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 14bf00c42..ffe538556 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1409,18 +1409,14 @@ impl IndexNode for LockedFATInode { 0 }; - if len == 0 { - return Ok(0); - } - - let buf = &mut buf[0..len]; - - let read_func = |file_offset: usize, buf: &mut [u8]| { - f.read(&guard.fs.upgrade().unwrap(), buf, file_offset as u64) - }; - if let Some(page_cache) = &guard.page_cache { - let r = page_cache.read(offset, buf, read_func); + let r = page_cache.read( + offset, + &mut buf[0..len], + |file_offset: usize, buf: &mut [u8]| { + f.read(&guard.fs.upgrade().unwrap(), buf, file_offset as u64) + }, + ); return r; } else { let r = f.read( From 63bd233d401cd399637412a69d2178fc9528334d Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Sun, 10 Nov 2024 23:47:01 +0800 Subject: [PATCH 11/38] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 72 +++++++++++----------------- kernel/src/filesystem/vfs/file.rs | 44 +++++++---------- kernel/src/filesystem/vfs/mod.rs | 19 ++++---- kernel/src/filesystem/vfs/syscall.rs | 6 +-- kernel/src/libs/elf.rs | 6 +-- kernel/src/mm/fault.rs | 18 ++++--- kernel/src/process/exec.rs | 4 +- 7 files changed, 72 insertions(+), 97 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index ffe538556..e8ce98eaf 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1384,49 +1384,17 @@ impl FATFsInfo { } impl IndexNode for LockedFATInode { - fn read_at( - &self, - offset: usize, - len: usize, - buf: &mut [u8], - _data: SpinLockGuard, - ) -> Result { - let len = core::cmp::min(len, buf.len()); - let buf = &mut buf[0..len]; - let mut guard: SpinLockGuard = self.0.lock(); + fn read_page_sync(&self, offset: usize, buf: &mut [u8]) -> Result { + let guard: SpinLockGuard = self.0.lock(); + let len = buf.len(); match &guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { - // log::debug!( - // "read_at len: {len}, offset: {offset}, file_size:{:?}", - // guard.metadata.size - // ); - - let file_size = guard.metadata.size; - - let len = if offset < file_size as usize { - core::cmp::min(file_size as usize, offset + len) - offset - } else { - 0 - }; - - if let Some(page_cache) = &guard.page_cache { - let r = page_cache.read( - offset, - &mut buf[0..len], - |file_offset: usize, buf: &mut [u8]| { - f.read(&guard.fs.upgrade().unwrap(), buf, file_offset as u64) - }, - ); - return r; - } else { - let r = f.read( - &guard.fs.upgrade().unwrap(), - &mut buf[0..len], - offset as u64, - ); - guard.update_metadata(); - return r; - } + let r = f.read( + &guard.fs.upgrade().unwrap(), + &mut buf[0..len], + offset as u64, + ); + return r; } FATDirEntry::Dir(_) => { @@ -1439,6 +1407,25 @@ impl IndexNode for LockedFATInode { } } + fn read_at( + &self, + offset: usize, + len: usize, + buf: &mut [u8], + data: SpinLockGuard, + ) -> Result { + let len = core::cmp::min(len, buf.len()); + let buf = &mut buf[0..len]; + + let page_cache = self.0.lock().page_cache.clone(); + if let Some(page_cache) = page_cache { + let r = page_cache.read(offset, &mut buf[0..len]); + return r; + } else { + return self.read_direct(offset, len, buf, data); + } + } + fn write_at( &self, offset: usize, @@ -1901,7 +1888,7 @@ impl IndexNode for LockedFATInode { buf: &mut [u8], _data: SpinLockGuard, ) -> Result { - let mut guard: SpinLockGuard = self.0.lock(); + let guard: SpinLockGuard = self.0.lock(); match &guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { let r = f.read( @@ -1909,7 +1896,6 @@ impl IndexNode for LockedFATInode { &mut buf[0..len], offset as u64, ); - guard.update_metadata(); return r; } diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index f9e883005..5dace20d3 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -257,19 +257,22 @@ impl PageCache { /// /// - `Ok(usize)` 成功读取的长度 /// - `Err(SystemError)` 失败返回错误码 - pub fn read( - &self, - offset: usize, - buf: &mut [u8], - read_func: impl Fn(usize, &mut [u8]) -> Result, - ) -> Result { - let mut not_exist = Vec::new(); - let len = buf.len(); - // log::debug!("offset:{offset}, len:{len}"); + pub fn read(&self, offset: usize, buf: &mut [u8]) -> Result { + let inode = self.inode.upgrade().unwrap(); + let file_size = inode.metadata().unwrap().size; + + let len = if offset < file_size as usize { + core::cmp::min(file_size as usize, offset + buf.len()) - offset + } else { + 0 + }; + if len == 0 { return Ok(0); } + let mut not_exist = Vec::new(); + let start_page_offset = offset >> MMArch::PAGE_SHIFT; let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; @@ -325,7 +328,7 @@ impl PageCache { for (page_offset, count) in not_exist { let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; - read_func(page_offset * MMArch::PAGE_SIZE, page_buf.as_mut())?; + inode.read_page_sync(page_offset * MMArch::PAGE_SIZE, page_buf.as_mut())?; self.create_pages(page_offset, page_buf.as_mut()); @@ -496,18 +499,12 @@ impl File { /// ### 返回值 /// - `Ok(usize)`: 成功读取的字节数 /// - `Err(SystemError)`: 错误码 - pub fn read( - &self, - len: usize, - buf: &mut [u8], - read_direct: bool, - ) -> Result { + pub fn read(&self, len: usize, buf: &mut [u8]) -> Result { self.do_read( self.offset.load(core::sync::atomic::Ordering::SeqCst), len, buf, true, - read_direct, ) } @@ -539,14 +536,8 @@ impl File { /// /// ### 返回值 /// - `Ok(usize)`: 成功读取的字节数 - pub fn pread( - &self, - offset: usize, - len: usize, - buf: &mut [u8], - read_direct: bool, - ) -> Result { - self.do_read(offset, len, buf, false, read_direct) + pub fn pread(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result { + self.do_read(offset, len, buf, false) } /// ## 从buf向文件中指定的偏移处写入指定的字节数的数据 @@ -568,7 +559,6 @@ impl File { len: usize, buf: &mut [u8], update_offset: bool, - read_direct: bool, ) -> Result { // 先检查本文件在权限等规则下,是否可读取。 self.readable()?; @@ -576,7 +566,7 @@ impl File { return Err(SystemError::ENOBUFS); } - let r = if read_direct { + let r = if self.mode().contains(FileMode::O_DIRECT) { self.inode .read_direct(offset, len, buf, self.private_data.lock()) } else { diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 47b8d40b8..16f59fa43 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -128,6 +128,11 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { fn mmap(&self, _start: usize, _len: usize, _offset: usize) -> Result<(), SystemError> { return Err(SystemError::ENOSYS); } + + fn read_page_sync(&self, _offset: usize, _buf: &mut [u8]) -> Result { + return Err(SystemError::ENOSYS); + } + /// @brief 打开文件 /// /// @return 成功:Ok() @@ -600,16 +605,12 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { /// - `Err(SystemError)``: Err(Posix错误码) fn read_direct( &self, - offset: usize, - len: usize, - buf: &mut [u8], - data: SpinLockGuard, + _offset: usize, + _len: usize, + _buf: &mut [u8], + _data: SpinLockGuard, ) -> Result { - if self.page_cache().is_none() { - return self.read_at(offset, len, buf, data); - } else { - return Err(SystemError::ENOSYS); - } + return Err(SystemError::ENOSYS); } } diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index 90b8dc774..ef8220ef7 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -570,7 +570,7 @@ impl Syscall { drop(fd_table_guard); let file = file.unwrap(); - return file.read(buf.len(), buf, false); + return file.read(buf.len(), buf); } /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。 @@ -639,7 +639,7 @@ impl Syscall { drop(fd_table_guard); let file = file.unwrap(); - return file.pread(offset, len, buf, false); + return file.pread(offset, len, buf); } /// # sys_pwrite64 系统调用的实际执行函数 @@ -1575,7 +1575,7 @@ impl Syscall { let file = File::new(inode, FileMode::O_RDONLY)?; - let len = file.read(buf_size, ubuf, false)?; + let len = file.read(buf_size, ubuf)?; return Ok(len); } diff --git a/kernel/src/libs/elf.rs b/kernel/src/libs/elf.rs index a39b107cb..7cbfdb918 100644 --- a/kernel/src/libs/elf.rs +++ b/kernel/src/libs/elf.rs @@ -341,7 +341,7 @@ impl ElfLoader { while remain > 0 { let read_size = min(remain, buf_size); - file.read(read_size, &mut buf[..read_size], true)?; + file.read(read_size, &mut buf[..read_size])?; // debug!("copy_to_user: vaddr={:?}, read_size = {read_size}", vaddr); unsafe { copy_to_user(vaddr, &buf[..read_size]).map_err(|_| SystemError::EFAULT)?; @@ -448,7 +448,7 @@ impl ElfLoader { .map_err(|_| elf::ParseError::BadOffset(shoff as u64))?; let shdr_buf_size = ehdr.e_shentsize * 2; let mut shdr_buf = vec![0u8; shdr_buf_size as usize]; - file.read(shdr_buf_size as usize, &mut shdr_buf, true) + file.read(shdr_buf_size as usize, &mut shdr_buf) .map_err(|_| elf::ParseError::BadOffset(shoff as u64))?; let mut offset = 0; @@ -481,7 +481,7 @@ impl ElfLoader { data_buf.clear(); data_buf.resize(size, 0); - file.read(size, data_buf, true) + file.read(size, data_buf) .expect("read program header table failed"); let buf = data_buf.get_bytes(0..size)?; diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index 4ec75642a..1e763fc55 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -659,17 +659,15 @@ impl PageFaultHandler { let new_cache_page = allocator.allocate_one().unwrap(); // (MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8) // .copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE); - file.inode() - .read_direct( - file_pgoff * MMArch::PAGE_SIZE, + file.pread( + file_pgoff * MMArch::PAGE_SIZE, + MMArch::PAGE_SIZE, + core::slice::from_raw_parts_mut( + MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8, MMArch::PAGE_SIZE, - core::slice::from_raw_parts_mut( - MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8, - MMArch::PAGE_SIZE, - ), - file.private_data.lock(), - ) - .expect("failed to read file to create pagecache page"); + ), + ) + .expect("failed to read file to create pagecache page"); let page = Arc::new(Page::new(true, new_cache_page)); pfm.page = Some(page.clone()); diff --git a/kernel/src/process/exec.rs b/kernel/src/process/exec.rs index dfaacd536..f3f0d810a 100644 --- a/kernel/src/process/exec.rs +++ b/kernel/src/process/exec.rs @@ -121,7 +121,7 @@ impl ExecParam { let inode = ROOT_INODE().lookup(file_path)?; // 读取文件头部,用于判断文件类型 - let file = File::new(inode, FileMode::O_RDONLY)?; + let file = File::new(inode, FileMode::O_RDONLY | FileMode::O_DIRECT)?; Ok(Self { file, @@ -166,7 +166,7 @@ pub fn load_binary_file(param: &mut ExecParam) -> Result Date: Sun, 10 Nov 2024 23:56:10 +0800 Subject: [PATCH 12/38] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dlru=E9=93=BE=E8=A1=A8?= =?UTF-8?q?=E7=BC=A9=E5=87=8F=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/mm/page.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 32612521e..f58183c6f 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -186,20 +186,7 @@ impl PageReclaimer { /// - `count`: 需要缩减的页面数量 pub fn shrink_list(&mut self, count: PageFrameCount) { for _ in 0..count.data() { - let (paddr, page) = self.lru.pop_lru().expect("pagecache is empty"); - let page_cache = page.read_irqsave().page_cache().unwrap(); - for vma in page.read_irqsave().anon_vma() { - let address_space = vma.lock_irqsave().address_space().unwrap(); - let address_space = address_space.upgrade().unwrap(); - let mut guard = address_space.write(); - let mapper = &mut guard.user_mapper.utable; - let virt = vma.lock_irqsave().page_address(&page).unwrap(); - unsafe { - mapper.unmap(virt, false).unwrap().flush(); - } - } - page_cache.remove_page(page.read_irqsave().index().unwrap()); - page_manager_lock_irqsave().remove_page(&paddr); + let (_, page) = self.lru.pop_lru().expect("pagecache is empty"); if page.read_irqsave().flags.contains(PageFlags::PG_DIRTY) { Self::page_writeback(&page, true); } @@ -233,6 +220,7 @@ impl PageReclaimer { let virt = vma.lock_irqsave().page_address(page).unwrap(); if unmap { unsafe { + // 取消页表映射 mapper.unmap(virt, false).unwrap().flush(); } } else { @@ -286,6 +274,12 @@ impl PageReclaimer { SpinLock::new(FilePrivateData::Unused).lock(), ) .unwrap(); + + // 删除页面 + let page_cache = page.read_irqsave().page_cache().unwrap(); + let paddr = page.read_irqsave().phys_address(); + page_cache.remove_page(page.read_irqsave().index().unwrap()); + page_manager_lock_irqsave().remove_page(&paddr); } /// lru脏页刷新 From 668a279945f85f2c10b42d3d35c55f2d13952013 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 11 Nov 2024 21:53:24 +0800 Subject: [PATCH 13/38] =?UTF-8?q?=E4=BF=AE=E6=AD=A3page=5Fwriteback?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/vfs/mod.rs | 11 -------- kernel/src/mm/page.rs | 45 ++++++++++++++------------------ 2 files changed, 19 insertions(+), 37 deletions(-) diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index ee28b2ca1..fd32ae7a6 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -579,17 +579,6 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { None } - /// @brief 在inode的指定偏移量开始,读取指定大小的数据 - /// - /// @param offset 起始位置在Inode中的偏移量 - /// @param len 要读取的字节数 - /// @param buf 缓冲区. 请注意,必须满足@buf.len()>=@len - /// @param _data 各文件系统系统所需私有信息 - /// - /// @return 成功:Ok(读取的字节数) - /// 失败:Err(Posix错误码) - /// - /// # 在inode的指定偏移量开始,读取指定大小的数据,忽略PageCache /// /// ## 参数 diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index f58183c6f..8b820b85b 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -208,11 +208,15 @@ impl PageReclaimer { /// ## 返回值 /// - VmFaultReason: 页面错误处理信息标志 pub fn page_writeback(page: &Arc, unmap: bool) { - if !unmap { - page.write_irqsave().remove_flags(PageFlags::PG_DIRTY); - } + // log::debug!("page writeback: {page:?}"); + + let guard = page.read_irqsave(); + let page_cache = guard.page_cache().unwrap(); + let paddr = guard.phys_address(); + let inode = page_cache.inode().clone().unwrap().upgrade().unwrap(); + let page_index = guard.index().unwrap(); - for vma in page.read_irqsave().anon_vma() { + for vma in guard.anon_vma() { let address_space = vma.lock_irqsave().address_space().unwrap(); let address_space = address_space.upgrade().unwrap(); let mut guard = address_space.write(); @@ -234,19 +238,9 @@ impl PageReclaimer { } } - let inode = page - .read_irqsave() - .page_cache - .clone() - .unwrap() - .inode() - .clone() - .unwrap() - .upgrade() - .unwrap(); + drop(guard); let len = if let Ok(metadata) = inode.metadata() { - let page_index = page.read_irqsave().index().unwrap(); let size = metadata.size as usize; if size < page_index * MMArch::PAGE_SIZE { 0 @@ -257,17 +251,13 @@ impl PageReclaimer { MMArch::PAGE_SIZE }; - // log::debug!("page writeback"); - inode .write_at( - page.read_irqsave().index().unwrap() * MMArch::PAGE_SIZE, + page_index * MMArch::PAGE_SIZE, len, unsafe { core::slice::from_raw_parts( - MMArch::phys_2_virt(page.read_irqsave().phys_addr) - .unwrap() - .data() as *mut u8, + MMArch::phys_2_virt(paddr).unwrap().data() as *mut u8, len, ) }, @@ -275,11 +265,14 @@ impl PageReclaimer { ) .unwrap(); - // 删除页面 - let page_cache = page.read_irqsave().page_cache().unwrap(); - let paddr = page.read_irqsave().phys_address(); - page_cache.remove_page(page.read_irqsave().index().unwrap()); - page_manager_lock_irqsave().remove_page(&paddr); + if unmap { + // 删除页面 + page_cache.remove_page(page_index); + page_manager_lock_irqsave().remove_page(&paddr); + } else { + // 清除标记 + page.write_irqsave().remove_flags(PageFlags::PG_DIRTY); + } } /// lru脏页刷新 From ec98b84dc985f6d78465c35f2b5ef2fb7f1ac7e2 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 11 Nov 2024 23:25:40 +0800 Subject: [PATCH 14/38] =?UTF-8?q?=E6=B7=BB=E5=8A=A0write=5Fdirect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 114 ++++++++++++++--------------- kernel/src/filesystem/vfs/file.rs | 2 +- kernel/src/filesystem/vfs/mod.rs | 75 +++++++++++++------ kernel/src/filesystem/vfs/mount.rs | 30 +++++--- 4 files changed, 126 insertions(+), 95 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index e8ce98eaf..39a45344f 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1384,16 +1384,11 @@ impl FATFsInfo { } impl IndexNode for LockedFATInode { - fn read_page_sync(&self, offset: usize, buf: &mut [u8]) -> Result { + fn read_sync(&self, offset: usize, buf: &mut [u8]) -> Result { let guard: SpinLockGuard = self.0.lock(); - let len = buf.len(); match &guard.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { - let r = f.read( - &guard.fs.upgrade().unwrap(), - &mut buf[0..len], - offset as u64, - ); + let r = f.read(&guard.fs.upgrade().unwrap(), buf, offset as u64); return r; } @@ -1407,6 +1402,27 @@ impl IndexNode for LockedFATInode { } } + fn write_sync(&self, offset: usize, buf: &[u8]) -> Result { + let mut guard: SpinLockGuard = self.0.lock(); + let fs: &Arc = &guard.fs.upgrade().unwrap(); + + match &mut guard.inode_type { + FATDirEntry::File(f) | FATDirEntry::VolId(f) => { + let r = f.write(fs, buf, offset as u64); + return r; + } + + FATDirEntry::Dir(_) => { + return Err(SystemError::EISDIR); + } + + FATDirEntry::UnInit => { + error!("FATFS: param: Inode_type uninitialized."); + return Err(SystemError::EROFS); + } + } + } + fn read_at( &self, offset: usize, @@ -1431,37 +1447,43 @@ impl IndexNode for LockedFATInode { offset: usize, len: usize, buf: &[u8], - _data: SpinLockGuard, + data: SpinLockGuard, ) -> Result { let len = core::cmp::min(len, buf.len()); let buf = &buf[0..len]; - let mut guard: SpinLockGuard = self.0.lock(); - let page_cache = guard.page_cache.clone(); - let fs: &Arc = &guard.fs.upgrade().unwrap(); - match &mut guard.inode_type { - FATDirEntry::File(f) | FATDirEntry::VolId(f) => { - if let Some(page_cache) = page_cache { - let write_len = page_cache.write(offset, buf)?; - let old_size = guard.metadata.size; - guard.metadata.size = core::cmp::max(old_size, (offset + write_len) as i64); - return Ok(write_len); - } else { - let r = f.write(fs, &buf[0..len], offset as u64); - guard.update_metadata(); - return r; - } - } + let page_cache = self.0.lock().page_cache.clone(); + if let Some(page_cache) = page_cache { + let write_len = page_cache.write(offset, buf)?; + let mut guard = self.0.lock(); + let old_size = guard.metadata.size; + guard.metadata.size = core::cmp::max(old_size, (offset + write_len) as i64); + return Ok(write_len); + } else { + return self.write_direct(offset, len, buf, data); + } + } - FATDirEntry::Dir(_) => { - return Err(SystemError::EISDIR); - } + fn read_direct( + &self, + offset: usize, + len: usize, + buf: &mut [u8], + _data: SpinLockGuard, + ) -> Result { + let len = core::cmp::min(len, buf.len()); + self.read_sync(offset, &mut buf[0..len]) + } - FATDirEntry::UnInit => { - error!("FATFS: param: Inode_type uninitialized."); - return Err(SystemError::EROFS); - } - } + fn write_direct( + &self, + offset: usize, + len: usize, + buf: &[u8], + _data: SpinLockGuard, + ) -> Result { + let len = core::cmp::min(len, buf.len()); + self.write_sync(offset, &buf[0..len]) } fn create( @@ -1880,34 +1902,6 @@ impl IndexNode for LockedFATInode { fn page_cache(&self) -> Option> { self.0.lock().page_cache.clone() } - - fn read_direct( - &self, - offset: usize, - len: usize, - buf: &mut [u8], - _data: SpinLockGuard, - ) -> Result { - let guard: SpinLockGuard = self.0.lock(); - match &guard.inode_type { - FATDirEntry::File(f) | FATDirEntry::VolId(f) => { - let r = f.read( - &guard.fs.upgrade().unwrap(), - &mut buf[0..len], - offset as u64, - ); - return r; - } - - FATDirEntry::Dir(_) => { - return Err(SystemError::EISDIR); - } - FATDirEntry::UnInit => { - error!("FATFS: param: Inode_type uninitialized."); - return Err(SystemError::EROFS); - } - } - } } impl Default for FATFsInfo { diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 5dace20d3..797f4a97e 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -328,7 +328,7 @@ impl PageCache { for (page_offset, count) in not_exist { let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; - inode.read_page_sync(page_offset * MMArch::PAGE_SIZE, page_buf.as_mut())?; + inode.read_sync(page_offset * MMArch::PAGE_SIZE, page_buf.as_mut())?; self.create_pages(page_offset, page_buf.as_mut()); diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index fd32ae7a6..054d3388b 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -129,7 +129,11 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { return Err(SystemError::ENOSYS); } - fn read_page_sync(&self, _offset: usize, _buf: &mut [u8]) -> Result { + fn read_sync(&self, _offset: usize, _buf: &mut [u8]) -> Result { + return Err(SystemError::ENOSYS); + } + + fn write_sync(&self, _offset: usize, _buf: &[u8]) -> Result { return Err(SystemError::ENOSYS); } @@ -189,6 +193,52 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { _data: SpinLockGuard, ) -> Result; + /// # 在inode的指定偏移量开始,读取指定大小的数据,忽略PageCache + /// + /// ## 参数 + /// + /// - `offset`: 起始位置在Inode中的偏移量 + /// - `len`: 要读取的字节数 + /// - `buf`: 缓冲区 + /// - `data`: 各文件系统系统所需私有信息 + /// + /// ## 返回值 + /// + /// - `Ok(usize)``: Ok(读取的字节数) + /// - `Err(SystemError)``: Err(Posix错误码) + fn read_direct( + &self, + _offset: usize, + _len: usize, + _buf: &mut [u8], + _data: SpinLockGuard, + ) -> Result { + return Err(SystemError::ENOSYS); + } + + /// # 在inode的指定偏移量开始,写入指定大小的数据,忽略PageCache + /// + /// ## 参数 + /// + /// - `offset`: 起始位置在Inode中的偏移量 + /// - `len`: 要读取的字节数 + /// - `buf`: 缓冲区 + /// - `data`: 各文件系统系统所需私有信息 + /// + /// ## 返回值 + /// + /// - `Ok(usize)``: Ok(读取的字节数) + /// - `Err(SystemError)``: Err(Posix错误码) + fn write_direct( + &self, + _offset: usize, + _len: usize, + _buf: &[u8], + _data: SpinLockGuard, + ) -> Result { + return Err(SystemError::ENOSYS); + } + /// @brief 获取当前inode的状态。 /// /// @return PollStatus结构体 @@ -578,29 +628,6 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync { ); None } - - /// # 在inode的指定偏移量开始,读取指定大小的数据,忽略PageCache - /// - /// ## 参数 - /// - /// - `offset`: 起始位置在Inode中的偏移量 - /// - `len`: 要读取的字节数 - /// - `buf`: 缓冲区 - /// - `_data`: 各文件系统系统所需私有信息 - /// - /// ## 返回值 - /// - /// - `Ok(usize)``: Ok(读取的字节数) - /// - `Err(SystemError)``: Err(Posix错误码) - fn read_direct( - &self, - _offset: usize, - _len: usize, - _buf: &mut [u8], - _data: SpinLockGuard, - ) -> Result { - return Err(SystemError::ENOSYS); - } } impl DowncastArc for dyn IndexNode { diff --git a/kernel/src/filesystem/vfs/mount.rs b/kernel/src/filesystem/vfs/mount.rs index 8afcd88e3..a01866914 100644 --- a/kernel/src/filesystem/vfs/mount.rs +++ b/kernel/src/filesystem/vfs/mount.rs @@ -296,6 +296,26 @@ impl IndexNode for MountFSInode { return self.inner_inode.write_at(offset, len, buf, data); } + fn read_direct( + &self, + offset: usize, + len: usize, + buf: &mut [u8], + data: SpinLockGuard, + ) -> Result { + self.inner_inode.read_direct(offset, len, buf, data) + } + + fn write_direct( + &self, + offset: usize, + len: usize, + buf: &[u8], + data: SpinLockGuard, + ) -> Result { + self.inner_inode.write_direct(offset, len, buf, data) + } + #[inline] fn fs(&self) -> Arc { return self.mount_fs.clone(); @@ -535,16 +555,6 @@ impl IndexNode for MountFSInode { fn page_cache(&self) -> Option> { self.inner_inode.page_cache() } - - fn read_direct( - &self, - offset: usize, - len: usize, - buf: &mut [u8], - data: SpinLockGuard, - ) -> Result { - self.inner_inode.read_direct(offset, len, buf, data) - } } impl FileSystem for MountFS { From 7a3608b2ae604188aad0d22f12e83ecf93b4e1e0 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Wed, 13 Nov 2024 02:52:28 +0800 Subject: [PATCH 15/38] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E9=87=8A=E6=94=BE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/driver/net/dma.rs | 8 ++----- kernel/src/driver/virtio/virtio_impl.rs | 8 ++----- kernel/src/filesystem/vfs/file.rs | 32 +++++++++++++++---------- kernel/src/ipc/shm.rs | 2 +- kernel/src/mm/allocator/page_frame.rs | 28 ++-------------------- kernel/src/mm/page.rs | 32 ++++++++++++++++++------- kernel/src/mm/ucontext.rs | 10 +------- 7 files changed, 51 insertions(+), 69 deletions(-) diff --git a/kernel/src/driver/net/dma.rs b/kernel/src/driver/net/dma.rs index e03fe86a5..fcfe1c948 100644 --- a/kernel/src/driver/net/dma.rs +++ b/kernel/src/driver/net/dma.rs @@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags; use crate::arch::MMArch; use crate::mm::kernel_mapper::KernelMapper; -use crate::mm::page::{page_manager_lock_irqsave, EntryFlags}; +use crate::mm::page::EntryFlags; use crate::mm::{ allocator::page_frame::{ allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame, @@ -61,11 +61,7 @@ pub unsafe fn dma_dealloc(paddr: usize, vaddr: NonNull, pages: usize) -> i32 flusher.flush(); unsafe { - deallocate_page_frames( - PhysPageFrame::new(PhysAddr::new(paddr)), - page_count, - &mut page_manager_lock_irqsave(), - ); + deallocate_page_frames(PhysPageFrame::new(PhysAddr::new(paddr)), page_count); } return 0; } diff --git a/kernel/src/driver/virtio/virtio_impl.rs b/kernel/src/driver/virtio/virtio_impl.rs index 0608a0ce4..878147487 100644 --- a/kernel/src/driver/virtio/virtio_impl.rs +++ b/kernel/src/driver/virtio/virtio_impl.rs @@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags; use crate::arch::MMArch; use crate::mm::kernel_mapper::KernelMapper; -use crate::mm::page::{page_manager_lock_irqsave, EntryFlags}; +use crate::mm::page::EntryFlags; use crate::mm::{ allocator::page_frame::{ allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame, @@ -72,11 +72,7 @@ unsafe impl Hal for HalImpl { flusher.flush(); unsafe { - deallocate_page_frames( - PhysPageFrame::new(PhysAddr::new(paddr)), - page_count, - &mut page_manager_lock_irqsave(), - ); + deallocate_page_frames(PhysPageFrame::new(PhysAddr::new(paddr)), page_count); } return 0; } diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 863208a6f..16c36c2c9 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -157,6 +157,18 @@ impl core::fmt::Debug for PageCache { } } +impl Drop for PageCache { + fn drop(&mut self) { + let xarray = self.xarray.lock_irqsave(); + let mut page_manager = page_manager_lock_irqsave(); + for index in 0..=u64::MAX { + if let Some(page) = xarray.load(index) { + page_manager.remove_page(&page.read_irqsave().phys_address()); + } + } + } +} + impl PageCache { pub fn new(inode: Option>) -> Arc { Arc::new_cyclic(|weak| Self { @@ -177,20 +189,20 @@ impl PageCache { } pub fn add_page(&self, offset: usize, page: &Arc) { - let mut guard = self.xarray.lock(); + let mut guard = self.xarray.lock_irqsave(); let mut cursor = guard.cursor_mut(offset as u64); cursor.store(page.clone()); } pub fn get_page(&self, offset: usize) -> Option> { - let mut guard = self.xarray.lock(); + let mut guard = self.xarray.lock_irqsave(); let mut cursor = guard.cursor_mut(offset as u64); let page = cursor.load().map(|r| (*r).clone()); page } pub fn remove_page(&self, offset: usize) { - let mut guard = self.xarray.lock(); + let mut guard = self.xarray.lock_irqsave(); let mut cursor = guard.cursor_mut(offset as u64); cursor.remove(); } @@ -218,7 +230,7 @@ impl PageCache { return; } - let mut guard = self.xarray.lock(); + let mut guard = self.xarray.lock_irqsave(); let mut cursor = guard.cursor_mut(page_index as u64); for i in 0..page_num { @@ -276,7 +288,7 @@ impl PageCache { let start_page_offset = offset >> MMArch::PAGE_SHIFT; let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; - let mut guard = self.xarray.lock(); + let mut guard = self.xarray.lock_irqsave(); let mut cursor = guard.cursor_mut(start_page_offset as u64); let mut buf_offset = 0; @@ -344,11 +356,7 @@ impl PageCache { 0 }; - let buf_offset = if offset < copy_offset { - copy_offset - offset - } else { - 0 - }; + let buf_offset = copy_offset.saturating_sub(offset); buf[buf_offset..buf_offset + copy_len] .copy_from_slice(&page_buf[page_buf_offset..page_buf_offset + copy_len]); @@ -405,7 +413,7 @@ impl PageCache { MMArch::PAGE_SIZE }; - let mut guard = self.xarray.lock(); + let mut guard = self.xarray.lock_irqsave(); let mut cursor = guard.cursor_mut(start_page_offset as u64); let exist = cursor.load().is_some(); @@ -418,7 +426,7 @@ impl PageCache { self.create_pages(start_page_offset + i, &page_buf); } - let mut guard = self.xarray.lock(); + let mut guard = self.xarray.lock_irqsave(); let mut cursor = guard.cursor_mut(start_page_offset as u64); if let Some(page) = cursor.load() { let vaddr = diff --git a/kernel/src/ipc/shm.rs b/kernel/src/ipc/shm.rs index 56ecdc67c..23136dc15 100644 --- a/kernel/src/ipc/shm.rs +++ b/kernel/src/ipc/shm.rs @@ -445,7 +445,7 @@ impl KernelShm { let page = page_manager_guard.get(&cur_phys.phys_address()).unwrap(); id_set.extend( page.read_irqsave() - .anon_vma() + .vma_set() .iter() .map(|vma| vma.id()) .collect::>(), diff --git a/kernel/src/mm/allocator/page_frame.rs b/kernel/src/mm/allocator/page_frame.rs index 180a2ac25..88da0d388 100644 --- a/kernel/src/mm/allocator/page_frame.rs +++ b/kernel/src/mm/allocator/page_frame.rs @@ -5,8 +5,6 @@ use core::{ use crate::{ arch::{mm::LockedFrameAllocator, MMArch}, - ipc::shm::shm_manager_lock, - libs::spinlock::SpinLockGuard, mm::{MemoryManagementArch, PhysAddr, VirtAddr}, }; @@ -355,30 +353,8 @@ pub unsafe fn allocate_page_frames(count: PageFrameCount) -> Option<(PhysAddr, P /// /// @param frame 要释放的第一个页帧 /// @param count 要释放的页帧数量 (必须是2的n次幂) -pub unsafe fn deallocate_page_frames( - frame: PhysPageFrame, - count: PageFrameCount, - page_manager_guard: &mut SpinLockGuard<'_, crate::mm::page::PageManager>, -) { +pub unsafe fn deallocate_page_frames(frame: PhysPageFrame, count: PageFrameCount) { unsafe { LockedFrameAllocator.free(frame.phys_address(), count); - } - - let mut frame = frame; - for _ in 0..count.data() { - let paddr = frame.phys_address(); - let page = page_manager_guard.get(&paddr); - - if let Some(page) = page { - // 如果page是共享页,将其共享页信息从SHM_MANAGER中删去 - let page_guard = page.read_irqsave(); - if page_guard.shared() { - shm_manager_lock().free_id(&page_guard.shm_id().unwrap()); - } - } - - // 将已回收的物理页面对应的Page从PAGE_MANAGER中删去 - page_manager_guard.remove_page(&paddr); - frame = frame.next(); - } + }; } diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 8b820b85b..6af705ed1 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -19,7 +19,7 @@ use crate::{ exception::ipi::{IpiKind, IpiTarget}, filesystem::vfs::{file::PageCache, FilePrivateData}, init::initcall::INITCALL_CORE, - ipc::shm::ShmId, + ipc::shm::{shm_manager_lock, ShmId}, libs::{ rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, spinlock::{SpinLock, SpinLockGuard}, @@ -29,7 +29,9 @@ use crate::{ }; use super::{ - allocator::page_frame::{FrameAllocator, PageFrameCount}, + allocator::page_frame::{ + deallocate_page_frames, FrameAllocator, PageFrameCount, PhysPageFrame, + }, syscall::ProtFlags, ucontext::LockedVMA, MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, @@ -216,7 +218,7 @@ impl PageReclaimer { let inode = page_cache.inode().clone().unwrap().upgrade().unwrap(); let page_index = guard.index().unwrap(); - for vma in guard.anon_vma() { + for vma in guard.vma_set() { let address_space = vma.lock_irqsave().address_space().unwrap(); let address_space = address_space.upgrade().unwrap(); let mut guard = address_space.write(); @@ -342,7 +344,7 @@ pub struct InnerPage { /// 共享页id(如果是共享页) shm_id: Option, /// 映射到当前page的VMA - anon_vma: HashSet>, + vma_set: HashSet>, /// 标志 flags: PageFlags, /// 页所在的物理页帧号 @@ -360,7 +362,7 @@ impl InnerPage { shared, free_when_zero: dealloc_when_zero, shm_id: None, - anon_vma: HashSet::new(), + vma_set: HashSet::new(), flags: PageFlags::empty(), phys_addr, index: None, @@ -370,13 +372,13 @@ impl InnerPage { /// 将vma加入anon_vma pub fn insert_vma(&mut self, vma: Arc) { - self.anon_vma.insert(vma); + self.vma_set.insert(vma); self.map_count += 1; } /// 将vma从anon_vma中删去 pub fn remove_vma(&mut self, vma: &LockedVMA) { - self.anon_vma.remove(vma); + self.vma_set.remove(vma); self.map_count -= 1; } @@ -427,8 +429,8 @@ impl InnerPage { } #[inline(always)] - pub fn anon_vma(&self) -> &HashSet> { - &self.anon_vma + pub fn vma_set(&self) -> &HashSet> { + &self.vma_set } #[inline(always)] @@ -462,6 +464,18 @@ impl InnerPage { } } +impl Drop for InnerPage { + fn drop(&mut self) { + assert!(self.map_count == 0, "page drop when map count is non-zero"); + if self.shared { + shm_manager_lock().free_id(&self.shm_id.unwrap()); + } + unsafe { + deallocate_page_frames(PhysPageFrame::new(self.phys_addr), PageFrameCount::new(1)) + }; + } +} + #[derive(Debug)] pub struct PageTable { /// 当前页表表示的虚拟地址空间的起始地址 diff --git a/kernel/src/mm/ucontext.rs b/kernel/src/mm/ucontext.rs index 81abd4b0c..016d4d961 100644 --- a/kernel/src/mm/ucontext.rs +++ b/kernel/src/mm/ucontext.rs @@ -841,7 +841,6 @@ impl Drop for UserMapper { deallocate_page_frames( PhysPageFrame::new(self.utable.table().phys()), PageFrameCount::new(1), - &mut page_manager_lock_irqsave(), ) }; } @@ -1171,14 +1170,7 @@ impl LockedVMA { // 如果物理页的anon_vma链表长度为0并且不是共享页,则释放物理页. if page.read_irqsave().can_deallocate() { - unsafe { - drop(page); - deallocate_page_frames( - PhysPageFrame::new(paddr), - PageFrameCount::new(1), - &mut page_manager_guard, - ) - }; + page_manager_guard.remove_page(&paddr); } flusher.consume(flush); From 0ba94831817829265efa1fd9444c51ec7f113c46 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Sun, 17 Nov 2024 02:05:45 +0800 Subject: [PATCH 16/38] =?UTF-8?q?=E5=AE=8C=E5=96=84Page=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BD=93=E5=92=8C=E9=A1=B5=E9=9D=A2=E5=88=9B=E5=BB=BA=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/vfs/file.rs | 64 ++++++++-------- kernel/src/ipc/shm.rs | 7 +- kernel/src/mm/fault.rs | 26 ++++--- kernel/src/mm/page.rs | 121 ++++++++++++++++++++---------- kernel/src/mm/ucontext.rs | 7 +- kernel/src/perf/bpf.rs | 7 +- 6 files changed, 139 insertions(+), 93 deletions(-) diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 16c36c2c9..3dbf42f58 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -13,8 +13,6 @@ use log::error; use system_error::SystemError; use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData}; -use crate::filesystem::eventfd::EventFdInode; -use crate::libs::align::page_align_up; use crate::libs::lazy_init::Lazy; use crate::perf::PerfEventInode; use crate::{ @@ -27,9 +25,7 @@ use crate::{ ipc::pipe::{LockedPipeInode, PipeFsPrivateData}, libs::{rwlock::RwLock, spinlock::SpinLock}, mm::{ - allocator::page_frame::FrameAllocator, page::{page_manager_lock_irqsave, page_reclaimer_lock_irqsave, Page, PageFlags}, - ucontext::AddressSpace, MemoryManagementArch, }, net::{ @@ -39,6 +35,8 @@ use crate::{ process::{cred::Cred, ProcessManager}, syscall::user_access::{UserBufferReader, UserBufferWriter}, }; +use crate::{filesystem::eventfd::EventFdInode, mm::page::FileMapInfo}; +use crate::{libs::align::page_align_up, mm::page::PageType}; /// 文件私有信息的枚举类型 #[derive(Debug, Clone)] @@ -215,47 +213,53 @@ impl PageCache { Ok(()) } - pub fn create_pages(&self, page_index: usize, buf: &[u8]) { + pub fn create_pages(&self, page_index: usize, buf: &[u8]) -> Result<(), SystemError> { assert!(buf.len() % MMArch::PAGE_SIZE == 0); let page_num = buf.len() / MMArch::PAGE_SIZE; - let address_space = AddressSpace::current().unwrap(); - let mut guard = address_space.write_irqsave(); - let mapper = &mut guard.user_mapper.utable; - let allocator = mapper.allocator_mut(); - let len = buf.len(); if len == 0 { - return; + return Ok(()); } let mut guard = self.xarray.lock_irqsave(); let mut cursor = guard.cursor_mut(page_index as u64); + let mut page_manager_guard = page_manager_lock_irqsave(); for i in 0..page_num { let buf_offset = i * MMArch::PAGE_SIZE; - if let Some(cache_page) = unsafe { allocator.allocate_one() } { - unsafe { - core::slice::from_raw_parts_mut( - MMArch::phys_2_virt(cache_page).unwrap().data() as *mut u8, - MMArch::PAGE_SIZE, - ) - .copy_from_slice(&buf[buf_offset..buf_offset + MMArch::PAGE_SIZE]); - } + let page = page_manager_guard.create_page( + true, + PageType::File(FileMapInfo { + page_cache: self + .self_ref + .upgrade() + .expect("failed to get self_arc of pagecache"), + index: page_index, + }), + )?; + + let mut page_guard = page.write_irqsave(); + let paddr = page_guard.phys_address(); + unsafe { + core::slice::from_raw_parts_mut( + MMArch::phys_2_virt(paddr).unwrap().data() as *mut u8, + MMArch::PAGE_SIZE, + ) + .copy_from_slice(&buf[buf_offset..buf_offset + MMArch::PAGE_SIZE]); + } - let page = Arc::new(Page::new(true, cache_page)); - page.write_irqsave().add_flags(PageFlags::PG_LRU); - page_manager_lock_irqsave().insert(cache_page, &page); - page_reclaimer_lock_irqsave().insert_page(cache_page, &page); - page.write_irqsave() - .set_page_cache_index(self.self_ref.upgrade(), Some(cursor.index() as usize)); + page_guard.add_flags(PageFlags::PG_LRU); + page_reclaimer_lock_irqsave().insert_page(paddr, &page); + + cursor.store(page.clone()); - cursor.store(page.clone()); - } cursor.next(); } + + Ok(()) } /// 从PageCache中读取数据。 @@ -342,7 +346,7 @@ impl PageCache { let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; inode.read_sync(page_offset * MMArch::PAGE_SIZE, page_buf.as_mut())?; - self.create_pages(page_offset, page_buf.as_mut()); + self.create_pages(page_offset, page_buf.as_mut())?; // 实际要拷贝的内容在文件中的偏移量 let copy_offset = core::cmp::max(page_offset * MMArch::PAGE_SIZE, offset); @@ -423,7 +427,7 @@ impl PageCache { if !exist { let page_buf = vec![0u8; MMArch::PAGE_SIZE]; - self.create_pages(start_page_offset + i, &page_buf); + self.create_pages(start_page_offset + i, &page_buf)?; } let mut guard = self.xarray.lock_irqsave(); @@ -443,7 +447,7 @@ impl PageCache { // "page_offset:{page_offset}, buf_offset:{buf_offset}, sub_len:{sub_len}" // ); } else { - return Err(SystemError::ENOMEM); + return Err(SystemError::EIO); }; buf_offset += sub_len; diff --git a/kernel/src/ipc/shm.rs b/kernel/src/ipc/shm.rs index 23136dc15..3c9353253 100644 --- a/kernel/src/ipc/shm.rs +++ b/kernel/src/ipc/shm.rs @@ -7,7 +7,7 @@ use crate::{ }, mm::{ allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame}, - page::{page_manager_lock_irqsave, Page}, + page::{page_manager_lock_irqsave, Page, PageType}, PhysAddr, }, process::{Pid, ProcessManager}, @@ -165,10 +165,9 @@ impl ShmManager { let mut page_manager_guard = page_manager_lock_irqsave(); let mut cur_phys = PhysPageFrame::new(phys_page.0); for _ in 0..page_count.data() { - let page = Arc::new(Page::new(true, cur_phys.phys_address())); + let page = Arc::new(Page::new(true, cur_phys.phys_address(), PageType::Shared)); page.write_irqsave().set_shm_id(shm_id); - let paddr = cur_phys.phys_address(); - page_manager_guard.insert(paddr, &page); + page_manager_guard.insert(&page)?; cur_phys = cur_phys.next(); } diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index 1e763fc55..acdf65c48 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -22,7 +22,7 @@ use crate::mm::MemoryManagementArch; use super::{ allocator::page_frame::FrameAllocator, - page::{page_reclaimer_lock_irqsave, Page, PageFlags}, + page::{page_reclaimer_lock_irqsave, FileMapInfo, Page, PageFlags, PageType}, }; bitflags! { @@ -314,7 +314,8 @@ impl PageFaultHandler { } let cow_page_phys = cow_page_phys.unwrap(); - let cow_page = Arc::new(Page::new(false, cow_page_phys)); + let cow_page = Arc::new(Page::copy(cache_page.read_irqsave(), cow_page_phys)); + cow_page.write_irqsave().set_shared(false); pfm.cow_page = Some(cow_page.clone()); //复制PageCache内容到新的页内 @@ -329,11 +330,7 @@ impl PageFaultHandler { let mut page_manager_guard = page_manager_lock_irqsave(); // 新页加入页管理器中 - page_manager_guard.insert(cow_page_phys, &cow_page); - cow_page.write_irqsave().set_page_cache_index( - cache_page.read_irqsave().page_cache(), - cache_page.read_irqsave().index(), - ); + page_manager_guard.insert(&cow_page).expect("insert failed"); ret = ret.union(Self::finish_fault(pfm)); @@ -669,16 +666,21 @@ impl PageFaultHandler { ) .expect("failed to read file to create pagecache page"); - let page = Arc::new(Page::new(true, new_cache_page)); + let page = page_manager_lock_irqsave() + .create_page( + true, + PageType::File(FileMapInfo { + page_cache: page_cache.clone(), + index: file_pgoff, + }), + ) + .expect("failed to create page"); pfm.page = Some(page.clone()); page.write_irqsave().add_flags(PageFlags::PG_LRU); - page_manager_lock_irqsave().insert(new_cache_page, &page); + page_reclaimer_lock_irqsave().insert_page(new_cache_page, &page); page_cache.add_page(file_pgoff, &page); - - page.write_irqsave() - .set_page_cache_index(Some(page_cache), Some(file_pgoff)); } ret } diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 6af705ed1..d5b61b7a6 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -93,13 +93,35 @@ impl PageManager { .clone() } - pub fn insert(&mut self, paddr: PhysAddr, page: &Arc) { - self.phys2page.insert(paddr, page.clone()); + pub fn insert(&mut self, page: &Arc) -> Result, SystemError> { + let phys = page.read_irqsave().phys_address(); + if !self.phys2page.contains_key(&phys) { + self.phys2page.insert(phys, page.clone()); + Ok(page.clone()) + } else { + log::error!("phys page: {phys:?} already exists."); + Err(SystemError::EINVAL) + } } pub fn remove_page(&mut self, paddr: &PhysAddr) { self.phys2page.remove(paddr); } + + pub fn create_page( + &mut self, + shared: bool, + page_type: PageType, + ) -> Result, SystemError> { + if let Some(cache_page) = unsafe { LockedFrameAllocator.allocate_one() } { + let page = Arc::new(Page::new(shared, cache_page, page_type)); + page.write_irqsave().add_flags(PageFlags::PG_LRU); + self.insert(&page) + } else { + log::debug!("allocate failed"); + Err(SystemError::ENOMEM) + } + } } pub static mut PAGE_RECLAIMER: Option> = None; @@ -213,10 +235,15 @@ impl PageReclaimer { // log::debug!("page writeback: {page:?}"); let guard = page.read_irqsave(); - let page_cache = guard.page_cache().unwrap(); + let (page_cache, page_index) = match guard.page_type() { + PageType::File(info) => (info.page_cache.clone(), info.index), + _ => { + log::warn!("try to writeback a non-file page"); + return; + } + }; let paddr = guard.phys_address(); let inode = page_cache.inode().clone().unwrap().upgrade().unwrap(); - let page_index = guard.index().unwrap(); for vma in guard.vma_set() { let address_space = vma.lock_irqsave().address_space().unwrap(); @@ -316,8 +343,17 @@ pub struct Page { } impl Page { - pub fn new(shared: bool, phys_addr: PhysAddr) -> Self { - let inner = InnerPage::new(shared, phys_addr); + pub fn new(shared: bool, phys_addr: PhysAddr, page_type: PageType) -> Self { + let inner = InnerPage::new(shared, phys_addr, page_type); + Self { + inner: RwLock::new(inner), + } + } + + pub fn copy(old_guard: RwLockReadGuard, new_phys: PhysAddr) -> Page { + let shared = old_guard.shared(); + let page_type = old_guard.page_type().clone(); + let inner = InnerPage::new(shared, new_phys, page_type); Self { inner: RwLock::new(inner), } @@ -349,13 +385,12 @@ pub struct InnerPage { flags: PageFlags, /// 页所在的物理页帧号 phys_addr: PhysAddr, - /// 在pagecache中的偏移 - index: Option, - page_cache: Option>, + /// 页面类型 + page_type: PageType, } impl InnerPage { - pub fn new(shared: bool, phys_addr: PhysAddr) -> Self { + pub fn new(shared: bool, phys_addr: PhysAddr, page_type: PageType) -> Self { let dealloc_when_zero = !shared; Self { map_count: 0, @@ -365,8 +400,7 @@ impl InnerPage { vma_set: HashSet::new(), flags: PageFlags::empty(), phys_addr, - index: None, - page_cache: None, + page_type, } } @@ -391,33 +425,27 @@ impl InnerPage { self.shared } - pub fn shm_id(&self) -> Option { - self.shm_id + pub fn set_shared(&mut self, shared: bool) { + self.shared = shared; } - pub fn index(&self) -> Option { - self.index + pub fn shm_id(&self) -> Option { + self.shm_id } pub fn page_cache(&self) -> Option> { - self.page_cache.clone() - } - - pub fn set_page_cache(&mut self, page_cache: Option>) { - self.page_cache = page_cache; + match &self.page_type { + PageType::File(info) => Some(info.page_cache.clone()), + _ => None, + } } - pub fn set_index(&mut self, index: Option) { - self.index = index; + pub fn page_type(&self) -> &PageType { + &self.page_type } - pub fn set_page_cache_index( - &mut self, - page_cache: Option>, - index: Option, - ) { - self.page_cache = page_cache; - self.index = index; + pub fn set_page_type(&mut self, page_type: PageType) { + self.page_type = page_type; } pub fn set_shm_id(&mut self, shm_id: ShmId) { @@ -476,6 +504,22 @@ impl Drop for InnerPage { } } +#[derive(Debug, Clone)] +pub enum PageType { + Uninit, + Anonymous, + File(FileMapInfo), + Shared, + Other, +} + +#[derive(Debug, Clone)] +pub struct FileMapInfo { + pub page_cache: Arc, + /// 在pagecache中的偏移 + pub index: usize, +} + #[derive(Debug)] pub struct PageTable { /// 当前页表表示的虚拟地址空间的起始地址 @@ -652,16 +696,9 @@ impl PageTable { let mut page_manager_guard = page_manager_lock_irqsave(); let old_phys = entry.address().unwrap(); let old_page = page_manager_guard.get_unwrap(&old_phys); - let new_page = - Arc::new(Page::new(old_page.read_irqsave().shared(), phys)); - if let Some(ref page_cache) = old_page.read_irqsave().page_cache() { - new_page.write_irqsave().set_page_cache_index( - Some(page_cache.clone()), - old_page.read_irqsave().index(), - ); - } - - page_manager_guard.insert(phys, &new_page); + let new_page = Arc::new(Page::copy(old_page.read_irqsave(), phys)); + + page_manager_guard.insert(&new_page).unwrap(); let old_phys = entry.address().unwrap(); let frame = MMArch::phys_2_virt(phys).unwrap().data() as *mut u8; frame.copy_from_nonoverlapping( @@ -1209,7 +1246,9 @@ impl PageMapper { let mut page_manager_guard: SpinLockGuard<'static, PageManager> = page_manager_lock_irqsave(); if !page_manager_guard.contains(&phys) { - page_manager_guard.insert(phys, &Arc::new(Page::new(false, phys))) + page_manager_guard + .insert(&Arc::new(Page::new(false, phys, PageType::Uninit))) + .unwrap(); } drop(page_manager_guard); return self.map_phys(virt, phys, flags); diff --git a/kernel/src/mm/ucontext.rs b/kernel/src/mm/ucontext.rs index 016d4d961..5871ae038 100644 --- a/kernel/src/mm/ucontext.rs +++ b/kernel/src/mm/ucontext.rs @@ -35,7 +35,7 @@ use super::{ allocator::page_frame::{ deallocate_page_frames, PageFrameCount, PhysPageFrame, VirtPageFrame, VirtPageFrameIter, }, - page::{EntryFlags, Flusher, InactiveFlusher, Page, PageFlushAll}, + page::{EntryFlags, Flusher, InactiveFlusher, Page, PageFlushAll, PageType}, syscall::{MadvFlags, MapFlags, MremapFlags, ProtFlags}, MemoryManagementArch, PageTableKind, VirtAddr, VirtRegion, VmFlags, }; @@ -1653,7 +1653,10 @@ impl VMA { pub fn page_address(&self, page: &Arc) -> Result { let page_guard = page.read_irqsave(); - let index = page_guard.index().unwrap(); + let index = match page_guard.page_type() { + PageType::File(info) => info.index, + _ => return Err(SystemError::EINVAL), + }; if index >= self.file_pgoff.unwrap() { let address = self.region.start + ((index - self.file_pgoff.unwrap()) << MMArch::PAGE_SHIFT); diff --git a/kernel/src/perf/bpf.rs b/kernel/src/perf/bpf.rs index b283b2e54..f3c8ef419 100644 --- a/kernel/src/perf/bpf.rs +++ b/kernel/src/perf/bpf.rs @@ -8,7 +8,7 @@ use crate::include::bindings::linux_bpf::{ }; use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use crate::mm::allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame}; -use crate::mm::page::{page_manager_lock_irqsave, Page}; +use crate::mm::page::{page_manager_lock_irqsave, Page, PageType}; use crate::mm::{MemoryManagementArch, PhysAddr}; use crate::perf::util::{LostSamples, PerfProbeArgs, PerfSample, SampleHeader}; use alloc::string::String; @@ -239,9 +239,8 @@ impl BpfPerfEvent { let mut page_manager_guard = page_manager_lock_irqsave(); let mut cur_phys = PhysPageFrame::new(phy_addr); for i in 0..page_count.data() { - let page = Arc::new(Page::new(true, cur_phys.phys_address())); - let paddr = cur_phys.phys_address(); - page_manager_guard.insert(paddr, &page); + let page = Arc::new(Page::new(true, cur_phys.phys_address(), PageType::Other)); + page_manager_guard.insert(&page)?; data.page_cache.add_page(i, &page); cur_phys = cur_phys.next(); } From 8c8051dab1f34b513f6de60d9a1125af9270ce79 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Sun, 17 Nov 2024 03:03:44 +0800 Subject: [PATCH 17/38] =?UTF-8?q?=E4=BC=98=E5=8C=96PageCache=E7=9A=84drop?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/vfs/file.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 3dbf42f58..03a387adb 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -157,12 +157,19 @@ impl core::fmt::Debug for PageCache { impl Drop for PageCache { fn drop(&mut self) { + // 尝试获取文件大小并计算页数量 + let file_page_num = || -> Option { + let size = self.inode()?.upgrade()?.metadata().ok()?.size; + (page_align_up(size.try_into().ok()?) >> MMArch::PAGE_SHIFT) + .try_into() + .ok() + }; + + let page_num = file_page_num().unwrap_or((i64::MAX as u64 >> MMArch::PAGE_SHIFT) + 1); let xarray = self.xarray.lock_irqsave(); let mut page_manager = page_manager_lock_irqsave(); - for index in 0..=u64::MAX { - if let Some(page) = xarray.load(index) { - page_manager.remove_page(&page.read_irqsave().phys_address()); - } + for (_, page) in xarray.range(0..page_num) { + page_manager.remove_page(&page.read_irqsave().phys_address()); } } } From 839bef9c3ce0789cbd1c86528302a97506775aed Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Tue, 19 Nov 2024 00:52:58 +0800 Subject: [PATCH 18/38] =?UTF-8?q?PageCache=E6=94=B9=E4=B8=BAHashMap?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/vfs/file.rs | 89 +++++++++---------------------- 1 file changed, 25 insertions(+), 64 deletions(-) diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 03a387adb..81f6956ec 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -8,7 +8,7 @@ use alloc::{ sync::{Arc, Weak}, vec::Vec, }; -use kdepends::xarray::XArray; +use hashbrown::HashMap; use log::error; use system_error::SystemError; @@ -133,42 +133,18 @@ impl FileMode { } /// 页面缓存 +#[derive(Debug)] pub struct PageCache { - xarray: SpinLock>>, + pages: SpinLock>>, inode: Lazy>, self_ref: Weak, } -impl core::fmt::Debug for PageCache { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct("PageCache") - .field( - "xarray", - &self - .xarray - .lock() - .range(0..((MMArch::PAGE_ADDRESS_SIZE >> MMArch::PAGE_SHIFT) as u64)) - .map(|(_, r)| (*r).clone()) - .collect::>>(), - ) - .finish() - } -} - impl Drop for PageCache { fn drop(&mut self) { - // 尝试获取文件大小并计算页数量 - let file_page_num = || -> Option { - let size = self.inode()?.upgrade()?.metadata().ok()?.size; - (page_align_up(size.try_into().ok()?) >> MMArch::PAGE_SHIFT) - .try_into() - .ok() - }; - - let page_num = file_page_num().unwrap_or((i64::MAX as u64 >> MMArch::PAGE_SHIFT) + 1); - let xarray = self.xarray.lock_irqsave(); + let guard = self.pages.lock_irqsave(); let mut page_manager = page_manager_lock_irqsave(); - for (_, page) in xarray.range(0..page_num) { + for page in guard.values() { page_manager.remove_page(&page.read_irqsave().phys_address()); } } @@ -177,7 +153,7 @@ impl Drop for PageCache { impl PageCache { pub fn new(inode: Option>) -> Arc { Arc::new_cyclic(|weak| Self { - xarray: SpinLock::new(XArray::new()), + pages: SpinLock::new(HashMap::new()), inode: { let v: Lazy> = Lazy::new(); if let Some(inode) = inode { @@ -194,22 +170,18 @@ impl PageCache { } pub fn add_page(&self, offset: usize, page: &Arc) { - let mut guard = self.xarray.lock_irqsave(); - let mut cursor = guard.cursor_mut(offset as u64); - cursor.store(page.clone()); + let mut guard = self.pages.lock_irqsave(); + guard.insert(offset, page.clone()); } pub fn get_page(&self, offset: usize) -> Option> { - let mut guard = self.xarray.lock_irqsave(); - let mut cursor = guard.cursor_mut(offset as u64); - let page = cursor.load().map(|r| (*r).clone()); - page + let guard = self.pages.lock_irqsave(); + guard.get(&offset).cloned() } - pub fn remove_page(&self, offset: usize) { - let mut guard = self.xarray.lock_irqsave(); - let mut cursor = guard.cursor_mut(offset as u64); - cursor.remove(); + pub fn remove_page(&self, offset: usize) -> Option> { + let mut guard = self.pages.lock_irqsave(); + guard.remove(&offset) } pub fn set_inode(&self, inode: Weak) -> Result<(), SystemError> { @@ -230,11 +202,10 @@ impl PageCache { return Ok(()); } - let mut guard = self.xarray.lock_irqsave(); - let mut cursor = guard.cursor_mut(page_index as u64); + let mut guard = self.pages.lock_irqsave(); let mut page_manager_guard = page_manager_lock_irqsave(); - for i in 0..page_num { + for i in page_index..page_index + page_num { let buf_offset = i * MMArch::PAGE_SIZE; let page = page_manager_guard.create_page( @@ -259,11 +230,9 @@ impl PageCache { } page_guard.add_flags(PageFlags::PG_LRU); - page_reclaimer_lock_irqsave().insert_page(paddr, &page); - - cursor.store(page.clone()); + guard.insert(i, page.clone()); - cursor.next(); + page_reclaimer_lock_irqsave().insert_page(paddr, &page); } Ok(()) @@ -299,12 +268,11 @@ impl PageCache { let start_page_offset = offset >> MMArch::PAGE_SHIFT; let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; - let mut guard = self.xarray.lock_irqsave(); - let mut cursor = guard.cursor_mut(start_page_offset as u64); + let guard = self.pages.lock_irqsave(); let mut buf_offset = 0; let mut ret = 0; - for i in 0..page_num { + for i in start_page_offset..start_page_offset + page_num { // 第一个页可能需要计算页内偏移 let page_offset = if i == 0 { offset % MMArch::PAGE_SIZE @@ -321,7 +289,7 @@ impl PageCache { MMArch::PAGE_SIZE }; - if let Some(page) = cursor.load() { + if let Some(page) = guard.get(&i) { let vaddr = unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; @@ -343,10 +311,8 @@ impl PageCache { } buf_offset += sub_len; - cursor.next(); } - drop(cursor); drop(guard); for (page_offset, count) in not_exist { @@ -407,7 +373,7 @@ impl PageCache { let mut buf_offset = 0; let mut ret = 0; - for i in 0..page_num { + for i in start_page_offset..start_page_offset + page_num { // 第一个页可能需要计算页内偏移 let page_offset = if i == 0 { offset % MMArch::PAGE_SIZE @@ -424,12 +390,8 @@ impl PageCache { MMArch::PAGE_SIZE }; - let mut guard = self.xarray.lock_irqsave(); - let mut cursor = guard.cursor_mut(start_page_offset as u64); - - let exist = cursor.load().is_some(); - - drop(cursor); + let guard = self.pages.lock_irqsave(); + let exist = guard.get(&i).is_some(); drop(guard); if !exist { @@ -437,9 +399,8 @@ impl PageCache { self.create_pages(start_page_offset + i, &page_buf)?; } - let mut guard = self.xarray.lock_irqsave(); - let mut cursor = guard.cursor_mut(start_page_offset as u64); - if let Some(page) = cursor.load() { + let guard = self.pages.lock_irqsave(); + if let Some(page) = guard.get(&i) { let vaddr = unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; From da469569cf02fdcd69e36780c995c653bfdc9ec9 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Tue, 19 Nov 2024 01:41:40 +0800 Subject: [PATCH 19/38] =?UTF-8?q?=E4=BF=AE=E6=AD=A3PageCache=E8=AF=BB?= =?UTF-8?q?=E5=86=99=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/vfs/file.rs | 54 +++++++++++++++++-------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 81f6956ec..e09aa0b14 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -142,6 +142,7 @@ pub struct PageCache { impl Drop for PageCache { fn drop(&mut self) { + log::debug!("page cache drop"); let guard = self.pages.lock_irqsave(); let mut page_manager = page_manager_lock_irqsave(); for page in guard.values() { @@ -192,7 +193,7 @@ impl PageCache { Ok(()) } - pub fn create_pages(&self, page_index: usize, buf: &[u8]) -> Result<(), SystemError> { + pub fn create_pages(&self, start_page_index: usize, buf: &[u8]) -> Result<(), SystemError> { assert!(buf.len() % MMArch::PAGE_SIZE == 0); let page_num = buf.len() / MMArch::PAGE_SIZE; @@ -205,8 +206,9 @@ impl PageCache { let mut guard = self.pages.lock_irqsave(); let mut page_manager_guard = page_manager_lock_irqsave(); - for i in page_index..page_index + page_num { + for i in 0..page_num { let buf_offset = i * MMArch::PAGE_SIZE; + let page_index = start_page_index + i; let page = page_manager_guard.create_page( true, @@ -230,7 +232,7 @@ impl PageCache { } page_guard.add_flags(PageFlags::PG_LRU); - guard.insert(i, page.clone()); + guard.insert(page_index, page.clone()); page_reclaimer_lock_irqsave().insert_page(paddr, &page); } @@ -265,14 +267,16 @@ impl PageCache { let mut not_exist = Vec::new(); - let start_page_offset = offset >> MMArch::PAGE_SHIFT; - let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; + let start_page_index = offset >> MMArch::PAGE_SHIFT; + let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_index; let guard = self.pages.lock_irqsave(); let mut buf_offset = 0; let mut ret = 0; - for i in start_page_offset..start_page_offset + page_num { + for i in 0..page_num { + let page_index = start_page_index + i; + // 第一个页可能需要计算页内偏移 let page_offset = if i == 0 { offset % MMArch::PAGE_SIZE @@ -289,7 +293,7 @@ impl PageCache { MMArch::PAGE_SIZE }; - if let Some(page) = guard.get(&i) { + if let Some(page) = guard.get(&page_index) { let vaddr = unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; @@ -300,14 +304,14 @@ impl PageCache { user_reader.copy_from_user(sub_buf, 0)?; ret += sub_len; } - } else if let Some((page_offset, count)) = not_exist.last_mut() { - if *page_offset + *count == start_page_offset + i { + } else if let Some((index, count)) = not_exist.last_mut() { + if *index + *count == page_index { *count += 1; } else { - not_exist.push((start_page_offset + i, 1)); + not_exist.push((page_index, 1)); } } else { - not_exist.push((start_page_offset + i, 1)); + not_exist.push((page_index, 1)); } buf_offset += sub_len; @@ -315,20 +319,20 @@ impl PageCache { drop(guard); - for (page_offset, count) in not_exist { + for (page_index, count) in not_exist { let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; - inode.read_sync(page_offset * MMArch::PAGE_SIZE, page_buf.as_mut())?; + inode.read_sync(page_index * MMArch::PAGE_SIZE, page_buf.as_mut())?; - self.create_pages(page_offset, page_buf.as_mut())?; + self.create_pages(page_index, page_buf.as_mut())?; // 实际要拷贝的内容在文件中的偏移量 - let copy_offset = core::cmp::max(page_offset * MMArch::PAGE_SIZE, offset); + let copy_offset = core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); // 实际要拷贝的内容的长度 - let copy_len = core::cmp::min((page_offset + count) * MMArch::PAGE_SIZE, offset + len) + let copy_len = core::cmp::min((page_index + count) * MMArch::PAGE_SIZE, offset + len) - copy_offset; - let page_buf_offset = if page_offset * MMArch::PAGE_SIZE < copy_offset { - copy_offset - page_offset * MMArch::PAGE_SIZE + let page_buf_offset = if page_index * MMArch::PAGE_SIZE < copy_offset { + copy_offset - page_index * MMArch::PAGE_SIZE } else { 0 }; @@ -367,13 +371,15 @@ impl PageCache { // log::debug!("offset:{offset}, len:{len}"); - let start_page_offset = offset >> MMArch::PAGE_SHIFT; - let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_offset; + let start_page_index = offset >> MMArch::PAGE_SHIFT; + let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_index; let mut buf_offset = 0; let mut ret = 0; - for i in start_page_offset..start_page_offset + page_num { + for i in 0..page_num { + let page_index = start_page_index + i; + // 第一个页可能需要计算页内偏移 let page_offset = if i == 0 { offset % MMArch::PAGE_SIZE @@ -391,16 +397,16 @@ impl PageCache { }; let guard = self.pages.lock_irqsave(); - let exist = guard.get(&i).is_some(); + let exist = guard.get(&page_index).is_some(); drop(guard); if !exist { let page_buf = vec![0u8; MMArch::PAGE_SIZE]; - self.create_pages(start_page_offset + i, &page_buf)?; + self.create_pages(page_index, &page_buf)?; } let guard = self.pages.lock_irqsave(); - if let Some(page) = guard.get(&i) { + if let Some(page) = guard.get(&page_index) { let vaddr = unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; From 67039ada7013a34af409fc8198cc61e370190b59 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Tue, 19 Nov 2024 03:17:09 +0800 Subject: [PATCH 20/38] =?UTF-8?q?=E5=AE=8C=E5=96=84fat=E5=85=83=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=9A=84=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 37 ++++++++++++++++++++++++------- kernel/src/filesystem/vfs/file.rs | 31 ++++++++++++++++++++++++++ kernel/src/mm/page.rs | 4 ++++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 3a3b05fb2..e7c56debf 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -129,9 +129,8 @@ pub struct FATInode { } impl FATInode { - /// @brief 更新当前inode的元数据 - pub fn update_metadata(&mut self) { - // todo: 更新文件的访问时间等信息 + /// 将inode的元数据与磁盘同步 + pub fn synchronize_metadata(&mut self) { match &self.inode_type { FATDirEntry::File(f) | FATDirEntry::VolId(f) => { self.metadata.size = f.size() as i64; @@ -146,6 +145,19 @@ impl FATInode { }; } + /// 更新inode的元数据 + pub fn update_metadata(&mut self, size: Option) { + if let Some(new_size) = size { + self.metadata.size = new_size; + } + self.update_time(); + } + + /// 更新访问时间 + pub fn update_time(&mut self) { + log::warn!("update_time has not yet been implemented"); + } + fn find(&mut self, name: &str) -> Result, SystemError> { match &self.inode_type { FATDirEntry::Dir(d) => { @@ -234,7 +246,7 @@ impl LockedFATInode { inode.0.lock().self_ref = Arc::downgrade(&inode); - inode.0.lock().update_metadata(); + inode.0.lock().synchronize_metadata(); return inode; } @@ -1438,6 +1450,7 @@ impl IndexNode for LockedFATInode { let page_cache = self.0.lock().page_cache.clone(); if let Some(page_cache) = page_cache { let r = page_cache.read(offset, &mut buf[0..len]); + // self.0.lock_irqsave().update_metadata(); return r; } else { return self.read_direct(offset, len, buf, data); @@ -1459,7 +1472,7 @@ impl IndexNode for LockedFATInode { let write_len = page_cache.write(offset, buf)?; let mut guard = self.0.lock(); let old_size = guard.metadata.size; - guard.metadata.size = core::cmp::max(old_size, (offset + write_len) as i64); + guard.update_metadata(Some(core::cmp::max(old_size, (offset + write_len) as i64))); return Ok(write_len); } else { return self.write_direct(offset, len, buf, data); @@ -1474,7 +1487,9 @@ impl IndexNode for LockedFATInode { _data: SpinLockGuard, ) -> Result { let len = core::cmp::min(len, buf.len()); - self.read_sync(offset, &mut buf[0..len]) + let r = self.read_sync(offset, &mut buf[0..len]); + // self.0.lock_irqsave().update_metadata(); + return r; } fn write_direct( @@ -1485,7 +1500,9 @@ impl IndexNode for LockedFATInode { _data: SpinLockGuard, ) -> Result { let len = core::cmp::min(len, buf.len()); - self.write_sync(offset, &buf[0..len]) + let r = self.write_sync(offset, &buf[0..len]); + // self.0.lock_irqsave().update_metadata(); + return r; } fn create( @@ -1544,6 +1561,10 @@ impl IndexNode for LockedFATInode { Ok(()) } fn resize(&self, len: usize) -> Result<(), SystemError> { + if let Some(page_cache) = self.page_cache() { + return page_cache.resize(len); + } + let mut guard: SpinLockGuard = self.0.lock(); let fs: &Arc = &guard.fs.upgrade().unwrap(); let old_size = guard.metadata.size as usize; @@ -1575,7 +1596,7 @@ impl IndexNode for LockedFATInode { file.truncate(fs, len as u64)?; } } - guard.update_metadata(); + guard.synchronize_metadata(); return Ok(()); } FATDirEntry::Dir(_) => return Err(SystemError::ENOSYS), diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index e09aa0b14..8d47d1d70 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -428,6 +428,37 @@ impl PageCache { } Ok(ret) } + + pub fn resize(&self, len: usize) -> Result<(), SystemError> { + let page_num = page_align_up(len) / MMArch::PAGE_SIZE; + + let mut guard = self.pages.lock_irqsave(); + let mut reclaimer = page_reclaimer_lock_irqsave(); + for (_i, page) in guard.drain_filter(|index, _page| *index >= page_num) { + let _ = reclaimer.remove_page(&page.read_irqsave().phys_address()); + } + + if page_num > 0 { + let last_page_index = page_num - 1; + let last_len = len - last_page_index * MMArch::PAGE_SIZE; + if let Some(page) = guard.get(&last_page_index) { + let vaddr = + unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; + + unsafe { + core::slice::from_raw_parts_mut( + (vaddr.data() + last_len) as *mut u8, + MMArch::PAGE_SIZE - last_len, + ) + .fill(0) + }; + } else { + return Err(SystemError::EIO); + } + } + + Ok(()) + } } /// @brief 抽象文件结构体 diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index d5b61b7a6..dc3185e9a 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -204,6 +204,10 @@ impl PageReclaimer { self.lru.put(paddr, page.clone()); } + pub fn remove_page(&mut self, paddr: &PhysAddr) -> Option> { + self.lru.pop(paddr) + } + /// lru链表缩减 /// ## 参数 /// From 49ab468cd5ca6ea90064c92accedf86c25864363 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Tue, 19 Nov 2024 03:26:24 +0800 Subject: [PATCH 21/38] =?UTF-8?q?=E5=85=81=E8=AE=B8execve=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E6=96=87=E4=BB=B6=E6=97=B6=E7=BC=93=E5=AD=98=E5=88=B0?= =?UTF-8?q?PageCache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/process/exec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/src/process/exec.rs b/kernel/src/process/exec.rs index f3f0d810a..12af4c339 100644 --- a/kernel/src/process/exec.rs +++ b/kernel/src/process/exec.rs @@ -121,7 +121,7 @@ impl ExecParam { let inode = ROOT_INODE().lookup(file_path)?; // 读取文件头部,用于判断文件类型 - let file = File::new(inode, FileMode::O_RDONLY | FileMode::O_DIRECT)?; + let file = File::new(inode, FileMode::O_RDONLY)?; Ok(Self { file, From bac195a0857b9ceb27ae3a95751c2c737bb8e989 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Thu, 21 Nov 2024 01:39:54 +0800 Subject: [PATCH 22/38] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/vfs/file.rs | 39 ++---- kernel/src/ipc/shm.rs | 20 +-- kernel/src/mm/fault.rs | 37 ++--- kernel/src/mm/page.rs | 221 ++++++++++++++++++++++++------ kernel/src/perf/bpf.rs | 23 ++-- 5 files changed, 222 insertions(+), 118 deletions(-) diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 8d47d1d70..adf3af1f6 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -13,8 +13,8 @@ use log::error; use system_error::SystemError; use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData}; -use crate::libs::lazy_init::Lazy; use crate::perf::PerfEventInode; +use crate::{arch::mm::LockedFrameAllocator, libs::lazy_init::Lazy}; use crate::{ arch::MMArch, driver::{ @@ -33,7 +33,6 @@ use crate::{ socket::SocketInode, }, process::{cred::Cred, ProcessManager}, - syscall::user_access::{UserBufferReader, UserBufferWriter}, }; use crate::{filesystem::eventfd::EventFdInode, mm::page::FileMapInfo}; use crate::{libs::align::page_align_up, mm::page::PageType}; @@ -210,7 +209,7 @@ impl PageCache { let buf_offset = i * MMArch::PAGE_SIZE; let page_index = start_page_index + i; - let page = page_manager_guard.create_page( + let page = page_manager_guard.create_one_page( true, PageType::File(FileMapInfo { page_cache: self @@ -219,22 +218,16 @@ impl PageCache { .expect("failed to get self_arc of pagecache"), index: page_index, }), + PageFlags::PG_LRU, + &mut LockedFrameAllocator, )?; let mut page_guard = page.write_irqsave(); - let paddr = page_guard.phys_address(); unsafe { - core::slice::from_raw_parts_mut( - MMArch::phys_2_virt(paddr).unwrap().data() as *mut u8, - MMArch::PAGE_SIZE, - ) - .copy_from_slice(&buf[buf_offset..buf_offset + MMArch::PAGE_SIZE]); + page_guard.copy_from_slice(&buf[buf_offset..buf_offset + MMArch::PAGE_SIZE]); } - page_guard.add_flags(PageFlags::PG_LRU); guard.insert(page_index, page.clone()); - - page_reclaimer_lock_irqsave().insert_page(paddr, &page); } Ok(()) @@ -294,16 +287,13 @@ impl PageCache { }; if let Some(page) = guard.get(&page_index) { - let vaddr = - unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; - - if let Ok(user_reader) = - UserBufferReader::new((vaddr.data() + page_offset) as *const u8, sub_len, false) - { - user_reader.copy_from_user(sub_buf, 0)?; - ret += sub_len; + unsafe { + sub_buf.copy_from_slice( + &page.read_irqsave().as_slice()[page_offset..page_offset + sub_len], + ); } + ret += sub_len; } else if let Some((index, count)) = not_exist.last_mut() { if *index + *count == page_index { *count += 1; @@ -407,14 +397,13 @@ impl PageCache { let guard = self.pages.lock_irqsave(); if let Some(page) = guard.get(&page_index) { - let vaddr = - unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; - let mut user_writer = - UserBufferWriter::new((vaddr.data() + page_offset) as *mut u8, sub_len, false)?; + unsafe { + page.write_irqsave().as_slice_mut()[page_offset..page_offset + sub_len] + .copy_from_slice(sub_buf); + } - user_writer.copy_to_user(sub_buf, 0)?; ret += sub_len; // log::debug!( diff --git a/kernel/src/ipc/shm.rs b/kernel/src/ipc/shm.rs index 3c9353253..6ea4dd4dd 100644 --- a/kernel/src/ipc/shm.rs +++ b/kernel/src/ipc/shm.rs @@ -7,14 +7,14 @@ use crate::{ }, mm::{ allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame}, - page::{page_manager_lock_irqsave, Page, PageType}, + page::{page_manager_lock_irqsave, PageFlags, PageType}, PhysAddr, }, process::{Pid, ProcessManager}, syscall::user_access::{UserBufferReader, UserBufferWriter}, time::PosixTimeSpec, }; -use alloc::{sync::Arc, vec::Vec}; +use alloc::vec::Vec; use core::sync::atomic::{compiler_fence, Ordering}; use hashbrown::{HashMap, HashSet}; use ida::IdAllocator; @@ -159,20 +159,20 @@ impl ShmManager { // 分配共享内存页面 let page_count = PageFrameCount::from_bytes(page_align_up(size)).unwrap(); - let phys_page = - unsafe { LockedFrameAllocator.allocate(page_count) }.ok_or(SystemError::EINVAL)?; // 创建共享内存page,并添加到PAGE_MANAGER中 let mut page_manager_guard = page_manager_lock_irqsave(); - let mut cur_phys = PhysPageFrame::new(phys_page.0); - for _ in 0..page_count.data() { - let page = Arc::new(Page::new(true, cur_phys.phys_address(), PageType::Shared)); + let (paddr, pages) = page_manager_guard.create_pages( + true, + PageType::Shared, + PageFlags::empty(), + &mut LockedFrameAllocator, + page_count, + )?; + for page in pages { page.write_irqsave().set_shm_id(shm_id); - page_manager_guard.insert(&page)?; - cur_phys = cur_phys.next(); } // 创建共享内存信息结构体 - let paddr = phys_page.0; let kern_ipc_perm = KernIpcPerm { id: shm_id, key, diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index acdf65c48..b11120cc6 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -22,7 +22,7 @@ use crate::mm::MemoryManagementArch; use super::{ allocator::page_frame::FrameAllocator, - page::{page_reclaimer_lock_irqsave, FileMapInfo, Page, PageFlags, PageType}, + page::{FileMapInfo, Page, PageFlags, PageType}, }; bitflags! { @@ -308,29 +308,15 @@ impl PageFaultHandler { let cache_page = pfm.page.clone().unwrap(); let mapper = &mut pfm.mapper; - let cow_page_phys = mapper.allocator_mut().allocate_one(); - if cow_page_phys.is_none() { + let mut page_manager_guard = page_manager_lock_irqsave(); + if let Ok(page) = page_manager_guard.copy_page( + &cache_page.read_irqsave().phys_address(), + mapper.allocator_mut(), + ) { + pfm.cow_page = Some(page.clone()); + } else { return VmFaultReason::VM_FAULT_OOM; } - let cow_page_phys = cow_page_phys.unwrap(); - - let cow_page = Arc::new(Page::copy(cache_page.read_irqsave(), cow_page_phys)); - cow_page.write_irqsave().set_shared(false); - pfm.cow_page = Some(cow_page.clone()); - - //复制PageCache内容到新的页内 - let new_frame = MMArch::phys_2_virt(cow_page_phys).unwrap(); - (new_frame.data() as *mut u8).copy_from_nonoverlapping( - MMArch::phys_2_virt(cache_page.read_irqsave().phys_address()) - .unwrap() - .data() as *mut u8, - MMArch::PAGE_SIZE, - ); - - let mut page_manager_guard = page_manager_lock_irqsave(); - - // 新页加入页管理器中 - page_manager_guard.insert(&cow_page).expect("insert failed"); ret = ret.union(Self::finish_fault(pfm)); @@ -667,19 +653,18 @@ impl PageFaultHandler { .expect("failed to read file to create pagecache page"); let page = page_manager_lock_irqsave() - .create_page( + .create_one_page( true, PageType::File(FileMapInfo { page_cache: page_cache.clone(), index: file_pgoff, }), + PageFlags::PG_LRU, + allocator, ) .expect("failed to create page"); pfm.page = Some(page.clone()); - page.write_irqsave().add_flags(PageFlags::PG_LRU); - - page_reclaimer_lock_irqsave().insert_page(new_cache_page, &page); page_cache.add_page(file_pgoff, &page); } ret diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index dc3185e9a..1ad2d14cd 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -1,4 +1,4 @@ -use alloc::string::ToString; +use alloc::{string::ToString, vec::Vec}; use core::{ fmt::{self, Debug, Error, Formatter}, marker::PhantomData, @@ -76,6 +76,7 @@ impl PageManager { } } + #[allow(dead_code)] pub fn contains(&self, paddr: &PhysAddr) -> bool { self.phys2page.contains_key(paddr) } @@ -93,7 +94,7 @@ impl PageManager { .clone() } - pub fn insert(&mut self, page: &Arc) -> Result, SystemError> { + fn insert(&mut self, page: &Arc) -> Result, SystemError> { let phys = page.read_irqsave().phys_address(); if !self.phys2page.contains_key(&phys) { self.phys2page.insert(phys, page.clone()); @@ -108,19 +109,96 @@ impl PageManager { self.phys2page.remove(paddr); } - pub fn create_page( + /// # 创建一个新页面并加入管理器 + /// + /// ## 参数 + /// + /// - `shared`: 是否共享 + /// - `page_type`: 页面类型 + /// - `flags`: 页面标志 + /// - `allocator`: 物理页帧分配器 + /// + /// ## 返回值 + /// + /// - `Ok(Arc)`: 新页面 + /// - `Err(SystemError)`: 错误码 + pub fn create_one_page( &mut self, shared: bool, page_type: PageType, + flags: PageFlags, + allocator: &mut dyn FrameAllocator, ) -> Result, SystemError> { - if let Some(cache_page) = unsafe { LockedFrameAllocator.allocate_one() } { - let page = Arc::new(Page::new(shared, cache_page, page_type)); - page.write_irqsave().add_flags(PageFlags::PG_LRU); - self.insert(&page) - } else { - log::debug!("allocate failed"); - Err(SystemError::ENOMEM) + self.create_pages(shared, page_type, flags, allocator, PageFrameCount::new(1))? + .1 + .first() + .ok_or(SystemError::ENOMEM) + .cloned() + } + + /// # 创建新页面并加入管理器 + /// + /// ## 参数 + /// + /// - `shared`: 是否共享 + /// - `page_type`: 页面类型 + /// - `flags`: 页面标志 + /// - `allocator`: 物理页帧分配器 + /// - `count`: 页面数量 + /// + /// ## 返回值 + /// + /// - `Ok((PhysAddr, Vec>))`: 页面起始物理地址,新页面集合 + /// - `Err(SystemError)`: 错误码 + pub fn create_pages( + &mut self, + shared: bool, + page_type: PageType, + flags: PageFlags, + allocator: &mut dyn FrameAllocator, + count: PageFrameCount, + ) -> Result<(PhysAddr, Vec>), SystemError> { + compiler_fence(Ordering::SeqCst); + let (start_paddr, count) = unsafe { allocator.allocate(count).ok_or(SystemError::ENOMEM)? }; + compiler_fence(Ordering::SeqCst); + + unsafe { + let vaddr = MMArch::phys_2_virt(start_paddr).unwrap(); + MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE * count.data()); + } + + let mut cur_phys = PhysPageFrame::new(start_paddr); + let mut ret = Vec::new(); + for _ in 0..count.data() { + let page = Page::new(shared, cur_phys.phys_address(), page_type.clone(), flags); + self.insert(&page)?; + ret.push(page); + cur_phys = cur_phys.next(); } + Ok((start_paddr, ret)) + } + + /// # 拷贝管理器中原有页面并加入管理器,同时拷贝原页面内容 + /// + /// ## 参数 + /// + /// - `old_phys`: 原页面的物理地址 + /// - `allocator`: 物理页帧分配器 + /// + /// ## 返回值 + /// + /// - `Ok(Arc)`: 新页面 + /// - `Err(SystemError)`: 错误码 + pub fn copy_page( + &mut self, + old_phys: &PhysAddr, + allocator: &mut dyn FrameAllocator, + ) -> Result, SystemError> { + let old_page = self.get(old_phys).ok_or(SystemError::EINVAL)?; + let paddr = unsafe { allocator.allocate_one().ok_or(SystemError::ENOMEM)? }; + let page = Page::copy(old_page.read_irqsave(), paddr)?; + self.insert(&page)?; + Ok(page) } } @@ -347,20 +425,58 @@ pub struct Page { } impl Page { - pub fn new(shared: bool, phys_addr: PhysAddr, page_type: PageType) -> Self { - let inner = InnerPage::new(shared, phys_addr, page_type); - Self { + /// # 创建新页面 + /// + /// ## 参数 + /// + /// - `shared`: 是否共享 + /// - `phys_addr`: 物理地址 + /// - `page_type`: 页面类型 + /// - `flags`: 页面标志 + /// + /// ## 返回值 + /// + /// - `Arc`: 新页面 + fn new(shared: bool, phys_addr: PhysAddr, page_type: PageType, flags: PageFlags) -> Arc { + let inner = InnerPage::new(shared, phys_addr, page_type, flags); + let page = Arc::new(Self { inner: RwLock::new(inner), - } + }); + if page.read_irqsave().flags == PageFlags::PG_LRU { + page_reclaimer_lock_irqsave().insert_page(phys_addr, &page); + }; + page } - pub fn copy(old_guard: RwLockReadGuard, new_phys: PhysAddr) -> Page { + /// # 拷贝页面及内容 + /// + /// ## 参数 + /// + /// - `old_guard`: 源页面的读守卫 + /// - `new_phys`: 新页面的物理地址 + /// + /// ## 返回值 + /// + /// - `Ok(Arc)`: 新页面 + /// - `Err(SystemError)`: 错误码 + fn copy( + old_guard: RwLockReadGuard, + new_phys: PhysAddr, + ) -> Result, SystemError> { let shared = old_guard.shared(); let page_type = old_guard.page_type().clone(); - let inner = InnerPage::new(shared, new_phys, page_type); - Self { - inner: RwLock::new(inner), + let flags = *old_guard.flags(); + let inner = InnerPage::new(shared, new_phys, page_type, flags); + unsafe { + let old_vaddr = + MMArch::phys_2_virt(old_guard.phys_address()).ok_or(SystemError::EFAULT)?; + let new_vaddr = MMArch::phys_2_virt(new_phys).ok_or(SystemError::EFAULT)?; + (new_vaddr.data() as *mut u8) + .copy_from_nonoverlapping(old_vaddr.data() as *mut u8, MMArch::PAGE_SIZE); } + Ok(Arc::new(Self { + inner: RwLock::new(inner), + })) } pub fn read_irqsave(&self) -> RwLockReadGuard { @@ -394,7 +510,7 @@ pub struct InnerPage { } impl InnerPage { - pub fn new(shared: bool, phys_addr: PhysAddr, page_type: PageType) -> Self { + pub fn new(shared: bool, phys_addr: PhysAddr, page_type: PageType, flags: PageFlags) -> Self { let dealloc_when_zero = !shared; Self { map_count: 0, @@ -402,7 +518,7 @@ impl InnerPage { free_when_zero: dealloc_when_zero, shm_id: None, vma_set: HashSet::new(), - flags: PageFlags::empty(), + flags, phys_addr, page_type, } @@ -494,13 +610,42 @@ impl InnerPage { pub fn phys_address(&self) -> PhysAddr { self.phys_addr } + + pub unsafe fn as_slice(&self) -> &[u8] { + core::slice::from_raw_parts( + MMArch::phys_2_virt(self.phys_addr).unwrap().data() as *const u8, + MMArch::PAGE_SIZE, + ) + } + + pub unsafe fn as_slice_mut(&mut self) -> &mut [u8] { + core::slice::from_raw_parts_mut( + MMArch::phys_2_virt(self.phys_addr).unwrap().data() as *mut u8, + MMArch::PAGE_SIZE, + ) + } + + pub unsafe fn copy_from_slice(&mut self, slice: &[u8]) { + assert_eq!( + slice.len(), + MMArch::PAGE_SIZE, + "length of slice not match PAGE_SIZE" + ); + core::slice::from_raw_parts_mut( + MMArch::phys_2_virt(self.phys_addr).unwrap().data() as *mut u8, + MMArch::PAGE_SIZE, + ) + .copy_from_slice(slice); + } } impl Drop for InnerPage { fn drop(&mut self) { assert!(self.map_count == 0, "page drop when map count is non-zero"); if self.shared { - shm_manager_lock().free_id(&self.shm_id.unwrap()); + if let Some(shm_id) = self.shm_id { + shm_manager_lock().free_id(&shm_id); + } } unsafe { deallocate_page_frames(PhysPageFrame::new(self.phys_addr), PageFrameCount::new(1)) @@ -699,16 +844,7 @@ impl PageTable { let phys = allocator.allocate_one()?; let mut page_manager_guard = page_manager_lock_irqsave(); let old_phys = entry.address().unwrap(); - let old_page = page_manager_guard.get_unwrap(&old_phys); - let new_page = Arc::new(Page::copy(old_page.read_irqsave(), phys)); - - page_manager_guard.insert(&new_page).unwrap(); - let old_phys = entry.address().unwrap(); - let frame = MMArch::phys_2_virt(phys).unwrap().data() as *mut u8; - frame.copy_from_nonoverlapping( - MMArch::phys_2_virt(old_phys).unwrap().data() as *mut u8, - MMArch::PAGE_SIZE, - ); + page_manager_guard.copy_page(&old_phys, allocator).ok()?; new_table.set_entry(i, PageEntry::new(phys, entry.flags())); } } @@ -1238,23 +1374,18 @@ impl PageMapper { virt: VirtAddr, flags: EntryFlags, ) -> Option> { - compiler_fence(Ordering::SeqCst); - let phys: PhysAddr = self.frame_allocator.allocate_one()?; - compiler_fence(Ordering::SeqCst); - - unsafe { - let vaddr = MMArch::phys_2_virt(phys).unwrap(); - MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE); - } - let mut page_manager_guard: SpinLockGuard<'static, PageManager> = page_manager_lock_irqsave(); - if !page_manager_guard.contains(&phys) { - page_manager_guard - .insert(&Arc::new(Page::new(false, phys, PageType::Uninit))) - .unwrap(); - } + let page = page_manager_guard + .create_one_page( + false, + PageType::Uninit, + PageFlags::empty(), + &mut self.frame_allocator, + ) + .ok()?; drop(page_manager_guard); + let phys = page.read_irqsave().phys_address(); return self.map_phys(virt, phys, flags); } diff --git a/kernel/src/perf/bpf.rs b/kernel/src/perf/bpf.rs index f3c8ef419..3f7c1da28 100644 --- a/kernel/src/perf/bpf.rs +++ b/kernel/src/perf/bpf.rs @@ -7,8 +7,8 @@ use crate::include::bindings::linux_bpf::{ perf_event_header, perf_event_mmap_page, perf_event_type, }; use crate::libs::spinlock::{SpinLock, SpinLockGuard}; -use crate::mm::allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame}; -use crate::mm::page::{page_manager_lock_irqsave, Page, PageType}; +use crate::mm::allocator::page_frame::{PageFrameCount, PhysPageFrame}; +use crate::mm::page::{page_manager_lock_irqsave, PageFlags, PageType}; use crate::mm::{MemoryManagementArch, PhysAddr}; use crate::perf::util::{LostSamples, PerfProbeArgs, PerfSample, SampleHeader}; use alloc::string::String; @@ -232,17 +232,16 @@ impl BpfPerfEvent { } pub fn do_mmap(&self, _start: usize, len: usize, offset: usize) -> Result<()> { let mut data = self.data.lock(); - // alloc page frame - let (phy_addr, page_count) = - unsafe { LockedFrameAllocator.allocate(PageFrameCount::new(len / PAGE_SIZE)) } - .ok_or(SystemError::ENOSPC)?; let mut page_manager_guard = page_manager_lock_irqsave(); - let mut cur_phys = PhysPageFrame::new(phy_addr); - for i in 0..page_count.data() { - let page = Arc::new(Page::new(true, cur_phys.phys_address(), PageType::Other)); - page_manager_guard.insert(&page)?; - data.page_cache.add_page(i, &page); - cur_phys = cur_phys.next(); + let (phy_addr, pages) = page_manager_guard.create_pages( + true, + PageType::Other, + PageFlags::empty(), + &mut LockedFrameAllocator, + PageFrameCount::new(len / PAGE_SIZE), + )?; + for i in 0..pages.len() { + data.page_cache.add_page(i, pages.get(i).unwrap()); } let virt_addr = unsafe { MMArch::phys_2_virt(phy_addr) }.ok_or(SystemError::EFAULT)?; // create mmap page From 2e3f29f506c9167a39a1c9d15a87b6043178dafa Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 25 Nov 2024 23:29:39 +0800 Subject: [PATCH 23/38] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=B3=84=E9=9C=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/mm/allocator/page_frame.rs | 2 ++ kernel/src/mm/page.rs | 13 ++++++++++--- kernel/src/perf/bpf.rs | 3 ++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/kernel/src/mm/allocator/page_frame.rs b/kernel/src/mm/allocator/page_frame.rs index 88da0d388..a7e9c8ba4 100644 --- a/kernel/src/mm/allocator/page_frame.rs +++ b/kernel/src/mm/allocator/page_frame.rs @@ -171,6 +171,8 @@ impl Iterator for VirtPageFrameIter { pub struct PageFrameCount(usize); impl PageFrameCount { + pub const ONE: PageFrameCount = PageFrameCount(1); + // @brief 初始化PageFrameCount pub const fn new(count: usize) -> Self { return Self(count); diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 1ad2d14cd..bfbe603e8 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -171,7 +171,10 @@ impl PageManager { let mut ret = Vec::new(); for _ in 0..count.data() { let page = Page::new(shared, cur_phys.phys_address(), page_type.clone(), flags); - self.insert(&page)?; + if let Err(e) = self.insert(&page) { + unsafe { deallocate_page_frames(PhysPageFrame::new(start_paddr), count) }; + return Err(e); + } ret.push(page); cur_phys = cur_phys.next(); } @@ -196,8 +199,12 @@ impl PageManager { ) -> Result, SystemError> { let old_page = self.get(old_phys).ok_or(SystemError::EINVAL)?; let paddr = unsafe { allocator.allocate_one().ok_or(SystemError::ENOMEM)? }; - let page = Page::copy(old_page.read_irqsave(), paddr)?; - self.insert(&page)?; + let deallocate_page = |_: &SystemError| unsafe { + deallocate_page_frames(PhysPageFrame::new(paddr), PageFrameCount::ONE) + }; + + let page = Page::copy(old_page.read_irqsave(), paddr).inspect_err(deallocate_page)?; + self.insert(&page).inspect_err(deallocate_page)?; Ok(page) } } diff --git a/kernel/src/perf/bpf.rs b/kernel/src/perf/bpf.rs index 3f7c1da28..ec43e63dd 100644 --- a/kernel/src/perf/bpf.rs +++ b/kernel/src/perf/bpf.rs @@ -6,6 +6,7 @@ use crate::filesystem::vfs::{FilePrivateData, FileSystem, IndexNode}; use crate::include::bindings::linux_bpf::{ perf_event_header, perf_event_mmap_page, perf_event_type, }; +use crate::libs::align::page_align_up; use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use crate::mm::allocator::page_frame::{PageFrameCount, PhysPageFrame}; use crate::mm::page::{page_manager_lock_irqsave, PageFlags, PageType}; @@ -238,7 +239,7 @@ impl BpfPerfEvent { PageType::Other, PageFlags::empty(), &mut LockedFrameAllocator, - PageFrameCount::new(len / PAGE_SIZE), + PageFrameCount::new(page_align_up(len) / PAGE_SIZE), )?; for i in 0..pages.len() { data.page_cache.add_page(i, pages.get(i).unwrap()); From 0b281af346ccb87deb4ac8499a323a4744ec026d Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 25 Nov 2024 23:47:35 +0800 Subject: [PATCH 24/38] =?UTF-8?q?Page=E6=B7=BB=E5=8A=A0truncate=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/vfs/file.rs | 9 +-------- kernel/src/mm/page.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index adf3af1f6..8010b7888 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -431,15 +431,8 @@ impl PageCache { let last_page_index = page_num - 1; let last_len = len - last_page_index * MMArch::PAGE_SIZE; if let Some(page) = guard.get(&last_page_index) { - let vaddr = - unsafe { MMArch::phys_2_virt(page.read_irqsave().phys_address()).unwrap() }; - unsafe { - core::slice::from_raw_parts_mut( - (vaddr.data() + last_len) as *mut u8, - MMArch::PAGE_SIZE - last_len, - ) - .fill(0) + page.write_irqsave().truncate(last_len); }; } else { return Err(SystemError::EIO); diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index bfbe603e8..078609503 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -644,6 +644,22 @@ impl InnerPage { ) .copy_from_slice(slice); } + + pub unsafe fn truncate(&mut self, len: usize) { + if len > MMArch::PAGE_SIZE { + return; + } + + let vaddr = unsafe { MMArch::phys_2_virt(self.phys_address()).unwrap() }; + + unsafe { + core::slice::from_raw_parts_mut( + (vaddr.data() + len) as *mut u8, + MMArch::PAGE_SIZE - len, + ) + .fill(0) + }; + } } impl Drop for InnerPage { From b9938e138bb226e1ac2a7dfa2ca9ae5c273c6e90 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Tue, 26 Nov 2024 01:15:14 +0800 Subject: [PATCH 25/38] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E9=87=8A=E6=94=BE=E5=86=85=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/mm/page.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 078609503..14447dbcd 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -168,11 +168,13 @@ impl PageManager { } let mut cur_phys = PhysPageFrame::new(start_paddr); - let mut ret = Vec::new(); + let mut ret: Vec> = Vec::new(); for _ in 0..count.data() { let page = Page::new(shared, cur_phys.phys_address(), page_type.clone(), flags); if let Err(e) = self.insert(&page) { - unsafe { deallocate_page_frames(PhysPageFrame::new(start_paddr), count) }; + for insert_page in ret { + self.remove_page(&insert_page.read_irqsave().phys_addr); + } return Err(e); } ret.push(page); @@ -199,12 +201,14 @@ impl PageManager { ) -> Result, SystemError> { let old_page = self.get(old_phys).ok_or(SystemError::EINVAL)?; let paddr = unsafe { allocator.allocate_one().ok_or(SystemError::ENOMEM)? }; - let deallocate_page = |_: &SystemError| unsafe { - deallocate_page_frames(PhysPageFrame::new(paddr), PageFrameCount::ONE) - }; - let page = Page::copy(old_page.read_irqsave(), paddr).inspect_err(deallocate_page)?; - self.insert(&page).inspect_err(deallocate_page)?; + assert!(!self.contains(&paddr), "phys page: {paddr:?} already exist"); + + let page = Page::copy(old_page.read_irqsave(), paddr) + .inspect_err(|_| unsafe { allocator.free_one(paddr) })?; + + self.insert(&page)?; + Ok(page) } } From 9336e3aacaadc1b66daf18434881574463f7d02a Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Wed, 27 Nov 2024 00:43:43 +0800 Subject: [PATCH 26/38] =?UTF-8?q?PageCache=E5=8A=A0=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/Cargo.toml | 1 - kernel/src/filesystem/fat/fs.rs | 6 +- kernel/src/filesystem/vfs/file.rs | 143 ++++++++++++++++-------------- kernel/src/mm/fault.rs | 6 +- kernel/src/mm/page.rs | 2 +- kernel/src/perf/bpf.rs | 4 +- 6 files changed, 87 insertions(+), 75 deletions(-) diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index d18d22f02..85d2b7194 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -62,7 +62,6 @@ paste = "=1.0.14" slabmalloc = { path = "crates/rust-slabmalloc" } log = "0.4.21" kprobe = { path = "crates/kprobe" } -xarray = "0.1.0" lru = "0.12.3" rbpf = { path = "crates/rbpf" } diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index e7c56debf..567aedcd8 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -1449,7 +1449,7 @@ impl IndexNode for LockedFATInode { let page_cache = self.0.lock().page_cache.clone(); if let Some(page_cache) = page_cache { - let r = page_cache.read(offset, &mut buf[0..len]); + let r = page_cache.lock_irqsave().read(offset, &mut buf[0..len]); // self.0.lock_irqsave().update_metadata(); return r; } else { @@ -1469,7 +1469,7 @@ impl IndexNode for LockedFATInode { let page_cache = self.0.lock().page_cache.clone(); if let Some(page_cache) = page_cache { - let write_len = page_cache.write(offset, buf)?; + let write_len = page_cache.lock_irqsave().write(offset, buf)?; let mut guard = self.0.lock(); let old_size = guard.metadata.size; guard.update_metadata(Some(core::cmp::max(old_size, (offset + write_len) as i64))); @@ -1562,7 +1562,7 @@ impl IndexNode for LockedFATInode { } fn resize(&self, len: usize) -> Result<(), SystemError> { if let Some(page_cache) = self.page_cache() { - return page_cache.resize(len); + return page_cache.lock_irqsave().resize(len); } let mut guard: SpinLockGuard = self.0.lock(); diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 8010b7888..2470faa2b 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -13,7 +13,6 @@ use log::error; use system_error::SystemError; use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData}; -use crate::perf::PerfEventInode; use crate::{arch::mm::LockedFrameAllocator, libs::lazy_init::Lazy}; use crate::{ arch::MMArch, @@ -36,6 +35,7 @@ use crate::{ }; use crate::{filesystem::eventfd::EventFdInode, mm::page::FileMapInfo}; use crate::{libs::align::page_align_up, mm::page::PageType}; +use crate::{libs::spinlock::SpinLockGuard, perf::PerfEventInode}; /// 文件私有信息的枚举类型 #[derive(Debug, Clone)] @@ -134,65 +134,37 @@ impl FileMode { /// 页面缓存 #[derive(Debug)] pub struct PageCache { - pages: SpinLock>>, + inner: SpinLock, inode: Lazy>, - self_ref: Weak, } -impl Drop for PageCache { - fn drop(&mut self) { - log::debug!("page cache drop"); - let guard = self.pages.lock_irqsave(); - let mut page_manager = page_manager_lock_irqsave(); - for page in guard.values() { - page_manager.remove_page(&page.read_irqsave().phys_address()); - } - } +#[derive(Debug)] +pub struct InnerPageCache { + pages: HashMap>, + page_cache_ref: Weak, } -impl PageCache { - pub fn new(inode: Option>) -> Arc { - Arc::new_cyclic(|weak| Self { - pages: SpinLock::new(HashMap::new()), - inode: { - let v: Lazy> = Lazy::new(); - if let Some(inode) = inode { - v.init(inode); - } - v - }, - self_ref: weak.clone(), - }) - } - - pub fn inode(&self) -> Option> { - self.inode.try_get().cloned() +impl InnerPageCache { + pub fn new(page_cache_ref: Weak) -> InnerPageCache { + Self { + pages: HashMap::new(), + page_cache_ref, + } } - pub fn add_page(&self, offset: usize, page: &Arc) { - let mut guard = self.pages.lock_irqsave(); - guard.insert(offset, page.clone()); + pub fn add_page(&mut self, offset: usize, page: &Arc) { + self.pages.insert(offset, page.clone()); } pub fn get_page(&self, offset: usize) -> Option> { - let guard = self.pages.lock_irqsave(); - guard.get(&offset).cloned() + self.pages.get(&offset).cloned() } - pub fn remove_page(&self, offset: usize) -> Option> { - let mut guard = self.pages.lock_irqsave(); - guard.remove(&offset) + pub fn remove_page(&mut self, offset: usize) -> Option> { + self.pages.remove(&offset) } - pub fn set_inode(&self, inode: Weak) -> Result<(), SystemError> { - if self.inode.initialized() { - return Err(SystemError::EINVAL); - } - self.inode.init(inode); - Ok(()) - } - - pub fn create_pages(&self, start_page_index: usize, buf: &[u8]) -> Result<(), SystemError> { + fn create_pages(&mut self, start_page_index: usize, buf: &[u8]) -> Result<(), SystemError> { assert!(buf.len() % MMArch::PAGE_SIZE == 0); let page_num = buf.len() / MMArch::PAGE_SIZE; @@ -202,7 +174,6 @@ impl PageCache { return Ok(()); } - let mut guard = self.pages.lock_irqsave(); let mut page_manager_guard = page_manager_lock_irqsave(); for i in 0..page_num { @@ -213,7 +184,7 @@ impl PageCache { true, PageType::File(FileMapInfo { page_cache: self - .self_ref + .page_cache_ref .upgrade() .expect("failed to get self_arc of pagecache"), index: page_index, @@ -227,7 +198,7 @@ impl PageCache { page_guard.copy_from_slice(&buf[buf_offset..buf_offset + MMArch::PAGE_SIZE]); } - guard.insert(page_index, page.clone()); + self.add_page(page_index, &page); } Ok(()) @@ -244,8 +215,14 @@ impl PageCache { /// /// - `Ok(usize)` 成功读取的长度 /// - `Err(SystemError)` 失败返回错误码 - pub fn read(&self, offset: usize, buf: &mut [u8]) -> Result { - let inode = self.inode.upgrade().unwrap(); + pub fn read(&mut self, offset: usize, buf: &mut [u8]) -> Result { + let inode = self + .page_cache_ref + .upgrade() + .unwrap() + .inode + .upgrade() + .unwrap(); let file_size = inode.metadata().unwrap().size; let len = if offset < file_size as usize { @@ -263,8 +240,6 @@ impl PageCache { let start_page_index = offset >> MMArch::PAGE_SHIFT; let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_index; - let guard = self.pages.lock_irqsave(); - let mut buf_offset = 0; let mut ret = 0; for i in 0..page_num { @@ -286,7 +261,7 @@ impl PageCache { MMArch::PAGE_SIZE }; - if let Some(page) = guard.get(&page_index) { + if let Some(page) = self.get_page(page_index) { let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; unsafe { sub_buf.copy_from_slice( @@ -307,9 +282,8 @@ impl PageCache { buf_offset += sub_len; } - drop(guard); - for (page_index, count) in not_exist { + // TODO 这里使用buffer避免多次读取磁盘,将来引入异步IO直接写入页面,减少内存开销和拷贝 let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; inode.read_sync(page_index * MMArch::PAGE_SIZE, page_buf.as_mut())?; @@ -353,7 +327,7 @@ impl PageCache { /// /// - `Ok(usize)` 成功读取的长度 /// - `Err(SystemError)` 失败返回错误码 - pub fn write(&self, offset: usize, buf: &[u8]) -> Result { + pub fn write(&mut self, offset: usize, buf: &[u8]) -> Result { let len = buf.len(); if len == 0 { return Ok(0); @@ -386,17 +360,14 @@ impl PageCache { MMArch::PAGE_SIZE }; - let guard = self.pages.lock_irqsave(); - let exist = guard.get(&page_index).is_some(); - drop(guard); + let exist = self.get_page(page_index).is_some(); if !exist { let page_buf = vec![0u8; MMArch::PAGE_SIZE]; self.create_pages(page_index, &page_buf)?; } - let guard = self.pages.lock_irqsave(); - if let Some(page) = guard.get(&page_index) { + if let Some(page) = self.get_page(page_index) { let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; unsafe { @@ -418,19 +389,18 @@ impl PageCache { Ok(ret) } - pub fn resize(&self, len: usize) -> Result<(), SystemError> { + pub fn resize(&mut self, len: usize) -> Result<(), SystemError> { let page_num = page_align_up(len) / MMArch::PAGE_SIZE; - let mut guard = self.pages.lock_irqsave(); let mut reclaimer = page_reclaimer_lock_irqsave(); - for (_i, page) in guard.drain_filter(|index, _page| *index >= page_num) { + for (_i, page) in self.pages.drain_filter(|index, _page| *index >= page_num) { let _ = reclaimer.remove_page(&page.read_irqsave().phys_address()); } if page_num > 0 { let last_page_index = page_num - 1; let last_len = len - last_page_index * MMArch::PAGE_SIZE; - if let Some(page) = guard.get(&last_page_index) { + if let Some(page) = self.get_page(last_page_index) { unsafe { page.write_irqsave().truncate(last_len); }; @@ -443,6 +413,47 @@ impl PageCache { } } +impl Drop for InnerPageCache { + fn drop(&mut self) { + log::debug!("page cache drop"); + let mut page_manager = page_manager_lock_irqsave(); + for page in self.pages.values() { + page_manager.remove_page(&page.read_irqsave().phys_address()); + } + } +} + +impl PageCache { + pub fn new(inode: Option>) -> Arc { + Arc::new_cyclic(|weak| Self { + inner: SpinLock::new(InnerPageCache::new(weak.clone())), + inode: { + let v: Lazy> = Lazy::new(); + if let Some(inode) = inode { + v.init(inode); + } + v + }, + }) + } + + pub fn inode(&self) -> Option> { + self.inode.try_get().cloned() + } + + pub fn set_inode(&self, inode: Weak) -> Result<(), SystemError> { + if self.inode.initialized() { + return Err(SystemError::EINVAL); + } + self.inode.init(inode); + Ok(()) + } + + pub fn lock_irqsave(&self) -> SpinLockGuard { + self.inner.lock_irqsave() + } +} + /// @brief 抽象文件结构体 #[derive(Debug)] pub struct File { diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index b11120cc6..edacaad36 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -591,7 +591,7 @@ impl PageFaultHandler { << MMArch::PAGE_SHIFT); for pgoff in start_pgoff..=end_pgoff { - if let Some(page) = page_cache.get_page(pgoff) { + if let Some(page) = page_cache.lock_irqsave().get_page(pgoff) { let page_guard = page.read_irqsave(); if page_guard.flags().contains(PageFlags::PG_UPTODATE) { let phys = page_guard.phys_address(); @@ -625,7 +625,7 @@ impl PageFaultHandler { let mapper = &mut pfm.mapper; let mut ret = VmFaultReason::empty(); - if let Some(page) = page_cache.get_page(file_pgoff) { + if let Some(page) = page_cache.lock_irqsave().get_page(file_pgoff) { // TODO 异步从磁盘中预读页面进PageCache // 直接将PageCache中的页面作为要映射的页面 @@ -665,7 +665,7 @@ impl PageFaultHandler { .expect("failed to create page"); pfm.page = Some(page.clone()); - page_cache.add_page(file_pgoff, &page); + page_cache.lock_irqsave().add_page(file_pgoff, &page); } ret } diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 14447dbcd..f1425794f 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -389,7 +389,7 @@ impl PageReclaimer { if unmap { // 删除页面 - page_cache.remove_page(page_index); + page_cache.lock_irqsave().remove_page(page_index); page_manager_lock_irqsave().remove_page(&paddr); } else { // 清除标记 diff --git a/kernel/src/perf/bpf.rs b/kernel/src/perf/bpf.rs index ec43e63dd..18692713a 100644 --- a/kernel/src/perf/bpf.rs +++ b/kernel/src/perf/bpf.rs @@ -242,7 +242,9 @@ impl BpfPerfEvent { PageFrameCount::new(page_align_up(len) / PAGE_SIZE), )?; for i in 0..pages.len() { - data.page_cache.add_page(i, pages.get(i).unwrap()); + data.page_cache + .lock_irqsave() + .add_page(i, pages.get(i).unwrap()); } let virt_addr = unsafe { MMArch::phys_2_virt(phy_addr) }.ok_or(SystemError::EFAULT)?; // create mmap page From f2d383f7cdf6cfb50f9b1e5d9de18368369a2f84 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Wed, 27 Nov 2024 01:41:50 +0800 Subject: [PATCH 27/38] =?UTF-8?q?PageCache=E5=88=9B=E5=BB=BA=E5=8D=95?= =?UTF-8?q?=E7=8B=AC=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 2 +- kernel/src/filesystem/mod.rs | 1 + kernel/src/filesystem/page_cache.rs | 345 ++++++++++++++++++++++++++++ kernel/src/filesystem/vfs/file.rs | 340 +-------------------------- kernel/src/filesystem/vfs/mod.rs | 9 +- kernel/src/filesystem/vfs/mount.rs | 8 +- kernel/src/mm/page.rs | 2 +- kernel/src/perf/bpf.rs | 2 +- kernel/src/perf/kprobe.rs | 3 +- kernel/src/perf/mod.rs | 3 +- 10 files changed, 362 insertions(+), 353 deletions(-) create mode 100644 kernel/src/filesystem/page_cache.rs diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 567aedcd8..334d74fcb 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -14,7 +14,7 @@ use alloc::{ use crate::driver::base::block::gendisk::GenDisk; use crate::driver::base::device::device_number::DeviceNumber; -use crate::filesystem::vfs::file::PageCache; +use crate::filesystem::page_cache::PageCache; use crate::filesystem::vfs::utils::DName; use crate::filesystem::vfs::{Magic, SpecialNodeData, SuperBlock}; use crate::ipc::pipe::LockedPipeInode; diff --git a/kernel/src/filesystem/mod.rs b/kernel/src/filesystem/mod.rs index 772d21f41..59bda2a15 100644 --- a/kernel/src/filesystem/mod.rs +++ b/kernel/src/filesystem/mod.rs @@ -5,6 +5,7 @@ pub mod fat; pub mod kernfs; pub mod mbr; pub mod overlayfs; +pub mod page_cache; pub mod procfs; pub mod ramfs; pub mod sysfs; diff --git a/kernel/src/filesystem/page_cache.rs b/kernel/src/filesystem/page_cache.rs new file mode 100644 index 000000000..53939b9e2 --- /dev/null +++ b/kernel/src/filesystem/page_cache.rs @@ -0,0 +1,345 @@ +use core::cmp::min; + +use alloc::{ + sync::{Arc, Weak}, + vec::Vec, +}; +use hashbrown::HashMap; +use system_error::SystemError; + +use super::vfs::IndexNode; +use crate::libs::spinlock::SpinLockGuard; +use crate::mm::page::FileMapInfo; +use crate::{arch::mm::LockedFrameAllocator, libs::lazy_init::Lazy}; +use crate::{ + arch::MMArch, + libs::spinlock::SpinLock, + mm::{ + page::{page_manager_lock_irqsave, page_reclaimer_lock_irqsave, Page, PageFlags}, + MemoryManagementArch, + }, +}; +use crate::{libs::align::page_align_up, mm::page::PageType}; + +/// 页面缓存 +#[derive(Debug)] +pub struct PageCache { + inner: SpinLock, + inode: Lazy>, +} + +#[derive(Debug)] +pub struct InnerPageCache { + pages: HashMap>, + page_cache_ref: Weak, +} + +impl InnerPageCache { + pub fn new(page_cache_ref: Weak) -> InnerPageCache { + Self { + pages: HashMap::new(), + page_cache_ref, + } + } + + pub fn add_page(&mut self, offset: usize, page: &Arc) { + self.pages.insert(offset, page.clone()); + } + + pub fn get_page(&self, offset: usize) -> Option> { + self.pages.get(&offset).cloned() + } + + pub fn remove_page(&mut self, offset: usize) -> Option> { + self.pages.remove(&offset) + } + + fn create_pages(&mut self, start_page_index: usize, buf: &[u8]) -> Result<(), SystemError> { + assert!(buf.len() % MMArch::PAGE_SIZE == 0); + + let page_num = buf.len() / MMArch::PAGE_SIZE; + + let len = buf.len(); + if len == 0 { + return Ok(()); + } + + let mut page_manager_guard = page_manager_lock_irqsave(); + + for i in 0..page_num { + let buf_offset = i * MMArch::PAGE_SIZE; + let page_index = start_page_index + i; + + let page = page_manager_guard.create_one_page( + true, + PageType::File(FileMapInfo { + page_cache: self + .page_cache_ref + .upgrade() + .expect("failed to get self_arc of pagecache"), + index: page_index, + }), + PageFlags::PG_LRU, + &mut LockedFrameAllocator, + )?; + + let mut page_guard = page.write_irqsave(); + unsafe { + page_guard.copy_from_slice(&buf[buf_offset..buf_offset + MMArch::PAGE_SIZE]); + } + + self.add_page(page_index, &page); + } + + Ok(()) + } + + /// 从PageCache中读取数据。 + /// + /// ## 参数 + /// + /// - `offset` 偏移量 + /// - `buf` 缓冲区 + /// + /// ## 返回值 + /// + /// - `Ok(usize)` 成功读取的长度 + /// - `Err(SystemError)` 失败返回错误码 + pub fn read(&mut self, offset: usize, buf: &mut [u8]) -> Result { + let inode = self + .page_cache_ref + .upgrade() + .unwrap() + .inode + .upgrade() + .unwrap(); + let file_size = inode.metadata().unwrap().size; + + let len = if offset < file_size as usize { + core::cmp::min(file_size as usize, offset + buf.len()) - offset + } else { + 0 + }; + + if len == 0 { + return Ok(0); + } + + let mut not_exist = Vec::new(); + + let start_page_index = offset >> MMArch::PAGE_SHIFT; + let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_index; + + let mut buf_offset = 0; + let mut ret = 0; + for i in 0..page_num { + let page_index = start_page_index + i; + + // 第一个页可能需要计算页内偏移 + let page_offset = if i == 0 { + offset % MMArch::PAGE_SIZE + } else { + 0 + }; + + // 第一个页和最后一个页可能不满 + let sub_len = if i == 0 { + min(len, MMArch::PAGE_SIZE - page_offset) + } else if i == page_num - 1 { + (offset + len - 1) % MMArch::PAGE_SIZE + 1 + } else { + MMArch::PAGE_SIZE + }; + + if let Some(page) = self.get_page(page_index) { + let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; + unsafe { + sub_buf.copy_from_slice( + &page.read_irqsave().as_slice()[page_offset..page_offset + sub_len], + ); + } + ret += sub_len; + } else if let Some((index, count)) = not_exist.last_mut() { + if *index + *count == page_index { + *count += 1; + } else { + not_exist.push((page_index, 1)); + } + } else { + not_exist.push((page_index, 1)); + } + + buf_offset += sub_len; + } + + for (page_index, count) in not_exist { + // TODO 这里使用buffer避免多次读取磁盘,将来引入异步IO直接写入页面,减少内存开销和拷贝 + let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; + inode.read_sync(page_index * MMArch::PAGE_SIZE, page_buf.as_mut())?; + + self.create_pages(page_index, page_buf.as_mut())?; + + // 实际要拷贝的内容在文件中的偏移量 + let copy_offset = core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); + // 实际要拷贝的内容的长度 + let copy_len = core::cmp::min((page_index + count) * MMArch::PAGE_SIZE, offset + len) + - copy_offset; + + let page_buf_offset = if page_index * MMArch::PAGE_SIZE < copy_offset { + copy_offset - page_index * MMArch::PAGE_SIZE + } else { + 0 + }; + + let buf_offset = copy_offset.saturating_sub(offset); + + buf[buf_offset..buf_offset + copy_len] + .copy_from_slice(&page_buf[page_buf_offset..page_buf_offset + copy_len]); + + ret += copy_len; + + // log::debug!("page_offset:{page_offset}, count:{count}"); + // log::debug!("copy_offset:{copy_offset}, copy_len:{copy_len}"); + // log::debug!("buf_offset:{buf_offset}, page_buf_offset:{page_buf_offset}"); + } + + Ok(ret) + } + + /// 向PageCache中写入数据。 + /// + /// ## 参数 + /// + /// - `offset` 偏移量 + /// - `buf` 缓冲区 + /// + /// ## 返回值 + /// + /// - `Ok(usize)` 成功读取的长度 + /// - `Err(SystemError)` 失败返回错误码 + pub fn write(&mut self, offset: usize, buf: &[u8]) -> Result { + let len = buf.len(); + if len == 0 { + return Ok(0); + } + + // log::debug!("offset:{offset}, len:{len}"); + + let start_page_index = offset >> MMArch::PAGE_SHIFT; + let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_index; + + let mut buf_offset = 0; + let mut ret = 0; + + for i in 0..page_num { + let page_index = start_page_index + i; + + // 第一个页可能需要计算页内偏移 + let page_offset = if i == 0 { + offset % MMArch::PAGE_SIZE + } else { + 0 + }; + + // 第一个页和最后一个页可能不满 + let sub_len = if i == 0 { + min(len, MMArch::PAGE_SIZE - page_offset) + } else if i == page_num - 1 { + (offset + len - 1) % MMArch::PAGE_SIZE + 1 + } else { + MMArch::PAGE_SIZE + }; + + let exist = self.get_page(page_index).is_some(); + + if !exist { + let page_buf = vec![0u8; MMArch::PAGE_SIZE]; + self.create_pages(page_index, &page_buf)?; + } + + if let Some(page) = self.get_page(page_index) { + let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; + + unsafe { + page.write_irqsave().as_slice_mut()[page_offset..page_offset + sub_len] + .copy_from_slice(sub_buf); + } + + ret += sub_len; + + // log::debug!( + // "page_offset:{page_offset}, buf_offset:{buf_offset}, sub_len:{sub_len}" + // ); + } else { + return Err(SystemError::EIO); + }; + + buf_offset += sub_len; + } + Ok(ret) + } + + pub fn resize(&mut self, len: usize) -> Result<(), SystemError> { + let page_num = page_align_up(len) / MMArch::PAGE_SIZE; + + let mut reclaimer = page_reclaimer_lock_irqsave(); + for (_i, page) in self.pages.drain_filter(|index, _page| *index >= page_num) { + let _ = reclaimer.remove_page(&page.read_irqsave().phys_address()); + } + + if page_num > 0 { + let last_page_index = page_num - 1; + let last_len = len - last_page_index * MMArch::PAGE_SIZE; + if let Some(page) = self.get_page(last_page_index) { + unsafe { + page.write_irqsave().truncate(last_len); + }; + } else { + return Err(SystemError::EIO); + } + } + + Ok(()) + } +} + +impl Drop for InnerPageCache { + fn drop(&mut self) { + log::debug!("page cache drop"); + let mut page_manager = page_manager_lock_irqsave(); + for page in self.pages.values() { + page_manager.remove_page(&page.read_irqsave().phys_address()); + } + } +} + +impl PageCache { + pub fn new(inode: Option>) -> Arc { + Arc::new_cyclic(|weak| Self { + inner: SpinLock::new(InnerPageCache::new(weak.clone())), + inode: { + let v: Lazy> = Lazy::new(); + if let Some(inode) = inode { + v.init(inode); + } + v + }, + }) + } + + pub fn inode(&self) -> Option> { + self.inode.try_get().cloned() + } + + pub fn set_inode(&self, inode: Weak) -> Result<(), SystemError> { + if self.inode.initialized() { + return Err(SystemError::EINVAL); + } + self.inode.init(inode); + Ok(()) + } + + pub fn lock_irqsave(&self) -> SpinLockGuard { + self.inner.lock_irqsave() + } +} diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 2470faa2b..e92990ac7 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -1,21 +1,17 @@ -use core::{ - cmp::min, - sync::atomic::{AtomicUsize, Ordering}, -}; +use core::sync::atomic::{AtomicUsize, Ordering}; use alloc::{ string::String, sync::{Arc, Weak}, vec::Vec, }; -use hashbrown::HashMap; use log::error; use system_error::SystemError; use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData}; -use crate::{arch::mm::LockedFrameAllocator, libs::lazy_init::Lazy}; +use crate::filesystem::eventfd::EventFdInode; +use crate::perf::PerfEventInode; use crate::{ - arch::MMArch, driver::{ base::{block::SeekFrom, device::DevicePrivateData}, tty::tty_device::TtyFilePrivateData, @@ -23,19 +19,12 @@ use crate::{ filesystem::procfs::ProcfsFilePrivateData, ipc::pipe::{LockedPipeInode, PipeFsPrivateData}, libs::{rwlock::RwLock, spinlock::SpinLock}, - mm::{ - page::{page_manager_lock_irqsave, page_reclaimer_lock_irqsave, Page, PageFlags}, - MemoryManagementArch, - }, net::{ event_poll::{EPollItem, EPollPrivateData, EventPoll}, socket::SocketInode, }, process::{cred::Cred, ProcessManager}, }; -use crate::{filesystem::eventfd::EventFdInode, mm::page::FileMapInfo}; -use crate::{libs::align::page_align_up, mm::page::PageType}; -use crate::{libs::spinlock::SpinLockGuard, perf::PerfEventInode}; /// 文件私有信息的枚举类型 #[derive(Debug, Clone)] @@ -131,329 +120,6 @@ impl FileMode { } } -/// 页面缓存 -#[derive(Debug)] -pub struct PageCache { - inner: SpinLock, - inode: Lazy>, -} - -#[derive(Debug)] -pub struct InnerPageCache { - pages: HashMap>, - page_cache_ref: Weak, -} - -impl InnerPageCache { - pub fn new(page_cache_ref: Weak) -> InnerPageCache { - Self { - pages: HashMap::new(), - page_cache_ref, - } - } - - pub fn add_page(&mut self, offset: usize, page: &Arc) { - self.pages.insert(offset, page.clone()); - } - - pub fn get_page(&self, offset: usize) -> Option> { - self.pages.get(&offset).cloned() - } - - pub fn remove_page(&mut self, offset: usize) -> Option> { - self.pages.remove(&offset) - } - - fn create_pages(&mut self, start_page_index: usize, buf: &[u8]) -> Result<(), SystemError> { - assert!(buf.len() % MMArch::PAGE_SIZE == 0); - - let page_num = buf.len() / MMArch::PAGE_SIZE; - - let len = buf.len(); - if len == 0 { - return Ok(()); - } - - let mut page_manager_guard = page_manager_lock_irqsave(); - - for i in 0..page_num { - let buf_offset = i * MMArch::PAGE_SIZE; - let page_index = start_page_index + i; - - let page = page_manager_guard.create_one_page( - true, - PageType::File(FileMapInfo { - page_cache: self - .page_cache_ref - .upgrade() - .expect("failed to get self_arc of pagecache"), - index: page_index, - }), - PageFlags::PG_LRU, - &mut LockedFrameAllocator, - )?; - - let mut page_guard = page.write_irqsave(); - unsafe { - page_guard.copy_from_slice(&buf[buf_offset..buf_offset + MMArch::PAGE_SIZE]); - } - - self.add_page(page_index, &page); - } - - Ok(()) - } - - /// 从PageCache中读取数据。 - /// - /// ## 参数 - /// - /// - `offset` 偏移量 - /// - `buf` 缓冲区 - /// - /// ## 返回值 - /// - /// - `Ok(usize)` 成功读取的长度 - /// - `Err(SystemError)` 失败返回错误码 - pub fn read(&mut self, offset: usize, buf: &mut [u8]) -> Result { - let inode = self - .page_cache_ref - .upgrade() - .unwrap() - .inode - .upgrade() - .unwrap(); - let file_size = inode.metadata().unwrap().size; - - let len = if offset < file_size as usize { - core::cmp::min(file_size as usize, offset + buf.len()) - offset - } else { - 0 - }; - - if len == 0 { - return Ok(0); - } - - let mut not_exist = Vec::new(); - - let start_page_index = offset >> MMArch::PAGE_SHIFT; - let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_index; - - let mut buf_offset = 0; - let mut ret = 0; - for i in 0..page_num { - let page_index = start_page_index + i; - - // 第一个页可能需要计算页内偏移 - let page_offset = if i == 0 { - offset % MMArch::PAGE_SIZE - } else { - 0 - }; - - // 第一个页和最后一个页可能不满 - let sub_len = if i == 0 { - min(len, MMArch::PAGE_SIZE - page_offset) - } else if i == page_num - 1 { - (offset + len - 1) % MMArch::PAGE_SIZE + 1 - } else { - MMArch::PAGE_SIZE - }; - - if let Some(page) = self.get_page(page_index) { - let sub_buf = &mut buf[buf_offset..(buf_offset + sub_len)]; - unsafe { - sub_buf.copy_from_slice( - &page.read_irqsave().as_slice()[page_offset..page_offset + sub_len], - ); - } - ret += sub_len; - } else if let Some((index, count)) = not_exist.last_mut() { - if *index + *count == page_index { - *count += 1; - } else { - not_exist.push((page_index, 1)); - } - } else { - not_exist.push((page_index, 1)); - } - - buf_offset += sub_len; - } - - for (page_index, count) in not_exist { - // TODO 这里使用buffer避免多次读取磁盘,将来引入异步IO直接写入页面,减少内存开销和拷贝 - let mut page_buf = vec![0u8; MMArch::PAGE_SIZE * count]; - inode.read_sync(page_index * MMArch::PAGE_SIZE, page_buf.as_mut())?; - - self.create_pages(page_index, page_buf.as_mut())?; - - // 实际要拷贝的内容在文件中的偏移量 - let copy_offset = core::cmp::max(page_index * MMArch::PAGE_SIZE, offset); - // 实际要拷贝的内容的长度 - let copy_len = core::cmp::min((page_index + count) * MMArch::PAGE_SIZE, offset + len) - - copy_offset; - - let page_buf_offset = if page_index * MMArch::PAGE_SIZE < copy_offset { - copy_offset - page_index * MMArch::PAGE_SIZE - } else { - 0 - }; - - let buf_offset = copy_offset.saturating_sub(offset); - - buf[buf_offset..buf_offset + copy_len] - .copy_from_slice(&page_buf[page_buf_offset..page_buf_offset + copy_len]); - - ret += copy_len; - - // log::debug!("page_offset:{page_offset}, count:{count}"); - // log::debug!("copy_offset:{copy_offset}, copy_len:{copy_len}"); - // log::debug!("buf_offset:{buf_offset}, page_buf_offset:{page_buf_offset}"); - } - - Ok(ret) - } - - /// 向PageCache中写入数据。 - /// - /// ## 参数 - /// - /// - `offset` 偏移量 - /// - `buf` 缓冲区 - /// - /// ## 返回值 - /// - /// - `Ok(usize)` 成功读取的长度 - /// - `Err(SystemError)` 失败返回错误码 - pub fn write(&mut self, offset: usize, buf: &[u8]) -> Result { - let len = buf.len(); - if len == 0 { - return Ok(0); - } - - // log::debug!("offset:{offset}, len:{len}"); - - let start_page_index = offset >> MMArch::PAGE_SHIFT; - let page_num = (page_align_up(offset + len) >> MMArch::PAGE_SHIFT) - start_page_index; - - let mut buf_offset = 0; - let mut ret = 0; - - for i in 0..page_num { - let page_index = start_page_index + i; - - // 第一个页可能需要计算页内偏移 - let page_offset = if i == 0 { - offset % MMArch::PAGE_SIZE - } else { - 0 - }; - - // 第一个页和最后一个页可能不满 - let sub_len = if i == 0 { - min(len, MMArch::PAGE_SIZE - page_offset) - } else if i == page_num - 1 { - (offset + len - 1) % MMArch::PAGE_SIZE + 1 - } else { - MMArch::PAGE_SIZE - }; - - let exist = self.get_page(page_index).is_some(); - - if !exist { - let page_buf = vec![0u8; MMArch::PAGE_SIZE]; - self.create_pages(page_index, &page_buf)?; - } - - if let Some(page) = self.get_page(page_index) { - let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; - - unsafe { - page.write_irqsave().as_slice_mut()[page_offset..page_offset + sub_len] - .copy_from_slice(sub_buf); - } - - ret += sub_len; - - // log::debug!( - // "page_offset:{page_offset}, buf_offset:{buf_offset}, sub_len:{sub_len}" - // ); - } else { - return Err(SystemError::EIO); - }; - - buf_offset += sub_len; - } - Ok(ret) - } - - pub fn resize(&mut self, len: usize) -> Result<(), SystemError> { - let page_num = page_align_up(len) / MMArch::PAGE_SIZE; - - let mut reclaimer = page_reclaimer_lock_irqsave(); - for (_i, page) in self.pages.drain_filter(|index, _page| *index >= page_num) { - let _ = reclaimer.remove_page(&page.read_irqsave().phys_address()); - } - - if page_num > 0 { - let last_page_index = page_num - 1; - let last_len = len - last_page_index * MMArch::PAGE_SIZE; - if let Some(page) = self.get_page(last_page_index) { - unsafe { - page.write_irqsave().truncate(last_len); - }; - } else { - return Err(SystemError::EIO); - } - } - - Ok(()) - } -} - -impl Drop for InnerPageCache { - fn drop(&mut self) { - log::debug!("page cache drop"); - let mut page_manager = page_manager_lock_irqsave(); - for page in self.pages.values() { - page_manager.remove_page(&page.read_irqsave().phys_address()); - } - } -} - -impl PageCache { - pub fn new(inode: Option>) -> Arc { - Arc::new_cyclic(|weak| Self { - inner: SpinLock::new(InnerPageCache::new(weak.clone())), - inode: { - let v: Lazy> = Lazy::new(); - if let Some(inode) = inode { - v.init(inode); - } - v - }, - }) - } - - pub fn inode(&self) -> Option> { - self.inode.try_get().cloned() - } - - pub fn set_inode(&self, inode: Weak) -> Result<(), SystemError> { - if self.inode.initialized() { - return Err(SystemError::EINVAL); - } - self.inode.init(inode); - Ok(()) - } - - pub fn lock_irqsave(&self) -> SpinLockGuard { - self.inner.lock_irqsave() - } -} - /// @brief 抽象文件结构体 #[derive(Debug)] pub struct File { diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 054d3388b..50f616192 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -24,14 +24,11 @@ use crate::{ time::PosixTimeSpec, }; -use self::{ - core::generate_inode_id, - file::{FileMode, PageCache}, - syscall::ModeType, - utils::DName, -}; +use self::{core::generate_inode_id, file::FileMode, syscall::ModeType, utils::DName}; pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS}; +use super::page_cache::PageCache; + /// vfs容许的最大的路径名称长度 pub const MAX_PATHLEN: usize = 1024; diff --git a/kernel/src/filesystem/vfs/mount.rs b/kernel/src/filesystem/vfs/mount.rs index a01866914..35d221d8f 100644 --- a/kernel/src/filesystem/vfs/mount.rs +++ b/kernel/src/filesystem/vfs/mount.rs @@ -14,7 +14,7 @@ use system_error::SystemError; use crate::{ driver::base::device::device_number::DeviceNumber, - filesystem::vfs::ROOT_INODE, + filesystem::{page_cache::PageCache, vfs::ROOT_INODE}, libs::{ casting::DowncastArc, rwlock::RwLock, @@ -24,10 +24,8 @@ use crate::{ }; use super::{ - file::{FileMode, PageCache}, - syscall::ModeType, - utils::DName, - FilePrivateData, FileSystem, FileType, IndexNode, InodeId, Magic, SuperBlock, + file::FileMode, syscall::ModeType, utils::DName, FilePrivateData, FileSystem, FileType, + IndexNode, InodeId, Magic, SuperBlock, }; const MOUNTFS_BLOCK_SIZE: u64 = 512; diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index f1425794f..af1ab71d4 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -17,7 +17,7 @@ use lru::LruCache; use crate::{ arch::{interrupt::ipi::send_ipi, mm::LockedFrameAllocator, MMArch}, exception::ipi::{IpiKind, IpiTarget}, - filesystem::vfs::{file::PageCache, FilePrivateData}, + filesystem::{page_cache::PageCache, vfs::FilePrivateData}, init::initcall::INITCALL_CORE, ipc::shm::{shm_manager_lock, ShmId}, libs::{ diff --git a/kernel/src/perf/bpf.rs b/kernel/src/perf/bpf.rs index 18692713a..bd3953a3e 100644 --- a/kernel/src/perf/bpf.rs +++ b/kernel/src/perf/bpf.rs @@ -1,7 +1,7 @@ use super::{PerfEventOps, Result}; use crate::arch::mm::LockedFrameAllocator; use crate::arch::MMArch; -use crate::filesystem::vfs::file::PageCache; +use crate::filesystem::page_cache::PageCache; use crate::filesystem::vfs::{FilePrivateData, FileSystem, IndexNode}; use crate::include::bindings::linux_bpf::{ perf_event_header, perf_event_mmap_page, perf_event_type, diff --git a/kernel/src/perf/kprobe.rs b/kernel/src/perf/kprobe.rs index 54ac829bc..7b9fdfb92 100644 --- a/kernel/src/perf/kprobe.rs +++ b/kernel/src/perf/kprobe.rs @@ -5,7 +5,8 @@ use crate::bpf::helper::BPF_HELPER_FUN_SET; use crate::bpf::prog::BpfProg; use crate::debug::kprobe::args::KprobeInfo; use crate::debug::kprobe::{register_kprobe, unregister_kprobe, LockKprobe}; -use crate::filesystem::vfs::file::{File, PageCache}; +use crate::filesystem::page_cache::PageCache; +use crate::filesystem::vfs::file::File; use crate::filesystem::vfs::{FilePrivateData, FileSystem, IndexNode}; use crate::libs::casting::DowncastArc; use crate::libs::spinlock::SpinLockGuard; diff --git a/kernel/src/perf/mod.rs b/kernel/src/perf/mod.rs index 0b6de2adb..99d2e25ad 100644 --- a/kernel/src/perf/mod.rs +++ b/kernel/src/perf/mod.rs @@ -2,7 +2,8 @@ mod bpf; mod kprobe; mod util; -use crate::filesystem::vfs::file::{File, FileMode, PageCache}; +use crate::filesystem::page_cache::PageCache; +use crate::filesystem::vfs::file::{File, FileMode}; use crate::filesystem::vfs::syscall::ModeType; use crate::filesystem::vfs::{ FilePrivateData, FileSystem, FileType, FsInfo, IndexNode, Metadata, SuperBlock, From df1e8e3667b90e17c54298b781fa39ce67e6c979 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Wed, 27 Nov 2024 02:16:58 +0800 Subject: [PATCH 28/38] =?UTF-8?q?Page=E5=A4=96=E9=83=A8=E6=B7=BB=E5=8A=A0P?= =?UTF-8?q?hysAddr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/page_cache.rs | 4 ++-- kernel/src/mm/fault.rs | 11 +++++------ kernel/src/mm/page.rs | 19 ++++++++++++++----- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/kernel/src/filesystem/page_cache.rs b/kernel/src/filesystem/page_cache.rs index 53939b9e2..380c59b16 100644 --- a/kernel/src/filesystem/page_cache.rs +++ b/kernel/src/filesystem/page_cache.rs @@ -284,7 +284,7 @@ impl InnerPageCache { let mut reclaimer = page_reclaimer_lock_irqsave(); for (_i, page) in self.pages.drain_filter(|index, _page| *index >= page_num) { - let _ = reclaimer.remove_page(&page.read_irqsave().phys_address()); + let _ = reclaimer.remove_page(&page.phys_address()); } if page_num > 0 { @@ -308,7 +308,7 @@ impl Drop for InnerPageCache { log::debug!("page cache drop"); let mut page_manager = page_manager_lock_irqsave(); for page in self.pages.values() { - page_manager.remove_page(&page.read_irqsave().phys_address()); + page_manager.remove_page(&page.phys_address()); } } } diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index edacaad36..29e6b15cf 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -309,10 +309,9 @@ impl PageFaultHandler { let mapper = &mut pfm.mapper; let mut page_manager_guard = page_manager_lock_irqsave(); - if let Ok(page) = page_manager_guard.copy_page( - &cache_page.read_irqsave().phys_address(), - mapper.allocator_mut(), - ) { + if let Ok(page) = + page_manager_guard.copy_page(&cache_page.phys_address(), mapper.allocator_mut()) + { pfm.cow_page = Some(page.clone()); } else { return VmFaultReason::VM_FAULT_OOM; @@ -594,7 +593,7 @@ impl PageFaultHandler { if let Some(page) = page_cache.lock_irqsave().get_page(pgoff) { let page_guard = page.read_irqsave(); if page_guard.flags().contains(PageFlags::PG_UPTODATE) { - let phys = page_guard.phys_address(); + let phys = page.phys_address(); let address = VirtAddr::new(addr.data() + ((pgoff - start_pgoff) << MMArch::PAGE_SHIFT)); @@ -697,7 +696,7 @@ impl PageFaultHandler { cache_page.expect("no cache_page in PageFaultMessage") }; - let page_phys = page_to_map.read_irqsave().phys_address(); + let page_phys = page_to_map.phys_address(); mapper.map_phys(address, page_phys, vma_guard.flags()); page_to_map.write_irqsave().insert_vma(pfm.vma()); diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index af1ab71d4..6a9eea57d 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -95,7 +95,7 @@ impl PageManager { } fn insert(&mut self, page: &Arc) -> Result, SystemError> { - let phys = page.read_irqsave().phys_address(); + let phys = page.phys_address(); if !self.phys2page.contains_key(&phys) { self.phys2page.insert(phys, page.clone()); Ok(page.clone()) @@ -433,6 +433,8 @@ bitflags! { #[derive(Debug)] pub struct Page { inner: RwLock, + /// 页面所在物理地址 + phys_addr: PhysAddr, } impl Page { @@ -452,6 +454,7 @@ impl Page { let inner = InnerPage::new(shared, phys_addr, page_type, flags); let page = Arc::new(Self { inner: RwLock::new(inner), + phys_addr, }); if page.read_irqsave().flags == PageFlags::PG_LRU { page_reclaimer_lock_irqsave().insert_page(phys_addr, &page); @@ -487,9 +490,15 @@ impl Page { } Ok(Arc::new(Self { inner: RwLock::new(inner), + phys_addr: new_phys, })) } + #[inline(always)] + pub fn phys_address(&self) -> PhysAddr { + self.phys_addr + } + pub fn read_irqsave(&self) -> RwLockReadGuard { self.inner.read_irqsave() } @@ -514,7 +523,7 @@ pub struct InnerPage { vma_set: HashSet>, /// 标志 flags: PageFlags, - /// 页所在的物理页帧号 + /// 页面所在物理地址 phys_addr: PhysAddr, /// 页面类型 page_type: PageType, @@ -618,7 +627,7 @@ impl InnerPage { } #[inline(always)] - pub fn phys_address(&self) -> PhysAddr { + fn phys_address(&self) -> PhysAddr { self.phys_addr } @@ -654,7 +663,7 @@ impl InnerPage { return; } - let vaddr = unsafe { MMArch::phys_2_virt(self.phys_address()).unwrap() }; + let vaddr = unsafe { MMArch::phys_2_virt(self.phys_addr).unwrap() }; unsafe { core::slice::from_raw_parts_mut( @@ -1412,7 +1421,7 @@ impl PageMapper { ) .ok()?; drop(page_manager_guard); - let phys = page.read_irqsave().phys_address(); + let phys = page.phys_address(); return self.map_phys(virt, phys, flags); } From 795169851192ec8e64665fce15b1cf1f9bbd9281 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Wed, 27 Nov 2024 23:30:47 +0800 Subject: [PATCH 29/38] =?UTF-8?q?=E5=AE=8C=E5=96=84Page=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/page_cache.rs | 1 - kernel/src/ipc/shm.rs | 10 ++-- kernel/src/ipc/syscall.rs | 14 ++++-- kernel/src/mm/fault.rs | 1 - kernel/src/mm/page.rs | 77 +++++++++-------------------- kernel/src/perf/bpf.rs | 3 +- 6 files changed, 36 insertions(+), 70 deletions(-) diff --git a/kernel/src/filesystem/page_cache.rs b/kernel/src/filesystem/page_cache.rs index 380c59b16..40224b555 100644 --- a/kernel/src/filesystem/page_cache.rs +++ b/kernel/src/filesystem/page_cache.rs @@ -71,7 +71,6 @@ impl InnerPageCache { let page_index = start_page_index + i; let page = page_manager_guard.create_one_page( - true, PageType::File(FileMapInfo { page_cache: self .page_cache_ref diff --git a/kernel/src/ipc/shm.rs b/kernel/src/ipc/shm.rs index 6ea4dd4dd..3c8a0a964 100644 --- a/kernel/src/ipc/shm.rs +++ b/kernel/src/ipc/shm.rs @@ -161,16 +161,12 @@ impl ShmManager { let page_count = PageFrameCount::from_bytes(page_align_up(size)).unwrap(); // 创建共享内存page,并添加到PAGE_MANAGER中 let mut page_manager_guard = page_manager_lock_irqsave(); - let (paddr, pages) = page_manager_guard.create_pages( - true, - PageType::Shared, + let (paddr, _page) = page_manager_guard.create_pages( + PageType::Shm(shm_id), PageFlags::empty(), &mut LockedFrameAllocator, page_count, )?; - for page in pages { - page.write_irqsave().set_shm_id(shm_id); - } // 创建共享内存信息结构体 let kern_ipc_perm = KernIpcPerm { @@ -324,7 +320,7 @@ impl ShmManager { // 设置共享内存物理页当映射计数等于0时可被回收 for _ in 0..count.data() { let page = page_manager_guard.get_unwrap(&cur_phys.phys_address()); - page.write_irqsave().set_dealloc_when_zero(true); + page.write_irqsave().remove_flags(PageFlags::PG_UNEVICTABLE); cur_phys = cur_phys.next(); } diff --git a/kernel/src/ipc/syscall.rs b/kernel/src/ipc/syscall.rs index 2d0b9b6b2..ff12385c9 100644 --- a/kernel/src/ipc/syscall.rs +++ b/kernel/src/ipc/syscall.rs @@ -16,11 +16,10 @@ use crate::{ FilePrivateData, }, ipc::shm::{shm_manager_lock, IPC_PRIVATE}, - libs::align::page_align_up, - libs::spinlock::SpinLock, + libs::{align::page_align_up, spinlock::SpinLock}, mm::{ allocator::page_frame::{PageFrameCount, PhysPageFrame, VirtPageFrame}, - page::{page_manager_lock_irqsave, EntryFlags, PageFlushAll}, + page::{page_manager_lock_irqsave, EntryFlags, PageFlushAll, PageType}, syscall::ProtFlags, ucontext::{AddressSpace, VMA}, VirtAddr, VmFlags, @@ -443,13 +442,18 @@ impl Syscall { // 如果物理页的shm_id为None,代表不是共享页 let mut page_manager_guard = page_manager_lock_irqsave(); let page = page_manager_guard.get(&paddr).ok_or(SystemError::EINVAL)?; - let shm_id = page.read_irqsave().shm_id().ok_or(SystemError::EINVAL)?; + let page_guard = page.read_irqsave(); + let shm_id = if let PageType::Shm(shm_id) = page_guard.page_type() { + shm_id + } else { + return Err(SystemError::EINVAL); + }; drop(page_manager_guard); // 获取对应共享页管理信息 let mut shm_manager_guard = shm_manager_lock(); let kernel_shm = shm_manager_guard - .get_mut(&shm_id) + .get_mut(shm_id) .ok_or(SystemError::EINVAL)?; // 更新最后一次断开连接时间 kernel_shm.update_dtim(); diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index 29e6b15cf..0fa8e6b0e 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -653,7 +653,6 @@ impl PageFaultHandler { let page = page_manager_lock_irqsave() .create_one_page( - true, PageType::File(FileMapInfo { page_cache: page_cache.clone(), index: file_pgoff, diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 6a9eea57d..64c2b6975 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -124,12 +124,11 @@ impl PageManager { /// - `Err(SystemError)`: 错误码 pub fn create_one_page( &mut self, - shared: bool, page_type: PageType, flags: PageFlags, allocator: &mut dyn FrameAllocator, ) -> Result, SystemError> { - self.create_pages(shared, page_type, flags, allocator, PageFrameCount::new(1))? + self.create_pages(page_type, flags, allocator, PageFrameCount::ONE)? .1 .first() .ok_or(SystemError::ENOMEM) @@ -152,7 +151,6 @@ impl PageManager { /// - `Err(SystemError)`: 错误码 pub fn create_pages( &mut self, - shared: bool, page_type: PageType, flags: PageFlags, allocator: &mut dyn FrameAllocator, @@ -170,7 +168,7 @@ impl PageManager { let mut cur_phys = PhysPageFrame::new(start_paddr); let mut ret: Vec> = Vec::new(); for _ in 0..count.data() { - let page = Page::new(shared, cur_phys.phys_address(), page_type.clone(), flags); + let page = Page::new(cur_phys.phys_address(), page_type.clone(), flags); if let Err(e) = self.insert(&page) { for insert_page in ret { self.remove_page(&insert_page.read_irqsave().phys_addr); @@ -427,6 +425,7 @@ bitflags! { const PG_PRIVATE = 1 << 15; const PG_RECLAIM = 1 << 18; const PG_SWAPBACKED = 1 << 19; + const PG_UNEVICTABLE = 1 << 20; } } @@ -450,8 +449,8 @@ impl Page { /// ## 返回值 /// /// - `Arc`: 新页面 - fn new(shared: bool, phys_addr: PhysAddr, page_type: PageType, flags: PageFlags) -> Arc { - let inner = InnerPage::new(shared, phys_addr, page_type, flags); + fn new(phys_addr: PhysAddr, page_type: PageType, flags: PageFlags) -> Arc { + let inner = InnerPage::new(phys_addr, page_type, flags); let page = Arc::new(Self { inner: RwLock::new(inner), phys_addr, @@ -477,10 +476,9 @@ impl Page { old_guard: RwLockReadGuard, new_phys: PhysAddr, ) -> Result, SystemError> { - let shared = old_guard.shared(); let page_type = old_guard.page_type().clone(); let flags = *old_guard.flags(); - let inner = InnerPage::new(shared, new_phys, page_type, flags); + let inner = InnerPage::new(new_phys, page_type, flags); unsafe { let old_vaddr = MMArch::phys_2_virt(old_guard.phys_address()).ok_or(SystemError::EFAULT)?; @@ -511,14 +509,6 @@ impl Page { #[derive(Debug)] /// 物理页面信息 pub struct InnerPage { - /// 映射计数 - map_count: usize, - /// 是否为共享页 - shared: bool, - /// 映射计数为0时,是否可回收 - free_when_zero: bool, - /// 共享页id(如果是共享页) - shm_id: Option, /// 映射到当前page的VMA vma_set: HashSet>, /// 标志 @@ -530,13 +520,8 @@ pub struct InnerPage { } impl InnerPage { - pub fn new(shared: bool, phys_addr: PhysAddr, page_type: PageType, flags: PageFlags) -> Self { - let dealloc_when_zero = !shared; + pub fn new(phys_addr: PhysAddr, page_type: PageType, flags: PageFlags) -> Self { Self { - map_count: 0, - shared, - free_when_zero: dealloc_when_zero, - shm_id: None, vma_set: HashSet::new(), flags, phys_addr, @@ -547,30 +532,20 @@ impl InnerPage { /// 将vma加入anon_vma pub fn insert_vma(&mut self, vma: Arc) { self.vma_set.insert(vma); - self.map_count += 1; } /// 将vma从anon_vma中删去 pub fn remove_vma(&mut self, vma: &LockedVMA) { self.vma_set.remove(vma); - self.map_count -= 1; } /// 判断当前物理页是否能被回 pub fn can_deallocate(&self) -> bool { - self.map_count == 0 && self.free_when_zero + self.map_count() == 0 && !self.flags.contains(PageFlags::PG_UNEVICTABLE) } pub fn shared(&self) -> bool { - self.shared - } - - pub fn set_shared(&mut self, shared: bool) { - self.shared = shared; - } - - pub fn shm_id(&self) -> Option { - self.shm_id + self.map_count() > 1 } pub fn page_cache(&self) -> Option> { @@ -588,14 +563,6 @@ impl InnerPage { self.page_type = page_type; } - pub fn set_shm_id(&mut self, shm_id: ShmId) { - self.shm_id = Some(shm_id); - } - - pub fn set_dealloc_when_zero(&mut self, dealloc_when_zero: bool) { - self.free_when_zero = dealloc_when_zero; - } - #[inline(always)] pub fn vma_set(&self) -> &HashSet> { &self.vma_set @@ -603,7 +570,7 @@ impl InnerPage { #[inline(always)] pub fn map_count(&self) -> usize { - self.map_count + self.vma_set.len() } #[inline(always)] @@ -677,11 +644,12 @@ impl InnerPage { impl Drop for InnerPage { fn drop(&mut self) { - assert!(self.map_count == 0, "page drop when map count is non-zero"); - if self.shared { - if let Some(shm_id) = self.shm_id { - shm_manager_lock().free_id(&shm_id); - } + assert!( + self.map_count() == 0, + "page drop when map count is non-zero" + ); + if let PageType::Shm(shm_id) = self.page_type { + shm_manager_lock().free_id(&shm_id); } unsafe { deallocate_page_frames(PhysPageFrame::new(self.phys_addr), PageFrameCount::new(1)) @@ -689,13 +657,15 @@ impl Drop for InnerPage { } } +/// 页面类型,包含额外的页面信息 #[derive(Debug, Clone)] pub enum PageType { - Uninit, - Anonymous, + /// 普通页面,不含额外信息 + Normal, + /// 文件映射页,含文件映射相关信息 File(FileMapInfo), - Shared, - Other, + /// 共享内存页,记录ShmId + Shm(ShmId), } #[derive(Debug, Clone)] @@ -1414,8 +1384,7 @@ impl PageMapper { page_manager_lock_irqsave(); let page = page_manager_guard .create_one_page( - false, - PageType::Uninit, + PageType::Normal, PageFlags::empty(), &mut self.frame_allocator, ) diff --git a/kernel/src/perf/bpf.rs b/kernel/src/perf/bpf.rs index bd3953a3e..a50ff893d 100644 --- a/kernel/src/perf/bpf.rs +++ b/kernel/src/perf/bpf.rs @@ -235,8 +235,7 @@ impl BpfPerfEvent { let mut data = self.data.lock(); let mut page_manager_guard = page_manager_lock_irqsave(); let (phy_addr, pages) = page_manager_guard.create_pages( - true, - PageType::Other, + PageType::Normal, PageFlags::empty(), &mut LockedFrameAllocator, PageFrameCount::new(page_align_up(len) / PAGE_SIZE), From f71462b1509b1cda8c18d83d0722b02fa8b411bf Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Thu, 28 Nov 2024 00:11:26 +0800 Subject: [PATCH 30/38] =?UTF-8?q?=E4=BF=AE=E5=A4=8DPageFlags=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/ipc/shm.rs | 2 +- kernel/src/perf/bpf.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/src/ipc/shm.rs b/kernel/src/ipc/shm.rs index 3c8a0a964..95170af90 100644 --- a/kernel/src/ipc/shm.rs +++ b/kernel/src/ipc/shm.rs @@ -163,7 +163,7 @@ impl ShmManager { let mut page_manager_guard = page_manager_lock_irqsave(); let (paddr, _page) = page_manager_guard.create_pages( PageType::Shm(shm_id), - PageFlags::empty(), + PageFlags::PG_UNEVICTABLE, &mut LockedFrameAllocator, page_count, )?; diff --git a/kernel/src/perf/bpf.rs b/kernel/src/perf/bpf.rs index a50ff893d..a915ad56c 100644 --- a/kernel/src/perf/bpf.rs +++ b/kernel/src/perf/bpf.rs @@ -236,7 +236,7 @@ impl BpfPerfEvent { let mut page_manager_guard = page_manager_lock_irqsave(); let (phy_addr, pages) = page_manager_guard.create_pages( PageType::Normal, - PageFlags::empty(), + PageFlags::PG_UNEVICTABLE, &mut LockedFrameAllocator, PageFrameCount::new(page_align_up(len) / PAGE_SIZE), )?; From 62c29482d462ac3b18ac77dd98c713b8d8b318d1 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Mon, 2 Dec 2024 00:38:23 +0800 Subject: [PATCH 31/38] =?UTF-8?q?=E4=BF=AE=E6=AD=A3ShmId=E9=87=8A=E6=94=BE?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/ipc/shm.rs | 1 + kernel/src/mm/page.rs | 6 ++---- kernel/src/mm/ucontext.rs | 13 ++++++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/kernel/src/ipc/shm.rs b/kernel/src/ipc/shm.rs index 95170af90..5607f351d 100644 --- a/kernel/src/ipc/shm.rs +++ b/kernel/src/ipc/shm.rs @@ -318,6 +318,7 @@ impl ShmManager { let mut page_manager_guard = page_manager_lock_irqsave(); if map_count > 0 { // 设置共享内存物理页当映射计数等于0时可被回收 + // TODO 后续需要加入到lru中 for _ in 0..count.data() { let page = page_manager_guard.get_unwrap(&cur_phys.phys_address()); page.write_irqsave().remove_flags(PageFlags::PG_UNEVICTABLE); diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 64c2b6975..9981cd831 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -19,7 +19,7 @@ use crate::{ exception::ipi::{IpiKind, IpiTarget}, filesystem::{page_cache::PageCache, vfs::FilePrivateData}, init::initcall::INITCALL_CORE, - ipc::shm::{shm_manager_lock, ShmId}, + ipc::shm::ShmId, libs::{ rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, spinlock::{SpinLock, SpinLockGuard}, @@ -648,9 +648,7 @@ impl Drop for InnerPage { self.map_count() == 0, "page drop when map count is non-zero" ); - if let PageType::Shm(shm_id) = self.page_type { - shm_manager_lock().free_id(&shm_id); - } + unsafe { deallocate_page_frames(PhysPageFrame::new(self.phys_addr), PageFrameCount::new(1)) }; diff --git a/kernel/src/mm/ucontext.rs b/kernel/src/mm/ucontext.rs index 5871ae038..ac0931032 100644 --- a/kernel/src/mm/ucontext.rs +++ b/kernel/src/mm/ucontext.rs @@ -21,6 +21,7 @@ use crate::{ arch::{mm::PageMapper, CurrentIrqArch, MMArch}, exception::InterruptArch, filesystem::vfs::file::File, + ipc::shm::shm_manager_lock, libs::{ align::page_align_up, rwlock::RwLock, @@ -1166,10 +1167,16 @@ impl LockedVMA { // 从anon_vma中删除当前VMA let page = page_manager_guard.get_unwrap(&paddr); - page.write_irqsave().remove_vma(self); + let mut page_guard = page.write_irqsave(); + page_guard.remove_vma(self); + + // 如果物理页的vma链表长度为0并且未标记为不可回收,则释放物理页. + // TODO 后续由lru释放物理页面 + if page_guard.can_deallocate() { + if let PageType::Shm(shm_id) = page_guard.page_type() { + shm_manager_lock().free_id(shm_id); + } - // 如果物理页的anon_vma链表长度为0并且不是共享页,则释放物理页. - if page.read_irqsave().can_deallocate() { page_manager_guard.remove_page(&paddr); } From 1fd014623a49e78643bcb44fa7c59a0fe7c29590 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Fri, 6 Dec 2024 19:22:58 +0800 Subject: [PATCH 32/38] =?UTF-8?q?=E5=AE=8C=E5=96=84shm=5Fid=E9=87=8A?= =?UTF-8?q?=E6=94=BE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/ipc/shm.rs | 40 ++++++++++++++++++--------------------- kernel/src/ipc/syscall.rs | 12 +++++++++++- kernel/src/mm/ucontext.rs | 5 ----- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/kernel/src/ipc/shm.rs b/kernel/src/ipc/shm.rs index 5607f351d..e2c0187fe 100644 --- a/kernel/src/ipc/shm.rs +++ b/kernel/src/ipc/shm.rs @@ -14,9 +14,8 @@ use crate::{ syscall::user_access::{UserBufferReader, UserBufferWriter}, time::PosixTimeSpec, }; -use alloc::vec::Vec; use core::sync::atomic::{compiler_fence, Ordering}; -use hashbrown::{HashMap, HashSet}; +use hashbrown::HashMap; use ida::IdAllocator; use log::info; use num::ToPrimitive; @@ -371,6 +370,8 @@ pub struct KernelShm { shm_start_paddr: PhysAddr, /// 共享内存大小(bytes),注意是用户指定的大小(未经过页面对齐) shm_size: usize, + /// 映射计数 + map_count: usize, /// 最后一次连接的时间 shm_atim: PosixTimeSpec, /// 最后一次断开连接的时间 @@ -390,6 +391,7 @@ impl KernelShm { kern_ipc_perm, shm_start_paddr, shm_size, + map_count: 0, shm_atim: PosixTimeSpec::new(0, 0), shm_dtim: PosixTimeSpec::new(0, 0), shm_ctim: PosixTimeSpec::now(), @@ -432,26 +434,7 @@ impl KernelShm { /// 共享内存段的映射计数(有多少个不同的VMA映射) pub fn map_count(&self) -> usize { - let mut page_manager_guard = page_manager_lock_irqsave(); - let mut id_set: HashSet = HashSet::new(); - let mut cur_phys = PhysPageFrame::new(self.shm_start_paddr); - let page_count = PageFrameCount::from_bytes(page_align_up(self.shm_size)).unwrap(); - - for _ in 0..page_count.data() { - let page = page_manager_guard.get(&cur_phys.phys_address()).unwrap(); - id_set.extend( - page.read_irqsave() - .vma_set() - .iter() - .map(|vma| vma.id()) - .collect::>(), - ); - - cur_phys = cur_phys.next(); - } - - // 由于LockedVMA的id是独一无二的,因此有多少个不同的id,就代表着有多少个不同的VMA映射到共享内存段 - return id_set.len(); + self.map_count } pub fn copy_from(&mut self, shm_id_ds: PosixShmIdDs) { @@ -470,6 +453,19 @@ impl KernelShm { self.update_ctim(); } + + pub fn mode(&self) -> &ShmFlags { + &self.kern_ipc_perm.mode + } + + pub fn increase_count(&mut self) { + self.map_count += 1; + } + + pub fn decrease_count(&mut self) { + assert!(self.map_count > 0, "map_count is zero"); + self.map_count -= 1; + } } /// 共享内存权限信息 diff --git a/kernel/src/ipc/syscall.rs b/kernel/src/ipc/syscall.rs index ff12385c9..3556b03f0 100644 --- a/kernel/src/ipc/syscall.rs +++ b/kernel/src/ipc/syscall.rs @@ -403,6 +403,9 @@ impl Syscall { // 更新最后一次连接时间 kernel_shm.update_atim(); + // 映射计数增加 + kernel_shm.increase_count(); + Ok(r) } @@ -457,7 +460,14 @@ impl Syscall { .ok_or(SystemError::EINVAL)?; // 更新最后一次断开连接时间 kernel_shm.update_dtim(); - drop(shm_manager_guard); + + // 映射计数减少 + kernel_shm.decrease_count(); + + // 释放shm_id + if kernel_shm.map_count() == 0 && kernel_shm.mode().contains(ShmFlags::SHM_DEST) { + shm_manager_guard.free_id(shm_id); + } // 取消映射 let flusher: PageFlushAll = PageFlushAll::new(); diff --git a/kernel/src/mm/ucontext.rs b/kernel/src/mm/ucontext.rs index ac0931032..4a18595c1 100644 --- a/kernel/src/mm/ucontext.rs +++ b/kernel/src/mm/ucontext.rs @@ -21,7 +21,6 @@ use crate::{ arch::{mm::PageMapper, CurrentIrqArch, MMArch}, exception::InterruptArch, filesystem::vfs::file::File, - ipc::shm::shm_manager_lock, libs::{ align::page_align_up, rwlock::RwLock, @@ -1173,10 +1172,6 @@ impl LockedVMA { // 如果物理页的vma链表长度为0并且未标记为不可回收,则释放物理页. // TODO 后续由lru释放物理页面 if page_guard.can_deallocate() { - if let PageType::Shm(shm_id) = page_guard.page_type() { - shm_manager_lock().free_id(shm_id); - } - page_manager_guard.remove_page(&paddr); } From 14bf62ba3504a173eded91cff21381489a6f55d5 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Sat, 7 Dec 2024 22:38:35 +0800 Subject: [PATCH 33/38] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E9=80=80=E5=87=BA=E6=97=B6=E6=9C=AA=E5=88=86=E7=A6=BB=E5=85=B1?= =?UTF-8?q?=E4=BA=AB=E5=86=85=E5=AD=98=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/ipc/syscall.rs | 37 +------------------------------------ kernel/src/mm/ucontext.rs | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/kernel/src/ipc/syscall.rs b/kernel/src/ipc/syscall.rs index 3556b03f0..1b5b93cb7 100644 --- a/kernel/src/ipc/syscall.rs +++ b/kernel/src/ipc/syscall.rs @@ -19,7 +19,7 @@ use crate::{ libs::{align::page_align_up, spinlock::SpinLock}, mm::{ allocator::page_frame::{PageFrameCount, PhysPageFrame, VirtPageFrame}, - page::{page_manager_lock_irqsave, EntryFlags, PageFlushAll, PageType}, + page::{page_manager_lock_irqsave, EntryFlags, PageFlushAll}, syscall::ProtFlags, ucontext::{AddressSpace, VMA}, VirtAddr, VmFlags, @@ -434,41 +434,6 @@ impl Syscall { return Err(SystemError::EINVAL); } - // 获取映射的物理地址 - let paddr = address_write_guard - .user_mapper - .utable - .translate(vaddr) - .ok_or(SystemError::EINVAL)? - .0; - - // 如果物理页的shm_id为None,代表不是共享页 - let mut page_manager_guard = page_manager_lock_irqsave(); - let page = page_manager_guard.get(&paddr).ok_or(SystemError::EINVAL)?; - let page_guard = page.read_irqsave(); - let shm_id = if let PageType::Shm(shm_id) = page_guard.page_type() { - shm_id - } else { - return Err(SystemError::EINVAL); - }; - drop(page_manager_guard); - - // 获取对应共享页管理信息 - let mut shm_manager_guard = shm_manager_lock(); - let kernel_shm = shm_manager_guard - .get_mut(shm_id) - .ok_or(SystemError::EINVAL)?; - // 更新最后一次断开连接时间 - kernel_shm.update_dtim(); - - // 映射计数减少 - kernel_shm.decrease_count(); - - // 释放shm_id - if kernel_shm.map_count() == 0 && kernel_shm.mode().contains(ShmFlags::SHM_DEST) { - shm_manager_guard.free_id(shm_id); - } - // 取消映射 let flusher: PageFlushAll = PageFlushAll::new(); vma.unmap(&mut address_write_guard.user_mapper.utable, flusher); diff --git a/kernel/src/mm/ucontext.rs b/kernel/src/mm/ucontext.rs index 4a18595c1..45f411ca1 100644 --- a/kernel/src/mm/ucontext.rs +++ b/kernel/src/mm/ucontext.rs @@ -21,6 +21,7 @@ use crate::{ arch::{mm::PageMapper, CurrentIrqArch, MMArch}, exception::InterruptArch, filesystem::vfs::file::File, + ipc::shm::{shm_manager_lock, ShmFlags}, libs::{ align::page_align_up, rwlock::RwLock, @@ -1151,12 +1152,35 @@ impl LockedVMA { pub fn unmap(&self, mapper: &mut PageMapper, mut flusher: impl Flusher) { // todo: 如果当前vma与文件相关,完善文件相关的逻辑 - let mut guard = self.lock_irqsave(); // 获取物理页的anon_vma的守卫 let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> = page_manager_lock_irqsave(); + + // 获取映射的物理地址 + if let Some((paddr, _flags)) = mapper.translate(guard.region().start()) { + // 如果是共享页,执行释放操作 + let page = page_manager_guard.get(&paddr).unwrap(); + let page_guard = page.read_irqsave(); + if let PageType::Shm(shm_id) = page_guard.page_type() { + let mut shm_manager_guard = shm_manager_lock(); + if let Some(kernel_shm) = shm_manager_guard.get_mut(shm_id) { + // 更新最后一次断开连接时间 + kernel_shm.update_dtim(); + + // 映射计数减少 + kernel_shm.decrease_count(); + + // 释放shm_id + if kernel_shm.map_count() == 0 && kernel_shm.mode().contains(ShmFlags::SHM_DEST) + { + shm_manager_guard.free_id(shm_id); + } + } + } + } + for page in guard.region.pages() { if mapper.translate(page.virt_address()).is_none() { continue; From b863ac3610cc33d55cffeea85108733bae08a7f3 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Thu, 12 Dec 2024 04:59:40 +0800 Subject: [PATCH 34/38] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=84=8F=E9=A1=B5?= =?UTF-8?q?=E6=9C=AA=E8=87=AA=E5=8A=A8=E5=9B=9E=E5=86=99=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/filesystem/fat/fs.rs | 2 +- kernel/src/filesystem/page_cache.rs | 12 +++++++----- kernel/src/mm/page.rs | 24 ++++++++++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 334d74fcb..88712c458 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -155,7 +155,7 @@ impl FATInode { /// 更新访问时间 pub fn update_time(&mut self) { - log::warn!("update_time has not yet been implemented"); + // log::warn!("update_time has not yet been implemented"); } fn find(&mut self, name: &str) -> Result, SystemError> { diff --git a/kernel/src/filesystem/page_cache.rs b/kernel/src/filesystem/page_cache.rs index 40224b555..7f5959331 100644 --- a/kernel/src/filesystem/page_cache.rs +++ b/kernel/src/filesystem/page_cache.rs @@ -249,20 +249,22 @@ impl InnerPageCache { MMArch::PAGE_SIZE }; - let exist = self.get_page(page_index).is_some(); + let mut page = self.get_page(page_index); - if !exist { + if page.is_none() { let page_buf = vec![0u8; MMArch::PAGE_SIZE]; self.create_pages(page_index, &page_buf)?; + page = self.get_page(page_index); } - if let Some(page) = self.get_page(page_index) { + if let Some(page) = page { let sub_buf = &buf[buf_offset..(buf_offset + sub_len)]; - + let mut page_guard = page.write_irqsave(); unsafe { - page.write_irqsave().as_slice_mut()[page_offset..page_offset + sub_len] + page_guard.as_slice_mut()[page_offset..page_offset + sub_len] .copy_from_slice(sub_buf); } + page_guard.add_flags(PageFlags::PG_DIRTY); ret += sub_len; diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 9981cd831..f0dcbb73f 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -303,7 +303,7 @@ impl PageReclaimer { for _ in 0..count.data() { let (_, page) = self.lru.pop_lru().expect("pagecache is empty"); if page.read_irqsave().flags.contains(PageFlags::PG_DIRTY) { - Self::page_writeback(&page, true); + self.page_writeback(&page, true); } } } @@ -322,8 +322,8 @@ impl PageReclaimer { /// /// ## 返回值 /// - VmFaultReason: 页面错误处理信息标志 - pub fn page_writeback(page: &Arc, unmap: bool) { - // log::debug!("page writeback: {page:?}"); + pub fn page_writeback(&mut self, page: &Arc, unmap: bool) { + log::debug!("page writeback: {page:?}"); let guard = page.read_irqsave(); let (page_cache, page_index) = match guard.page_type() { @@ -372,7 +372,7 @@ impl PageReclaimer { }; inode - .write_at( + .write_direct( page_index * MMArch::PAGE_SIZE, len, unsafe { @@ -389,6 +389,7 @@ impl PageReclaimer { // 删除页面 page_cache.lock_irqsave().remove_page(page_index); page_manager_lock_irqsave().remove_page(&paddr); + self.remove_page(&paddr); } else { // 清除标记 page.write_irqsave().remove_flags(PageFlags::PG_DIRTY); @@ -396,12 +397,19 @@ impl PageReclaimer { } /// lru脏页刷新 - pub fn flush_dirty_pages(&self) { + pub fn flush_dirty_pages(&mut self) { // log::info!("flush_dirty_pages"); - let iter = self.lru.iter(); - for (_, page) in iter { + let iter = self.lru.iter().filter_map(|(_, page)| { if page.read_irqsave().flags().contains(PageFlags::PG_DIRTY) { - Self::page_writeback(page, false); + Some(page.clone()) + } else { + None + } + }); + let collection: Vec> = iter.collect(); + for page in collection { + if page.read_irqsave().flags().contains(PageFlags::PG_DIRTY) { + self.page_writeback(&page, false); } } } From 2d3912b77e79ea61133c4578b6a85650e5cf5e66 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Thu, 12 Dec 2024 21:01:49 +0800 Subject: [PATCH 35/38] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/mm/page.rs | 44 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index f0dcbb73f..d4d63e191 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -302,8 +302,20 @@ impl PageReclaimer { pub fn shrink_list(&mut self, count: PageFrameCount) { for _ in 0..count.data() { let (_, page) = self.lru.pop_lru().expect("pagecache is empty"); - if page.read_irqsave().flags.contains(PageFlags::PG_DIRTY) { - self.page_writeback(&page, true); + let guard = page.write_irqsave(); + if let PageType::File(info) = guard.page_type() { + let page_cache = &info.page_cache; + let page_index = info.index; + let paddr = guard.phys_address(); + if guard.flags().contains(PageFlags::PG_DIRTY) { + // 先回写脏页 + Self::page_writeback(&page, true); + } + + // 删除页面 + page_cache.lock_irqsave().remove_page(page_index); + page_manager_lock_irqsave().remove_page(&paddr); + self.remove_page(&paddr); } } } @@ -322,8 +334,8 @@ impl PageReclaimer { /// /// ## 返回值 /// - VmFaultReason: 页面错误处理信息标志 - pub fn page_writeback(&mut self, page: &Arc, unmap: bool) { - log::debug!("page writeback: {page:?}"); + pub fn page_writeback(page: &Arc, unmap: bool) { + // log::debug!("page writeback: {page:?}"); let guard = page.read_irqsave(); let (page_cache, page_index) = match guard.page_type() { @@ -385,31 +397,17 @@ impl PageReclaimer { ) .unwrap(); - if unmap { - // 删除页面 - page_cache.lock_irqsave().remove_page(page_index); - page_manager_lock_irqsave().remove_page(&paddr); - self.remove_page(&paddr); - } else { - // 清除标记 - page.write_irqsave().remove_flags(PageFlags::PG_DIRTY); - } + // 清除标记 + page.write_irqsave().remove_flags(PageFlags::PG_DIRTY); } /// lru脏页刷新 pub fn flush_dirty_pages(&mut self) { // log::info!("flush_dirty_pages"); - let iter = self.lru.iter().filter_map(|(_, page)| { - if page.read_irqsave().flags().contains(PageFlags::PG_DIRTY) { - Some(page.clone()) - } else { - None - } - }); - let collection: Vec> = iter.collect(); - for page in collection { + let iter = self.lru.iter(); + for (_paddr, page) in iter { if page.read_irqsave().flags().contains(PageFlags::PG_DIRTY) { - self.page_writeback(&page, false); + Self::page_writeback(page, false); } } } From b4b6ca8e684d7e2c7d5eb3355dc0fef859b9dd83 Mon Sep 17 00:00:00 2001 From: MemoryShore <1353318529@qq.com> Date: Fri, 13 Dec 2024 03:02:10 +0800 Subject: [PATCH 36/38] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=AD=BB=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/mm/page.rs | 24 +++++++++++------------- kernel/src/mm/ucontext.rs | 9 ++------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index d4d63e191..d635a4f32 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -302,14 +302,14 @@ impl PageReclaimer { pub fn shrink_list(&mut self, count: PageFrameCount) { for _ in 0..count.data() { let (_, page) = self.lru.pop_lru().expect("pagecache is empty"); - let guard = page.write_irqsave(); - if let PageType::File(info) = guard.page_type() { + let mut guard = page.write_irqsave(); + if let PageType::File(info) = guard.page_type().clone() { let page_cache = &info.page_cache; let page_index = info.index; let paddr = guard.phys_address(); if guard.flags().contains(PageFlags::PG_DIRTY) { // 先回写脏页 - Self::page_writeback(&page, true); + Self::page_writeback(&mut guard, true); } // 删除页面 @@ -329,15 +329,14 @@ impl PageReclaimer { /// 脏页回写函数 /// ## 参数 /// - /// - `page`: 需要回写的脏页 + /// - `guard`: 需要回写的脏页 /// - `unmap`: 是否取消映射 /// /// ## 返回值 /// - VmFaultReason: 页面错误处理信息标志 - pub fn page_writeback(page: &Arc, unmap: bool) { - // log::debug!("page writeback: {page:?}"); + pub fn page_writeback(guard: &mut RwLockWriteGuard, unmap: bool) { + // log::debug!("page writeback: {:?}", guard.phys_addr); - let guard = page.read_irqsave(); let (page_cache, page_index) = match guard.page_type() { PageType::File(info) => (info.page_cache.clone(), info.index), _ => { @@ -353,7 +352,7 @@ impl PageReclaimer { let address_space = address_space.upgrade().unwrap(); let mut guard = address_space.write(); let mapper = &mut guard.user_mapper.utable; - let virt = vma.lock_irqsave().page_address(page).unwrap(); + let virt = vma.lock_irqsave().page_address(page_index).unwrap(); if unmap { unsafe { // 取消页表映射 @@ -370,8 +369,6 @@ impl PageReclaimer { } } - drop(guard); - let len = if let Ok(metadata) = inode.metadata() { let size = metadata.size as usize; if size < page_index * MMArch::PAGE_SIZE { @@ -398,7 +395,7 @@ impl PageReclaimer { .unwrap(); // 清除标记 - page.write_irqsave().remove_flags(PageFlags::PG_DIRTY); + guard.remove_flags(PageFlags::PG_DIRTY); } /// lru脏页刷新 @@ -406,8 +403,9 @@ impl PageReclaimer { // log::info!("flush_dirty_pages"); let iter = self.lru.iter(); for (_paddr, page) in iter { - if page.read_irqsave().flags().contains(PageFlags::PG_DIRTY) { - Self::page_writeback(page, false); + let mut guard = page.write_irqsave(); + if guard.flags().contains(PageFlags::PG_DIRTY) { + Self::page_writeback(&mut guard, false); } } } diff --git a/kernel/src/mm/ucontext.rs b/kernel/src/mm/ucontext.rs index 45f411ca1..04d953b28 100644 --- a/kernel/src/mm/ucontext.rs +++ b/kernel/src/mm/ucontext.rs @@ -36,7 +36,7 @@ use super::{ allocator::page_frame::{ deallocate_page_frames, PageFrameCount, PhysPageFrame, VirtPageFrame, VirtPageFrameIter, }, - page::{EntryFlags, Flusher, InactiveFlusher, Page, PageFlushAll, PageType}, + page::{EntryFlags, Flusher, InactiveFlusher, PageFlushAll, PageType}, syscall::{MadvFlags, MapFlags, MremapFlags, ProtFlags}, MemoryManagementArch, PageTableKind, VirtAddr, VirtRegion, VmFlags, }; @@ -1677,12 +1677,7 @@ impl VMA { return Ok(r); } - pub fn page_address(&self, page: &Arc) -> Result { - let page_guard = page.read_irqsave(); - let index = match page_guard.page_type() { - PageType::File(info) => info.index, - _ => return Err(SystemError::EINVAL), - }; + pub fn page_address(&self, index: usize) -> Result { if index >= self.file_pgoff.unwrap() { let address = self.region.start + ((index - self.file_pgoff.unwrap()) << MMArch::PAGE_SHIFT); From ce418954ad5fc7cd5d893d4a9a97907eb6a8a29f Mon Sep 17 00:00:00 2001 From: longjin Date: Mon, 16 Dec 2024 02:00:15 +0800 Subject: [PATCH 37/38] =?UTF-8?q?=E6=8A=8A=E5=9B=9E=E5=86=99=E9=97=B4?= =?UTF-8?q?=E9=9A=94=E6=94=B9=E4=B8=BA0.5s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/mm/page.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index d635a4f32..3ec685472 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -261,7 +261,7 @@ fn page_reclaim_thread() -> i32 { page_reclaimer_lock_irqsave().flush_dirty_pages(); // 休眠5秒 // log::info!("sleep"); - let _ = nanosleep(PosixTimeSpec::new(5, 0)); + let _ = nanosleep(PosixTimeSpec::new(0, 500_000_000)); } } } From 50bf8c3b083c673452fec9db998cba989e361bb7 Mon Sep 17 00:00:00 2001 From: longjin Date: Mon, 16 Dec 2024 02:00:26 +0800 Subject: [PATCH 38/38] =?UTF-8?q?=E6=9B=B4=E6=96=B0novashell=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=88=B0feaebefaef?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- user/dadk/config/nova_shell-0.1.0.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user/dadk/config/nova_shell-0.1.0.toml b/user/dadk/config/nova_shell-0.1.0.toml index 190de5fd4..e5778ddfd 100644 --- a/user/dadk/config/nova_shell-0.1.0.toml +++ b/user/dadk/config/nova_shell-0.1.0.toml @@ -24,7 +24,7 @@ source = "git" source-path = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/NovaShell.git" # git标签或分支 # 注意: branch和revision只能二选一,且source要设置为"git" -revision = "cb835e03e4" +revision = "feaebefaef" # 构建相关信息 [build] # (可选)构建命令