Skip to content

Commit d1d0aca

Browse files
committed
20240527 0010
1 parent 80ca935 commit d1d0aca

File tree

5 files changed

+69
-44
lines changed

5 files changed

+69
-44
lines changed

kernel/src/arch/riscv64/mm/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{
1212
page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
1313
},
1414
kernel_mapper::KernelMapper,
15-
page::{PageEntry, EntryFlags, PAGE_1G_SHIFT},
15+
page::{EntryFlags, PageEntry, PAGE_1G_SHIFT},
1616
ucontext::UserMapper,
1717
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
1818
},

kernel/src/arch/x86_64/mm/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::{
2727
};
2828

2929
use crate::mm::kernel_mapper::KernelMapper;
30-
use crate::mm::page::{PageEntry, EntryFlags, PAGE_1G_SHIFT};
30+
use crate::mm::page::{EntryFlags, PageEntry, PAGE_1G_SHIFT};
3131
use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr};
3232
use crate::{kdebug, kinfo, kwarn};
3333
use system_error::SystemError;

kernel/src/filesystem/vfs/file.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
base::{block::SeekFrom, device::DevicePrivateData},
1414
tty::tty_device::TtyFilePrivateData,
1515
},
16-
filesystem::{fat::fs::LockedFATInode, procfs::ProcfsFilePrivateData},
16+
filesystem::procfs::ProcfsFilePrivateData,
1717
ipc::pipe::{LockedPipeInode, PipeFsPrivateData},
1818
kerror,
1919
libs::{rwlock::RwLock, spinlock::SpinLock},
@@ -25,7 +25,7 @@ use crate::{
2525
process::ProcessManager,
2626
};
2727

28-
use super::{mount::MountFSInode, Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData};
28+
use super::{Dirent, FileType, IndexNode, InodeId, Metadata, SpecialNodeData};
2929

3030
/// 文件私有信息的枚举类型
3131
#[derive(Debug, Clone)]
@@ -121,6 +121,7 @@ impl FileMode {
121121
}
122122
}
123123

124+
#[allow(dead_code)]
124125
pub struct PageCache {
125126
inode_ref: Weak<dyn IndexNode>,
126127
map: HashMap<usize, Arc<Page>>,
@@ -134,12 +135,12 @@ impl PageCache {
134135
}
135136
}
136137

