Refactor: wrap RwLock<AddrSpace>.

This commit is contained in:
4lDO2
2024-02-26 15:40:58 +01:00
parent 749df4c869
commit 156017a25d
14 changed files with 93 additions and 79 deletions
+5 -4
View File
@@ -5,7 +5,7 @@ use rmm::PhysicalAddress;
use spin::RwLock;
use crate::{
context::memory::{handle_notify_files, AddrSpace, Grant, PageSpan},
context::memory::{handle_notify_files, AddrSpace, Grant, PageSpan, AddrSpaceWrapper},
memory::{free_frames, used_frames, Frame, PAGE_SIZE},
paging::VirtualAddress,
};
@@ -68,7 +68,7 @@ fn from_raw(raw: u32) -> Option<(HandleTy, MemoryType, HandleFlags)> {
impl MemoryScheme {
pub fn fmap_anonymous(
addr_space: &Arc<RwLock<AddrSpace>>,
addr_space: &Arc<AddrSpaceWrapper>,
map: &Map,
is_phys_contiguous: bool,
) -> Result<usize> {
@@ -83,7 +83,7 @@ impl MemoryScheme {
return Err(Error::new(EOPNOTSUPP));
}
let page = addr_space.write().mmap(
let page = addr_space.inner.write().mmap(
(map.address != 0).then_some(span.base),
page_count,
map.flags,
@@ -132,6 +132,7 @@ impl MemoryScheme {
let page_count = NonZeroUsize::new(size.div_ceil(PAGE_SIZE)).ok_or(Error::new(EINVAL))?;
AddrSpace::current()?
.inner
.write()
.mmap_anywhere(
page_count,
@@ -234,7 +235,7 @@ impl KernelScheme for MemoryScheme {
fn kfmap(
&self,
id: usize,
addr_space: &Arc<RwLock<AddrSpace>>,
addr_space: &Arc<AddrSpaceWrapper>,
map: &Map,
_consume: bool,
) -> Result<usize> {
+2 -2
View File
@@ -13,7 +13,7 @@ use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
use syscall::{EventFlags, MunmapFlags, SendFdFlags, SEEK_CUR, SEEK_END, SEEK_SET};
use crate::{
context::{file::FileDescription, memory::AddrSpace},
context::{file::FileDescription, memory::{AddrSpace, AddrSpaceWrapper}},
syscall::{
error::*,
usercopy::{UserSliceRo, UserSliceWo},
@@ -381,7 +381,7 @@ pub trait KernelScheme: Send + Sync + 'static {
fn kfmap(
&self,
number: usize,
addr_space: &Arc<RwLock<AddrSpace>>,
addr_space: &Arc<AddrSpaceWrapper>,
map: &crate::syscall::data::Map,
consume: bool,
) -> Result<usize> {
+15 -15
View File
@@ -3,7 +3,7 @@ use crate::{
context::{
self,
file::FileDescriptor,
memory::{handle_notify_files, new_addrspace, AddrSpace, Grant, PageSpan},
memory::{handle_notify_files, AddrSpace, Grant, PageSpan, AddrSpaceWrapper},
Context, ContextId, Status,
},
memory::PAGE_SIZE,
@@ -127,7 +127,7 @@ enum Operation {
filetable: Arc<RwLock<Vec<Option<FileDescriptor>>>>,
},
AddrSpace {
addrspace: Arc<RwLock<AddrSpace>>,
addrspace: Arc<AddrSpaceWrapper>,
},
CurrentAddrSpace,
@@ -135,7 +135,7 @@ enum Operation {
// types, is that we would rather want the actual switch to occur when closing, as opposed to
// when writing. This is so that we can actually guarantee that no file descriptors are leaked.
AwaitingAddrSpaceChange {
new: Arc<RwLock<AddrSpace>>,
new: Arc<AddrSpaceWrapper>,
new_sp: usize,
new_ip: usize,
},
@@ -153,7 +153,7 @@ enum Operation {
CurrentSigactions,
AwaitingSigactionsChange(Arc<RwLock<Vec<(SigAction, usize)>>>),
MmapMinAddr(Arc<RwLock<AddrSpace>>),
MmapMinAddr(Arc<AddrSpaceWrapper>),
}
#[derive(Clone, Copy, PartialEq, Eq)]
enum Attr {
@@ -692,7 +692,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
fn kfmap(
&self,
id: usize,
dst_addr_space: &Arc<RwLock<AddrSpace>>,
dst_addr_space: &Arc<AddrSpaceWrapper>,
map: &crate::syscall::data::Map,
consume: bool,
) -> Result<usize> {
@@ -717,8 +717,8 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
let requested_dst_base = (map.address != 0).then_some(requested_dst_page);
let mut src_addr_space = addrspace.write();
let mut dst_addr_space = dst_addr_space.write();
let mut src_addr_space = addrspace.inner.write();
let mut dst_addr_space = dst_addr_space.inner.write();
let src_page_count = NonZeroUsize::new(src_span.count).ok_or(Error::new(EINVAL))?;
@@ -901,7 +901,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
for (dst, (grant_base, grant_info)) in dst
.iter_mut()
.zip(addrspace.read().grants.iter().skip(orig_offset))
.zip(addrspace.inner.read().grants.iter().skip(orig_offset))
{
*dst = GrantDesc {
base: grant_base.start_address().data(),
@@ -981,7 +981,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
read_from(buf, &data.buf, &mut data.offset)
}
Operation::MmapMinAddr(ref addrspace) => {
buf.write_usize(addrspace.read().mmap_min)?;
buf.write_usize(addrspace.inner.read().mmap_min)?;
Ok(mem::size_of::<usize>())
}
Operation::SchedAffinity => {
@@ -1053,7 +1053,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
let unpin = false;
addrspace
.write()
.inner.write()
.munmap(PageSpan::new(page, page_count), unpin)?;
}
ADDRSPACE_OP_MPROTECT => {
@@ -1062,7 +1062,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
let flags = MapFlags::from_bits(next()??).ok_or(Error::new(EINVAL))?;
addrspace
.write()
.inner.write()
.mprotect(PageSpan::new(page, page_count), flags)?;
}
_ => return Err(Error::new(EINVAL)),
@@ -1304,7 +1304,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
if val % PAGE_SIZE != 0 || val > crate::USER_END_OFFSET {
return Err(Error::new(EINVAL));
}
addrspace.write().mmap_min = val;
addrspace.inner.write().mmap_min = val;
Ok(mem::size_of::<usize>())
}
Operation::SchedAffinity => {
@@ -1441,10 +1441,10 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
// TODO: Better way to obtain new empty address spaces, perhaps using SYS_OPEN. But
// in that case, what scheme?
b"empty" => Operation::AddrSpace {
addrspace: new_addrspace()?,
addrspace: AddrSpaceWrapper::new()?,
},
b"exclusive" => Operation::AddrSpace {
addrspace: addrspace.write().try_clone()?,
addrspace: addrspace.inner.write().try_clone()?,
},
b"mmap-min-addr" => Operation::MmapMinAddr(Arc::clone(addrspace)),
@@ -1461,7 +1461,7 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
let page = Page::containing_address(VirtualAddress::new(page_addr));
match addrspace
.read()
.inner.read()
.grants
.contains(page)
.ok_or(Error::new(EINVAL))?
+2 -2
View File
@@ -32,7 +32,7 @@ pub fn resource() -> Result<Vec<u8>> {
// TODO: All user programs must have some grant in order for executable memory to even
// exist, but is this a good indicator of whether it is user or kernel?
stat_string.push(if let Ok(addr_space) = context.addr_space() {
if addr_space.read().grants.is_empty() {
if addr_space.inner.read().grants.is_empty() {
'K'
} else {
'U'
@@ -84,7 +84,7 @@ pub fn resource() -> Result<Vec<u8>> {
memory += kstack.len();
}
if let Ok(addr_space) = context.addr_space() {
for (_base, info) in addr_space.read().grants.iter() {
for (_base, info) in addr_space.inner.read().grants.iter() {
// TODO: method
if matches!(info.provider, context::memory::Provider::Allocated { .. }) {
memory += info.page_count() * PAGE_SIZE;
+11 -9
View File
@@ -24,7 +24,7 @@ use crate::{
context::HardBlockedReason,
file::{FileDescription, FileDescriptor},
memory::{
AddrSpace, BorrowedFmapSource, Grant, GrantFileRef, MmapMode, PageSpan, DANGLING,
AddrSpace, BorrowedFmapSource, Grant, GrantFileRef, MmapMode, PageSpan, DANGLING, AddrSpaceWrapper,
},
BorrowedHtBuf, Context, Status,
},
@@ -242,7 +242,7 @@ impl UserInner {
tail.buf_mut()[..buf.len()].copy_from_slice(buf);
let is_pinned = true;
let dst_page = dst_addr_space.write().mmap_anywhere(
let dst_page = dst_addr_space.inner.write().mmap_anywhere(
ONE,
PROT_READ,
|dst_page, flags, mapper, flusher| {
@@ -342,7 +342,7 @@ impl UserInner {
.split_at(core::cmp::min(align_offset, user_buf.len()))
.expect("split must succeed");
let mut dst_space = dst_space_lock.write();
let mut dst_space = dst_space_lock.inner.write();
let free_span = dst_space
.grants
@@ -434,7 +434,7 @@ impl UserInner {
Ok(Grant::borrow(
Arc::clone(&cur_space_lock),
&mut *cur_space_lock.write(),
&mut *cur_space_lock.inner.write(),
first_middle_src_page,
dst_page,
middle_page_count.get(),
@@ -667,6 +667,7 @@ impl UserInner {
let context = context.upgrade().ok_or(Error::new(ESRCH))?;
let (frame, _) = AddrSpace::current()?
.inner
.read()
.table
.utable
@@ -736,7 +737,7 @@ impl UserInner {
fn fmap_inner(
&self,
dst_addr_space: Arc<RwLock<AddrSpace>>,
dst_addr_space: Arc<AddrSpaceWrapper>,
file: usize,
map: &Map,
) -> Result<usize> {
@@ -836,7 +837,7 @@ impl UserInner {
BorrowedFmapSource {
src_base: Page::containing_address(VirtualAddress::new(base_addr)),
addr_space_lock,
addr_space_guard: addr_space_lock.write(),
addr_space_guard: addr_space_lock.inner.write(),
mode: if map.flags.contains(MapFlags::MAP_SHARED) {
MmapMode::Shared
} else {
@@ -849,7 +850,7 @@ impl UserInner {
let page_count_nz = NonZeroUsize::new(page_count).expect("already validated map.size != 0");
let mut notify_files = Vec::new();
let dst_base = dst_addr_space.write().mmap(
let dst_base = dst_addr_space.inner.write().mmap(
dst_base,
page_count_nz,
map.flags,
@@ -878,7 +879,7 @@ pub struct CaptureGuard<const READ: bool, const WRITE: bool> {
base: usize,
len: usize,
space: Option<Arc<RwLock<AddrSpace>>>,
space: Option<Arc<AddrSpaceWrapper>>,
head: CopyInfo<READ, WRITE>,
tail: CopyInfo<READ, WRITE>,
@@ -935,6 +936,7 @@ impl<const READ: bool, const WRITE: bool> CaptureGuard<READ, WRITE> {
let unpin = true;
space
.inner
.write()
.munmap(PageSpan::new(first_page, page_count), unpin)?;
@@ -1160,7 +1162,7 @@ impl KernelScheme for UserScheme {
fn kfmap(
&self,
file: usize,
addr_space: &Arc<RwLock<AddrSpace>>,
addr_space: &Arc<AddrSpaceWrapper>,
map: &Map,
_consume: bool,
) -> Result<usize> {