Allocate pages eagerly for Delay when forking. Implement sys_getsockname.

master
Jiajie Chen 6 years ago
parent 3e6860ae8a
commit 2683314c38

@ -17,6 +17,11 @@ impl<T: FrameAllocator> MemoryHandler for Delay<T> {
entry.update();
}
fn map_eager(&self, pt: &mut PageTable, addr: VirtAddr) {
let target = self.allocator.alloc().expect("failed to alloc frame");
self.flags.apply(pt.map(addr, target));
}
fn unmap(&self, pt: &mut PageTable, addr: VirtAddr) {
let entry = pt.get_entry(addr).expect("failed to get entry");
if entry.present() {
@ -42,4 +47,4 @@ impl<T: FrameAllocator> Delay<T> {
pub fn new(flags: MemoryAttr, allocator: T) -> Self {
Delay { flags, allocator }
}
}
}

@ -4,6 +4,10 @@ use super::*;
pub trait MemoryHandler: Debug + 'static {
fn box_clone(&self) -> Box<MemoryHandler>;
fn map(&self, pt: &mut PageTable, addr: VirtAddr);
fn map_eager(&self, pt: &mut PageTable, addr: VirtAddr) {
// override this when pages are allocated lazily
self.map(pt, addr);
}
fn unmap(&self, pt: &mut PageTable, addr: VirtAddr);
fn page_fault_handler(&self, pt: &mut PageTable, addr: VirtAddr) -> bool;
}
@ -26,4 +30,4 @@ mod delay;
pub use self::linear::Linear;
pub use self::byframe::ByFrame;
pub use self::delay::Delay;
pub use self::delay::Delay;

