From 2683314c387f285a0b908736578cd74103992222 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 6 Mar 2019 15:35:10 +0800 Subject: [PATCH] Allocate pages eagerly for Delay when forking. Implement sys_getsockname. --- crate/memory/src/memory_set/handler/delay.rs | 7 ++++- crate/memory/src/memory_set/handler/mod.rs | 6 +++- crate/memory/src/memory_set/mod.rs | 15 ++++++++-- kernel/src/process/structs.rs | 16 +++++++---- kernel/src/syscall/mod.rs | 3 ++ kernel/src/syscall/net.rs | 30 ++++++++++++++++++++ 6 files changed, 68 insertions(+), 9 deletions(-) diff --git a/crate/memory/src/memory_set/handler/delay.rs b/crate/memory/src/memory_set/handler/delay.rs index 1a424a7..e158f54 100644 --- a/crate/memory/src/memory_set/handler/delay.rs +++ b/crate/memory/src/memory_set/handler/delay.rs @@ -17,6 +17,11 @@ impl MemoryHandler for Delay { 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 Delay { pub fn new(flags: MemoryAttr, allocator: T) -> Self { Delay { flags, allocator } } -} \ No newline at end of file +} diff --git a/crate/memory/src/memory_set/handler/mod.rs b/crate/memory/src/memory_set/handler/mod.rs index 0a3c7ee..ff6951e 100644 --- a/crate/memory/src/memory_set/handler/mod.rs +++ b/crate/memory/src/memory_set/handler/mod.rs @@ -4,6 +4,10 @@ use super::*; pub trait MemoryHandler: Debug + 'static { fn box_clone(&self) -> Box; 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; \ No newline at end of file +pub use self::delay::Delay; diff --git a/crate/memory/src/memory_set/mod.rs b/crate/memory/src/memory_set/mod.rs index 007d63f..b4611fa 100644 --- a/crate/memory/src/memory_set/mod.rs +++ b/crate/memory/src/memory_set/mod.rs @@ -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 MemorySet { // 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 Clone for MemorySet { 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 { diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 9c5140d..94ca586 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -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 diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index aed192f..219a2fd 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -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 diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index ea3c21a..7453027 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -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::() { + 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::() as u32 }; + return Ok(0); + } else { + Err(SysError::EINVAL) + } +} \ No newline at end of file