137-
pub fn set_page(&mut self, offset: usize, page: Arc<Page>) {
138+
pub fn add_page(&mut self, offset: usize, page: Arc<Page>) {
138139
self.map.insert(offset, page);
139140
}
140141

141142
pub fn get_page(&self, offset: usize) -> Option<Arc<Page>> {
142-
self.map.get(&offset).map(|page| page.clone())
143+
self.map.get(&offset).cloned()
143144
}
144145

145146
// pub fn get_pages(&self, start_pgoff: usize, end_pgoff: usize) -> Vec<Arc<Page>> {
@@ -158,16 +159,6 @@ pub trait PageCacheOperations: IndexNode {
158159
fn read_ahead(&self);
159160
}
160161

161-
impl PageCacheOperations for LockedFATInode {
162-
fn write_page(&self, page: Page) {
163-
todo!()
164-
}
165-
166-
fn read_ahead(&self) {
167-
todo!()
168-
}
169-
}
170-
171162
/// @brief 抽象文件结构体
172163
#[derive(Debug)]
173164
pub struct File {

kernel/src/mm/fault.rs

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::{alloc::Layout, cmp::min, intrinsics::unlikely, panic};
22

3-
use alloc::sync::Arc;
3+
use alloc::{sync::Arc, vec::Vec};
44

55
use crate::{
66
arch::{mm::PageMapper, MMArch},
@@ -15,7 +15,8 @@ use crate::{
1515
use crate::mm::MemoryManagementArch;
1616

1717
use super::{
18-
page::{self, PageFlags},
18+
allocator::page_frame::{FrameAllocator, PhysPageFrame},
19+
page::{Page, PageFlags},
1920
phys_2_virt,
2021
};
2122

@@ -309,19 +310,20 @@ impl PageFaultHandler {
309310
/// - VmFaultReason: 页面错误处理信息标志
310311
#[allow(dead_code, unused_variables)]
311312
pub unsafe fn do_read_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
312-
panic!(
313-
"do_read_fault has not yet been implemented,
314-
fault message: {:?},
315-
pid: {}\n",
316-
pfm,
317-
crate::process::ProcessManager::current_pid().data()
318-
);
313+
// panic!(
314+
// "do_read_fault has not yet been implemented,
315+
// fault message: {:?},
316+
// pid: {}\n",
317+
// pfm,
318+
// crate::process::ProcessManager::current_pid().data()
319+
// );
319320

320321
// TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_read_fault
321-
let mut ret = VmFaultReason::empty();
322-
ret = Self::do_fault_around(pfm, mapper);
323-
ret = Self::filemap_fault(pfm, mapper);
324-
return ret;
322+
let ret = Self::do_fault_around(pfm.clone(), mapper);
323+
if !ret.is_empty() {
324+
return ret;
325+
}
326+
return Self::filemap_fault(pfm.clone(), mapper);
325327
}
326328

327329
/// 处理对共享文件映射区写入引起的缺页
@@ -433,20 +435,24 @@ impl PageFaultHandler {
433435
}
434436

435437
pub unsafe fn do_fault_around(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
436-
mapper
437-
.allocate_table(*pfm.address(), 0)
438-
.expect("failed to allocate pte table");
438+
if mapper.get_table(*pfm.address(), 0).is_none() {
439+
mapper
440+
.allocate_table(*pfm.address(), 0)
441+
.expect("failed to allocate pte table");
442+
}
439443
let vma = pfm.vma();
440444
let vma_guard = vma.lock();
441445
let vma_region = vma_guard.region();
442446
// 缺页在VMA中的偏移量
443447
let vm_pgoff = (*pfm.address() - vma_region.start()) >> MMArch::PAGE_SHIFT;
448+
444449
// 缺页在PTE中的偏移量
445-
let pte_pgoff = (pfm.address().data() >> MMArch::PAGE_SHIFT) & (1 << MMArch::PAGE_SIZE);
450+
let pte_pgoff =
451+
(pfm.address().data() >> MMArch::PAGE_SHIFT) & (1 << MMArch::PAGE_ENTRY_SHIFT);
446452

447453
let vma_pages_count = (vma_region.end() - vma_region.start()) >> MMArch::PAGE_SHIFT;
448454

449-
// 开始位置不能超出当前pte和vma头部的最小值
455+
// 开始位置不能超出当前pte和vma头部
450456
let from_pte = pte_pgoff - min(vm_pgoff, pte_pgoff);
451457

452458
let fault_around_page_number = 16;
@@ -464,11 +470,11 @@ impl PageFaultHandler {
464470
);
465471

466472
// 预先分配pte页表(如果不存在)
467-
if mapper.get_table(*pfm.address(), 0).is_none() {
468-
if mapper.allocate_table(*pfm.address(), 0).is_none() {
469-
return VmFaultReason::VM_FAULT_OOM;
470-
}
471-
};
473+
if mapper.get_table(*pfm.address(), 0).is_none()
474+
&& mapper.allocate_table(*pfm.address(), 0).is_none()
475+
{
476+
return VmFaultReason::VM_FAULT_OOM;
477+
}
472478

473479
// from_pte - pte_pgoff得出预读起始pte相对缺失页的偏移,加上pfm.file_pgoff(缺失页在文件中的偏移)得出起始页在文件中的偏移,结束pte同理
474480
Self::filemap_map_pages(
@@ -515,7 +521,7 @@ impl PageFaultHandler {
515521
let frame = virt as *mut u8;
516522
let new_frame =
517523
phys_2_virt(mapper.translate(address).unwrap().0.data()) as *mut u8;
518-
frame.copy_from_nonoverlapping(new_frame, MMArch::PAGE_SIZE);
524+
new_frame.copy_from_nonoverlapping(frame, MMArch::PAGE_SIZE);
519525
}
520526
}
521527
}
@@ -526,22 +532,44 @@ impl PageFaultHandler {
526532
let vma = pfm.vma();
527533
let vma_guard = vma.lock();
528534
let file = vma_guard.vm_file().expect("no vm_file in vma");
529-
let page_cache = file.inode().page_cache().unwrap();
535+
let mut page_cache = file.inode().page_cache().unwrap();
530536

531537
if let Some(page) = page_cache.get_page(pfm.file_pgoff) {
532538
// TODO 异步从磁盘中预读页面进PageCache
533539
let address = vma_guard.region().start
534-
+ (pfm.file_pgoff
540+
+ ((pfm.file_pgoff
535541
- vma_guard
536542
.file_page_offset()
537-
.expect("file_page_offset is none")
543+
.expect("file_page_offset is none"))
538544
<< MMArch::PAGE_SHIFT);
539545
mapper.map(address, vma_guard.flags()).unwrap().flush();
540546
let frame = phys_2_virt(page.phys_frame().phys_address().data()) as *mut u8;
541547
let new_frame = phys_2_virt(mapper.translate(address).unwrap().0.data()) as *mut u8;
542-
frame.copy_from_nonoverlapping(new_frame, MMArch::PAGE_SIZE);
548+
new_frame.copy_from_nonoverlapping(frame, MMArch::PAGE_SIZE);
543549
} else {
544550
// TODO 同步预读
551+
let mut buf: Vec<u8> = vec![0; MMArch::PAGE_SIZE];
552+
file.pread(
553+
pfm.file_pgoff * MMArch::PAGE_SIZE,
554+
MMArch::PAGE_SIZE,
555+
&mut buf[..],
556+
)
557+
.unwrap();
558+
let allocator = mapper.allocator_mut();
559+
560+
// 分配一个物理页面作为加入PageCache的新页
561+
let new_cache_page = allocator.allocate_one().unwrap();
562+
(phys_2_virt(new_cache_page.data()) as *mut u8)
563+
.copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
564+
page_cache.add_page(
565+
pfm.file_pgoff,
566+
Arc::new(Page::new(false, PhysPageFrame::new(new_cache_page))),
567+
);
568+
569+
// 分配空白页并映射到缺页地址
570+
mapper.map(pfm.address, vma_guard.flags()).unwrap().flush();
571+
let new_frame = phys_2_virt(mapper.translate(pfm.address).unwrap().0.data());
572+
(new_frame as *mut u8).copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
545573
}
546574
VmFaultReason::VM_FAULT_COMPLETED
547575
}

kernel/src/mm/page.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@ pub struct EntryFlags<Arch> {
495495
phantom: PhantomData<Arch>,
496496
}
497497

498+
impl<Arch: MemoryManagementArch> Default for EntryFlags<Arch> {
499+
fn default() -> Self {
500+
Self::new()
501+
}
502+
}
503+
498504
#[allow(dead_code)]
499505
impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
500506
#[inline(always)]

0 commit comments

Comments
 (0)