@ -98,6 +98,16 @@ impl MemoryArea {
}
}
/*
** @brief map the memory area to the physice address in a page table eagerly
** @param pt: &mut T::Active the page table to use
** @retval none
*/
fn map_eager(&self, pt: &mut PageTable) {
for page in Page::range_of(self.start_addr, self.end_addr) {
self.handler.map_eager(pt, page.start_address());
}
}
/*
** @brief unmap the memory area from the physice address in a page table
** @param pt: &mut T::Active the page table to use
** @retval none
@ -240,7 +250,7 @@ impl<T: InactivePageTable> MemorySet<T> {
// try each area's end address as the start
core::iter::once(addr_hint)
.chain(self.areas.iter().map(|area| area.end_addr))
.map(|addr| (addr + PAGE_SIZE) & ! PAGE_SIZE) // round up a page
.map(|addr| (addr + PAGE_SIZE - 1) & !(PAGE_SIZE - 1)) // round up a page
.find(|&addr| self.test_free_area(addr, addr + len))
.expect("failed to find free area ???")
}
@ -347,8 +357,9 @@ impl<T: InactivePageTable> Clone for MemorySet<T> {
fn clone(&self) -> Self {
let mut page_table = T::new();
page_table.edit(|pt| {
// without CoW, we should allocate the pages eagerly
for area in self.areas.iter() {
area.map(pt);
area.map_eager(pt);
}
});
MemorySet {

@ -170,6 +170,8 @@ impl Thread {
info!("COME into fork!");
// Clone memory set, make a new page table
let memory_set = self.proc.lock().memory_set.clone();
let files = self.proc.lock().files.clone();
let cwd = self.proc.lock().cwd.clone();
info!("finish mmset clone in fork!");
// MMU: copy data to the new space
@ -185,13 +187,14 @@ impl Thread {
info!("temporary copy data!");
let kstack = KernelStack::new();
Box::new(Thread {
context: unsafe { Context::new_fork(tf, kstack.top(), memory_set.token()) },
kstack,
proc: Arc::new(Mutex::new(Process {
memory_set,
files: self.proc.lock().files.clone(),
cwd: self.proc.lock().cwd.clone(),
files,
cwd,
})),
})
}
@ -236,9 +239,12 @@ fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize, usize) {
let offset = ph.offset() as usize;
let file_size = ph.file_size() as usize;
let mem_size = ph.mem_size() as usize;
let mut name = "load";
if ph.get_type() == Ok(Type::Tls) {
virt_addr = USER_TLS_OFFSET;
name = "tls";
debug!("copying tls addr to {:X}", virt_addr);
}
#[cfg(target_arch = "aarch64")]
@ -251,7 +257,7 @@ fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize, usize) {
info!("area @ {:?}, size = {:#x}", target.as_ptr(), mem_size);
#[cfg(not(feature = "no_mmu"))]
let target = {
ms.push(virt_addr, virt_addr + mem_size, ByFrame::new(memory_attr_from(ph.flags()), GlobalFrameAlloc), "");
ms.push(virt_addr, virt_addr + mem_size, ByFrame::new(memory_attr_from(ph.flags()), GlobalFrameAlloc), &name);
unsafe { ::core::slice::from_raw_parts_mut(virt_addr as *mut u8, mem_size) }
};
// Copy data
@ -267,7 +273,7 @@ fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize, usize) {
if ph.get_type() == Ok(Type::Tls) {
virt_addr = USER_TMP_TLS_OFFSET;
tls = virt_addr + ph.mem_size() as usize;
debug!("tls addr {:X}", tls);
debug!("copying tls addr to {:X}", virt_addr);
// TODO: put this in a function
// Get target slice
@ -277,7 +283,7 @@ fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize, usize) {
info!("area @ {:?}, size = {:#x}", target.as_ptr(), mem_size);
#[cfg(not(feature = "no_mmu"))]
let target = {
ms.push(virt_addr, virt_addr + mem_size, ByFrame::new(memory_attr_from(ph.flags()).writable(), GlobalFrameAlloc), "");
ms.push(virt_addr, virt_addr + mem_size, ByFrame::new(memory_attr_from(ph.flags()).writable(), GlobalFrameAlloc), "tmptls");
unsafe { ::core::slice::from_raw_parts_mut(virt_addr as *mut u8, mem_size) }
};
// Copy data

@ -61,10 +61,13 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
// 048 => sys_shutdown(),
049 => sys_bind(args[0], args[1] as *const u8, args[2]),
050 => sys_listen(args[0], args[1]),
051 => sys_getsockname(args[0], args[1] as *mut u8, args[2] as *mut u32),
054 => sys_setsockopt(args[0], args[1], args[2], args[3] as *const u8, args[4]),
// 055 => sys_getsockopt(),
// 056 => sys_clone(),
057 => sys_fork(tf),
// use fork for vfork
058 => sys_fork(tf),
059 => sys_exec(args[0] as *const u8, args[1] as usize, args[2] as *const *const u8, tf),
060 => sys_exit(args[0] as isize),
061 => sys_wait(args[0], args[1] as *mut i32), // TODO: wait4

@ -640,3 +640,33 @@ pub fn sys_accept(fd: usize, addr: *mut u8, addr_len: *mut u32) -> SysResult {
Err(SysError::EINVAL)
}
}
pub fn sys_getsockname(fd: usize, addr: *mut u8, addr_len: *mut u32) -> SysResult {
// smoltcp tcp sockets do not support backlog
// open multiple sockets for each connection
let mut proc = process();
if addr as usize == 0 {
return Err(SysError::EINVAL);
}
proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() {
return Err(SysError::EINVAL);
}
proc.memory_set.check_mut_array(addr, max_addr_len)?;
let iface = &mut *(NET_DRIVERS.lock()[0]);
let wrapper = proc.get_socket_mut(fd)?;
if let SocketType::Tcp(Some(endpoint)) = wrapper.socket_type {
let mut sockaddr_in = unsafe { &mut *(addr as *mut SockaddrIn) };
fill_addr(&mut sockaddr_in, endpoint.addr, endpoint.port);
unsafe { *addr_len = size_of::<SockaddrIn>() as u32 };
return Ok(0);
} else {
Err(SysError::EINVAL)
}
}
Loading…
Cancel
Save