From 54de0d8ae7e7764f7f9210e3fe78556fca561589 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 1 May 2019 00:18:11 +0800 Subject: [PATCH 1/9] remove once crate. fix bitvec crate commit id. --- kernel/Cargo.lock | 9 +-------- kernel/Cargo.toml | 1 - kernel/src/arch/aarch64/board/raspi3/mod.rs | 4 ---- kernel/src/arch/aarch64/board/raspi3/serial.rs | 3 --- kernel/src/arch/aarch64/driver/mod.rs | 3 --- kernel/src/arch/mipsel/board/malta/mod.rs | 2 -- kernel/src/arch/mipsel/board/mipssim/mod.rs | 2 -- kernel/src/arch/mipsel/board/thinpad/mod.rs | 2 -- kernel/src/arch/mipsel/driver/mod.rs | 2 -- kernel/src/arch/x86_64/driver/mod.rs | 4 ---- kernel/src/arch/x86_64/driver/pic.rs | 3 --- kernel/src/arch/x86_64/driver/pit.rs | 2 -- kernel/src/arch/x86_64/driver/serial.rs | 3 --- kernel/src/arch/x86_64/memory.rs | 2 -- kernel/src/drivers/gpu/fb.rs | 3 --- 15 files changed, 1 insertion(+), 44 deletions(-) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 24ac173..f9d9c2b 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -85,7 +85,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitvec" version = "0.11.0" -source = "git+https://github.com/myrrlyn/bitvec.git#ed2aec38bfb5b1116e3585b1574c50655b9c85ec" +source = "git+https://github.com/myrrlyn/bitvec.git#8ab20a3e33fe068fc3a4a05eda1211d5fcc1237b" [[package]] name = "bootloader" @@ -248,11 +248,6 @@ name = "nodrop" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "once" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "os_bootinfo" version = "0.2.1" @@ -381,7 +376,6 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mips 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "pc-keyboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "pci 0.0.1 (git+https://github.com/rcore-os/pci-rs)", @@ -689,7 +683,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6" "checksum mips 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4cbf449a63e4db77af9f662d6b42068c0925e779a3a7c70ad02f191cf1e6c802" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "931fb7a4cf34610cf6cbe58d52a8ca5ef4c726d4e2e178abd0dc13a6551c6d73" "checksum os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "66481dbeb5e773e7bd85b63cd6042c30786f834338288c5ec4f3742673db360a" "checksum paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4a4a1c555c6505821f9d58b8779d0f630a6b7e4e1be24ba718610acf01fa79" "checksum paste-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "26e796e623b8b257215f27e6c80a5478856cae305f5b59810ff9acdaa34570e6" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 32855b1..2483a42 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -50,7 +50,6 @@ opt-level = 2 [dependencies] log = "0.4" spin = "0.5" -once = "0.3" xmas-elf = "0.6" bitflags = "1.0" bit_field = "0.9" diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs index 1cc6696..0480e35 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mod.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -2,7 +2,6 @@ use alloc::string::String; use bcm2837::atags::Atags; -use once::*; #[path = "../../../../drivers/gpu/fb.rs"] pub mod fb; @@ -18,10 +17,7 @@ pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000; /// Initialize serial port before other initializations. pub fn init_serial_early() { - assert_has_not_been_called!("board::init must be called only once"); - serial::init(); - println!("Hello Raspberry Pi!"); } diff --git a/kernel/src/arch/aarch64/board/raspi3/serial.rs b/kernel/src/arch/aarch64/board/raspi3/serial.rs index b7796d3..b2a1577 100644 --- a/kernel/src/arch/aarch64/board/raspi3/serial.rs +++ b/kernel/src/arch/aarch64/board/raspi3/serial.rs @@ -1,7 +1,6 @@ use bcm2837::mini_uart::{MiniUart, MiniUartInterruptId}; use core::fmt; use lazy_static::lazy_static; -use once::*; use spin::Mutex; /// Struct to get a global SerialPort interface @@ -23,8 +22,6 @@ impl SerialPort { /// Init a newly created SerialPort, can only be called once. fn init(&mut self) { - assert_has_not_been_called!("SerialPort::init must be called only once"); - self.mu.init(); super::irq::register_irq(super::irq::Interrupt::Aux, handle_serial_irq); } diff --git a/kernel/src/arch/aarch64/driver/mod.rs b/kernel/src/arch/aarch64/driver/mod.rs index a100c2b..d80ab0c 100644 --- a/kernel/src/arch/aarch64/driver/mod.rs +++ b/kernel/src/arch/aarch64/driver/mod.rs @@ -1,7 +1,6 @@ //! ARM64 drivers use super::board; -use once::*; pub use self::board::fb; pub use self::board::serial; @@ -10,8 +9,6 @@ pub mod console; /// Initialize ARM64 common drivers pub fn init() { - assert_has_not_been_called!("driver::init must be called only once"); - board::init_driver(); console::init(); } diff --git a/kernel/src/arch/mipsel/board/malta/mod.rs b/kernel/src/arch/mipsel/board/malta/mod.rs index 0fbaa33..7b54808 100644 --- a/kernel/src/arch/mipsel/board/malta/mod.rs +++ b/kernel/src/arch/mipsel/board/malta/mod.rs @@ -1,7 +1,6 @@ use crate::drivers::bus::pci; use alloc::string::String; use mips::registers::cp0; -use once::*; #[path = "../../../../drivers/console/mod.rs"] pub mod console; @@ -17,7 +16,6 @@ use fb::FramebufferInfo; /// Initialize serial port first pub fn init_serial_early() { - assert_has_not_been_called!("board::init must be called only once"); // initialize serial driver serial::init(0xbf000900); // Enable serial interrupt diff --git a/kernel/src/arch/mipsel/board/mipssim/mod.rs b/kernel/src/arch/mipsel/board/mipssim/mod.rs index 97eb465..be68708 100644 --- a/kernel/src/arch/mipsel/board/mipssim/mod.rs +++ b/kernel/src/arch/mipsel/board/mipssim/mod.rs @@ -1,5 +1,4 @@ use alloc::string::String; -use once::*; #[path = "../../../../drivers/console/mod.rs"] pub mod console; @@ -11,7 +10,6 @@ pub mod serial; /// Initialize serial port first pub fn init_serial_early() { - assert_has_not_been_called!("board::init must be called only once"); serial::init(0xbfd003f8); println!("Hello QEMU MIPSSIM!"); } diff --git a/kernel/src/arch/mipsel/board/thinpad/mod.rs b/kernel/src/arch/mipsel/board/thinpad/mod.rs index dae1f92..2afb19f 100644 --- a/kernel/src/arch/mipsel/board/thinpad/mod.rs +++ b/kernel/src/arch/mipsel/board/thinpad/mod.rs @@ -1,5 +1,4 @@ use alloc::string::String; -use once::*; #[path = "../../../../drivers/console/mod.rs"] pub mod console; @@ -14,7 +13,6 @@ use fb::FramebufferResult; /// Initialize serial port first pub fn init_serial_early() { - assert_has_not_been_called!("board::init must be called only once"); serial::init(0xa3000000); println!("Hello ThinPad!"); } diff --git a/kernel/src/arch/mipsel/driver/mod.rs b/kernel/src/arch/mipsel/driver/mod.rs index 0cf6ad0..7fb6fd0 100644 --- a/kernel/src/arch/mipsel/driver/mod.rs +++ b/kernel/src/arch/mipsel/driver/mod.rs @@ -1,7 +1,6 @@ //! mipsel drivers use super::board; -use once::*; pub use self::board::fb; pub use self::board::serial; @@ -10,7 +9,6 @@ pub mod console; /// Initialize common drivers pub fn init() { - assert_has_not_been_called!("driver::init must be called only once"); board::init_driver(); console::init(); } diff --git a/kernel/src/arch/x86_64/driver/mod.rs b/kernel/src/arch/x86_64/driver/mod.rs index 02158ed..cbc4d67 100644 --- a/kernel/src/arch/x86_64/driver/mod.rs +++ b/kernel/src/arch/x86_64/driver/mod.rs @@ -1,5 +1,3 @@ -use once::*; - pub mod ide; pub mod keyboard; pub mod pic; @@ -9,8 +7,6 @@ pub mod serial; pub mod vga; pub fn init() { - assert_has_not_been_called!(); - // Use IOAPIC instead of PIC pic::disable(); diff --git a/kernel/src/arch/x86_64/driver/pic.rs b/kernel/src/arch/x86_64/driver/pic.rs index 7a67a3c..d35ca5c 100644 --- a/kernel/src/arch/x86_64/driver/pic.rs +++ b/kernel/src/arch/x86_64/driver/pic.rs @@ -1,7 +1,6 @@ // Copy from Redox use log::*; -use once::*; use spin::Mutex; use x86_64::instructions::port::Port; @@ -18,8 +17,6 @@ pub fn disable() { } pub unsafe fn init() { - assert_has_not_been_called!("pic::init must be called only once"); - let mut master = MASTER.lock(); let mut slave = SLAVE.lock(); diff --git a/kernel/src/arch/x86_64/driver/pit.rs b/kernel/src/arch/x86_64/driver/pit.rs index 655ce8a..2b88280 100644 --- a/kernel/src/arch/x86_64/driver/pit.rs +++ b/kernel/src/arch/x86_64/driver/pit.rs @@ -1,9 +1,7 @@ use log::*; -use once::*; use x86_64::instructions::port::Port; pub fn init() { - assert_has_not_been_called!("pit::init must be called only once"); Pit::new(0x40).init(100); info!("pit: init end"); } diff --git a/kernel/src/arch/x86_64/driver/serial.rs b/kernel/src/arch/x86_64/driver/serial.rs index 68655e2..8242fdb 100644 --- a/kernel/src/arch/x86_64/driver/serial.rs +++ b/kernel/src/arch/x86_64/driver/serial.rs @@ -1,4 +1,3 @@ -use once::*; use spin::Mutex; use uart_16550::SerialPort; use x86_64::instructions::port::Port; @@ -9,8 +8,6 @@ pub static COM1: Mutex = Mutex::new(unsafe { SerialPort::new(0x3F8) pub static COM2: Mutex = Mutex::new(unsafe { SerialPort::new(0x2F8) }); pub fn init() { - assert_has_not_been_called!("serial::init must be called only once"); - COM1.lock().init(); COM2.lock().init(); enable_irq(consts::COM1); diff --git a/kernel/src/arch/x86_64/memory.rs b/kernel/src/arch/x86_64/memory.rs index 092dc9e..c5afb85 100644 --- a/kernel/src/arch/x86_64/memory.rs +++ b/kernel/src/arch/x86_64/memory.rs @@ -4,12 +4,10 @@ use bitmap_allocator::BitAlloc; use super::{BootInfo, MemoryRegionType}; use crate::memory::{active_table, init_heap, FRAME_ALLOCATOR}; use log::*; -use once::*; use rcore_memory::paging::*; use rcore_memory::PAGE_SIZE; pub fn init(boot_info: &BootInfo) { - assert_has_not_been_called!("memory::init must be called only once"); init_frame_allocator(boot_info); init_device_vm_map(); init_heap(); diff --git a/kernel/src/drivers/gpu/fb.rs b/kernel/src/drivers/gpu/fb.rs index 54d7e10..01fbe6a 100644 --- a/kernel/src/drivers/gpu/fb.rs +++ b/kernel/src/drivers/gpu/fb.rs @@ -4,7 +4,6 @@ use alloc::string::String; use core::fmt; use lazy_static::lazy_static; use log::*; -use once::*; use spin::Mutex; /// Framebuffer information @@ -134,8 +133,6 @@ impl fmt::Debug for Framebuffer { impl Framebuffer { fn new(width: u32, height: u32, depth: u32) -> Result { - assert_has_not_been_called!("Framebuffer::new must be called only once"); - let probed_info = super::probe_fb_info(width, height, depth); match probed_info { From 8651f09b31f54a22a78a995a9758001a5e021e02 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 1 May 2019 18:33:55 +0800 Subject: [PATCH 2/9] Automatically enlarge heap when kernel heap is about to run out --- crate/memory/src/memory_set/handler/mod.rs | 4 +-- kernel/Cargo.lock | 6 ++-- kernel/Cargo.toml | 2 +- kernel/src/fs/mod.rs | 4 +-- kernel/src/fs/pseudo.rs | 2 +- kernel/src/lib.rs | 5 +-- kernel/src/memory.rs | 38 +++++++++++++++++++--- kernel/src/syscall/mod.rs | 10 ++---- user | 2 +- 9 files changed, 50 insertions(+), 23 deletions(-) diff --git a/crate/memory/src/memory_set/handler/mod.rs b/crate/memory/src/memory_set/handler/mod.rs index 6154e96..9a17732 100644 --- a/crate/memory/src/memory_set/handler/mod.rs +++ b/crate/memory/src/memory_set/handler/mod.rs @@ -41,11 +41,11 @@ pub trait FrameAllocator: Debug + Clone + Send + Sync + 'static { mod byframe; mod delay; -mod linear; mod file; +mod linear; //mod swap; pub use self::byframe::ByFrame; pub use self::delay::Delay; -pub use self::linear::Linear; pub use self::file::{File, Read}; +pub use self::linear::Linear; diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index f9d9c2b..c1dd7a0 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "buddy_system_allocator" -version = "0.1.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -367,7 +367,7 @@ dependencies = [ "bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator)", "bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)", "bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)", - "buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "buddy_system_allocator 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", "console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "device_tree 1.0.3 (git+https://github.com/rcore-os/device_tree-rs)", @@ -661,7 +661,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)" = "" "checksum bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfadef5c4e2c2e64067b9ecc061179f12ac7ec65ba613b1f60f3972bbada1f5b" "checksum bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)" = "" -"checksum buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2ed828f1e227d6e32b998d6375b67fd63ac5389d50b23f258ce151d22b6cc595" +"checksum buddy_system_allocator 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "94a6c0143a07fea0db2f4b43cb9540dcc7c17af8a7beafdf2184e5e4e35aae91" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 2483a42..8ef38d7 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -57,7 +57,7 @@ volatile = "0.2" heapless = "0.4" bitvec = { git = "https://github.com/myrrlyn/bitvec.git", default-features = false, features = ["alloc"] } console-traits = "0.3" -buddy_system_allocator = "0.1" +buddy_system_allocator = "0.3" pci = { git = "https://github.com/rcore-os/pci-rs" } device_tree = { git = "https://github.com/rcore-os/device_tree-rs" } isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers" } diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 256ce5e..419e3eb 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -9,15 +9,15 @@ use crate::arch::driver::ide; pub use self::file::*; pub use self::file_like::*; pub use self::pipe::Pipe; -pub use self::stdio::{STDIN, STDOUT}; pub use self::pseudo::*; +pub use self::stdio::{STDIN, STDOUT}; mod device; mod file; mod file_like; mod pipe; -mod stdio; mod pseudo; +mod stdio; /// Hard link user programs #[cfg(feature = "link_user")] diff --git a/kernel/src/fs/pseudo.rs b/kernel/src/fs/pseudo.rs index 6da58c0..fdcc535 100644 --- a/kernel/src/fs/pseudo.rs +++ b/kernel/src/fs/pseudo.rs @@ -14,7 +14,7 @@ impl Pseudo { pub fn new(s: &str, type_: FileType) -> Self { Pseudo { content: Vec::from(s.as_bytes()), - type_ + type_, } } } diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index fa5f0a6..b6c482c 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -18,7 +18,7 @@ extern crate log; extern crate lazy_static; pub use crate::process::{new_kernel_context, processor}; -use buddy_system_allocator::LockedHeap; +use buddy_system_allocator::LockedHeapWithRescue; use rcore_thread::std_thread as thread; #[macro_use] // print! @@ -65,4 +65,5 @@ pub fn kmain() -> ! { /// /// It should be defined in memory mod, but in Rust `global_allocator` must be in root mod. #[global_allocator] -static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); +static HEAP_ALLOCATOR: LockedHeapWithRescue = + LockedHeapWithRescue::new(crate::memory::enlarge_heap); diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 8367cbc..f34354f 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -14,14 +14,17 @@ use super::HEAP_ALLOCATOR; pub use crate::arch::paging::*; -use crate::consts::MEMORY_OFFSET; +use crate::consts::{KERNEL_OFFSET, MEMORY_OFFSET}; use crate::process::process_unsafe; use crate::sync::SpinNoIrqLock; +use alloc::boxed::Box; +use alloc::vec::Vec; use bitmap_allocator::BitAlloc; -use buddy_system_allocator::LockedHeap; +use buddy_system_allocator::{Heap, LockedHeap}; use lazy_static::*; use log::*; pub use rcore_memory::memory_set::{handler::*, MemoryArea, MemoryAttr}; +use rcore_memory::paging::PageTable; use rcore_memory::*; pub type MemorySet = rcore_memory::memory_set::MemorySet; @@ -145,5 +148,32 @@ pub fn init_heap() { info!("heap init end"); } -/// Allocator for the rest memory space on NO-MMU case. -pub static MEMORY_ALLOCATOR: LockedHeap = LockedHeap::empty(); +pub fn enlarge_heap(heap: &mut Heap) { + let mut page_table = active_table(); + let mut addrs = [(0, 0); 32]; + let mut addr_len = 0; + let va_offset = KERNEL_OFFSET + 0xe0000000; + for i in 0..16384 { + let page = alloc_frame().unwrap(); + let va = KERNEL_OFFSET + 0xe0000000 + page; + if addr_len > 0 { + let (ref mut addr, ref mut len) = addrs[addr_len-1]; + if *addr - PAGE_SIZE == va { + *len += PAGE_SIZE; + *addr -= PAGE_SIZE; + continue; + } + } + addrs[addr_len] = (va, PAGE_SIZE); + addr_len += 1; + } + for (addr, len) in addrs[..addr_len].into_iter() { + for va in (*addr..(*addr + *len)).step_by(PAGE_SIZE) { + page_table.map(va, va - va_offset).update(); + } + info!("Adding {:#X} {:#X} to heap", addr, len); + unsafe { + heap.init(*addr, *len); + } + } +} diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 066d0a6..3f183d8 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -31,8 +31,8 @@ mod net; mod proc; mod time; -use spin::Mutex; use alloc::collections::BTreeMap; +use spin::Mutex; #[cfg(feature = "profile")] lazy_static! { @@ -45,9 +45,7 @@ lazy_static! { #[deny(unreachable_patterns)] pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { #[cfg(feature = "profile")] - let begin_time = unsafe { - core::arch::x86_64::_rdtsc() - }; + let begin_time = unsafe { core::arch::x86_64::_rdtsc() }; let cid = cpu::id(); let pid = process().pid.clone(); let tid = processor().tid(); @@ -268,9 +266,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { } #[cfg(feature = "profile")] { - let end_time = unsafe { - core::arch::x86_64::_rdtsc() - }; + let end_time = unsafe { core::arch::x86_64::_rdtsc() }; *SYSCALL_TIMING.lock().entry(id).or_insert(0) += end_time - begin_time; if end_time % 1000 == 0 { let timing = SYSCALL_TIMING.lock(); diff --git a/user b/user index 05f0efd..aec8667 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit 05f0efd3fda084109e4b6da8ff30ecb1557a267f +Subproject commit aec8667eb056cb564e301d6c0937da1e4500a4d3 From 6c988c4bfdb84664d7dbe813b4fedf726f8aed0e Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 1 May 2019 23:36:39 +0800 Subject: [PATCH 3/9] note potential lost wakeup problem in Condvar. fix some use case. --- kernel/src/fs/stdio.rs | 8 +++++--- kernel/src/net/structs.rs | 14 ++++---------- kernel/src/sync/condvar.rs | 15 +++++++++------ kernel/src/syscall/misc.rs | 1 + kernel/src/syscall/proc.rs | 3 +-- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index 3967e41..e373a1d 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -30,10 +30,12 @@ impl Stdin { } #[cfg(not(feature = "board_k210"))] loop { - let ret = self.buf.lock().pop_front(); - match ret { + let mut buf_lock = self.buf.lock(); + match buf_lock.pop_front() { Some(c) => return c, - None => self.pushed._wait(), + None => { + self.pushed.wait(buf_lock); + } } } } diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index b905fde..4dc9435 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -265,9 +265,8 @@ impl Socket for TcpSocketState { TcpState::SynSent => { // still connecting drop(socket); - drop(sockets); debug!("poll for connection wait"); - SOCKET_ACTIVITY._wait(); + SOCKET_ACTIVITY.wait(sockets); } TcpState::Established => { break Ok(0); @@ -357,10 +356,8 @@ impl Socket for TcpSocketState { return Ok((new_socket, Endpoint::Ip(remote_endpoint))); } - // avoid deadlock drop(socket); - drop(sockets); - SOCKET_ACTIVITY._wait(); + SOCKET_ACTIVITY.wait(sockets); } } @@ -447,9 +444,8 @@ impl Socket for UdpSocketState { ); } - // avoid deadlock drop(socket); - SOCKET_ACTIVITY._wait() + SOCKET_ACTIVITY.wait(sockets); } } @@ -626,10 +622,8 @@ impl Socket for RawSocketState { ); } - // avoid deadlock drop(socket); - drop(sockets); - SOCKET_ACTIVITY._wait() + SOCKET_ACTIVITY.wait(sockets); } } diff --git a/kernel/src/sync/condvar.rs b/kernel/src/sync/condvar.rs index a03f107..61db073 100644 --- a/kernel/src/sync/condvar.rs +++ b/kernel/src/sync/condvar.rs @@ -15,6 +15,7 @@ impl Condvar { } /// Park current thread and wait for this condvar to be notified. + #[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")] pub fn _wait(&self) { // The condvar might be notified between adding to queue and thread parking. // So park current thread before wait queue lock is freed. @@ -25,6 +26,7 @@ impl Condvar { }); } + #[deprecated(note = "this may leads to lost wakeup problem. please use `wait` instead.")] pub fn wait_any(condvars: &[&Condvar]) { let token = Arc::new(thread::current()); // Avoid racing in the same way as the function above @@ -40,19 +42,23 @@ impl Condvar { }); } - pub fn add_to_wait_queue(&self) -> MutexGuard>, SpinNoIrq> { + fn add_to_wait_queue(&self) -> MutexGuard>, SpinNoIrq> { let mut lock = self.wait_queue.lock(); lock.push_back(Arc::new(thread::current())); return lock; } + /// Park current thread and wait for this condvar to be notified. pub fn wait<'a, T, S>(&self, guard: MutexGuard<'a, T, S>) -> MutexGuard<'a, T, S> where S: MutexSupport, { let mutex = guard.mutex; - drop(guard); - self._wait(); + let lock = self.add_to_wait_queue(); + thread::park_action(move || { + drop(lock); + drop(guard); + }); mutex.lock() } @@ -80,7 +86,4 @@ impl Condvar { } count } - pub fn _clear(&self) { - self.wait_queue.lock().clear(); - } } diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index e7f867c..54c7925 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -91,6 +91,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S return Err(SysError::EAGAIN); } // FIXME: support timeout + // FIXME: fix racing queue._wait(); Ok(0) } diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 9fcb97e..b24c960 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -120,8 +120,7 @@ pub fn sys_wait4(pid: isize, wstatus: *mut i32) -> SysResult { target ); let condvar = proc.child_exit.clone(); - drop(proc); // must release lock of current process - condvar._wait(); + condvar.wait(proc); } } From 81fde731d097e4158fc497ac854be7881a07b45b Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 2 May 2019 15:07:06 +0800 Subject: [PATCH 4/9] Save and log file paths on sys_open and sys_close --- kernel/src/fs/file.rs | 46 ++++++++++++++++++++++++++++++++++++-- kernel/src/fs/file_like.rs | 2 +- kernel/src/memory.rs | 2 +- kernel/src/syscall/fs.rs | 15 ++++++++++++- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 3979c4d..d41c5a5 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -1,6 +1,7 @@ //! File handle for process use alloc::{string::String, sync::Arc}; +use core::fmt; use rcore_fs::vfs::{FsError, INode, Metadata, PollStatus, Result}; @@ -9,6 +10,10 @@ pub struct FileHandle { inode: Arc, offset: u64, options: OpenOptions, + + // for debugging + #[cfg(debug_assertions)] + path: String, } #[derive(Debug, Clone)] @@ -28,11 +33,29 @@ pub enum SeekFrom { impl FileHandle { pub fn new(inode: Arc, options: OpenOptions) -> Self { - FileHandle { + #[cfg(debug_assertions)] + return FileHandle { inode, offset: 0, options, - } + path: String::from("unknown"), + }; + #[cfg(not(debug_assertions))] + return FileHandle { + inode, + offset: 0, + options, + }; + } + + #[cfg(debug_assertions)] + pub fn set_path(&mut self, path: &str) { + self.path = String::from(path); + } + + #[cfg(not(debug_assertions))] + pub fn set_path(&mut self, _path: &str) { + unreachable!() } pub fn read(&mut self, buf: &mut [u8]) -> Result { @@ -121,3 +144,22 @@ impl FileHandle { self.inode.clone() } } + +impl fmt::Debug for FileHandle { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // for debugging + #[cfg(debug_assertions)] + return f + .debug_struct("FileHandle") + .field("offset", &self.offset) + .field("options", &self.options) + .field("path", &self.path) + .finish(); + #[cfg(not(debug_assertions))] + return f + .debug_struct("FileHandle") + .field("offset", &self.offset) + .field("options", &self.options) + .finish(); + } +} diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index 32c5cdc..c8730eb 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -53,7 +53,7 @@ impl FileLike { impl fmt::Debug for FileLike { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - FileLike::File(_) => write!(f, "File"), + FileLike::File(file) => write!(f, "File {:?}", file), FileLike::Socket(_) => write!(f, "Socket"), } } diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index f34354f..6ee97b9 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -157,7 +157,7 @@ pub fn enlarge_heap(heap: &mut Heap) { let page = alloc_frame().unwrap(); let va = KERNEL_OFFSET + 0xe0000000 + page; if addr_len > 0 { - let (ref mut addr, ref mut len) = addrs[addr_len-1]; + let (ref mut addr, ref mut len) = addrs[addr_len - 1]; if *addr - PAGE_SIZE == va { *len += PAGE_SIZE; *addr -= PAGE_SIZE; diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index efa0852..de38f95 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -273,7 +273,14 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> proc.lookup_inode_at(dir_fd, &path, true)? }; - let file = FileHandle::new(inode, flags.to_options()); + let mut file = FileHandle::new(inode, flags.to_options()); + + // for debugging + if cfg!(debug_assertions) { + file.set_path(&path); + debug!("files before open {:#?}", proc.files); + } + let fd = proc.add_file(FileLike::File(file)); Ok(fd) } @@ -281,6 +288,12 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> pub fn sys_close(fd: usize) -> SysResult { info!("close: fd: {:?}", fd); let mut proc = process(); + + // for debugging + if cfg!(debug_assertions) { + debug!("files before close {:#?}", proc.files); + } + proc.files.remove(&fd).ok_or(SysError::EBADF)?; Ok(0) } From ad2f02388cf84e9cdfef8cdee535d0cba8741b47 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 2 May 2019 15:18:41 +0800 Subject: [PATCH 5/9] Fix compilation on mipsel --- kernel/src/drivers/bus/pci.rs | 1 - kernel/src/fs/file_like.rs | 4 ++-- kernel/src/fs/mod.rs | 3 --- kernel/src/memory.rs | 10 +++++++--- kernel/src/process/structs.rs | 2 +- kernel/src/shell.rs | 4 ++-- kernel/src/syscall/mem.rs | 2 +- kernel/src/syscall/net.rs | 1 - 8 files changed, 13 insertions(+), 14 deletions(-) diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index 2744b2b..b2c86e7 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -5,7 +5,6 @@ use crate::drivers::{Driver, DRIVERS, NET_DRIVERS}; use crate::memory::active_table; use alloc::collections::BTreeMap; use alloc::sync::Arc; -use core::cmp::Ordering; use pci::*; use rcore_memory::{paging::PageTable, PAGE_SIZE}; use spin::Mutex; diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index c8730eb..5f7ebc4 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -53,8 +53,8 @@ impl FileLike { impl fmt::Debug for FileLike { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - FileLike::File(file) => write!(f, "File {:?}", file), - FileLike::Socket(_) => write!(f, "Socket"), + FileLike::File(file) => write!(f, "File({:?})", file), + FileLike::Socket(_) => write!(f, "Socket(..)"), } } } diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 419e3eb..7217ae3 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -3,9 +3,6 @@ use alloc::{sync::Arc, vec::Vec}; use rcore_fs::vfs::*; use rcore_fs_sfs::SimpleFileSystem; -#[cfg(target_arch = "x86_64")] -use crate::arch::driver::ide; - pub use self::file::*; pub use self::file_like::*; pub use self::pipe::Pipe; diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 6ee97b9..b3b013a 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -18,9 +18,8 @@ use crate::consts::{KERNEL_OFFSET, MEMORY_OFFSET}; use crate::process::process_unsafe; use crate::sync::SpinNoIrqLock; use alloc::boxed::Box; -use alloc::vec::Vec; use bitmap_allocator::BitAlloc; -use buddy_system_allocator::{Heap, LockedHeap}; +use buddy_system_allocator::Heap; use lazy_static::*; use log::*; pub use rcore_memory::memory_set::{handler::*, MemoryArea, MemoryAttr}; @@ -149,13 +148,18 @@ pub fn init_heap() { } pub fn enlarge_heap(heap: &mut Heap) { + info!("Enlarging heap to avoid oom"); + let mut page_table = active_table(); let mut addrs = [(0, 0); 32]; let mut addr_len = 0; + #[cfg(target_arch = "x86_64")] let va_offset = KERNEL_OFFSET + 0xe0000000; + #[cfg(not(target_arch = "x86_64"))] + let va_offset = KERNEL_OFFSET + 0x00e00000; for i in 0..16384 { let page = alloc_frame().unwrap(); - let va = KERNEL_OFFSET + 0xe0000000 + page; + let va = va_offset + page; if addr_len > 0 { let (ref mut addr, ref mut len) = addrs[addr_len - 1]; if *addr - PAGE_SIZE == va { diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 2ec8dcf..bea6a9e 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -13,7 +13,7 @@ use xmas_elf::{ }; use crate::arch::interrupt::{Context, TrapFrame}; -use crate::fs::{FileHandle, FileLike, INodeExt, OpenOptions, FOLLOW_MAX_DEPTH}; +use crate::fs::{FileHandle, FileLike, OpenOptions, FOLLOW_MAX_DEPTH}; use crate::memory::{ ByFrame, Delay, File, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet, Read, }; diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index 84c4367..7e8822b 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -1,7 +1,6 @@ //! Kernel shell -use crate::drivers::CMDLINE; -use crate::fs::{INodeExt, ROOT_INODE}; +use crate::fs::ROOT_INODE; use crate::process::*; use alloc::string::String; use alloc::vec::Vec; @@ -40,6 +39,7 @@ pub fn add_user_shell() { #[cfg(feature = "run_cmdline")] pub fn add_user_shell() { + use crate::drivers::CMDLINE; let cmdline = CMDLINE.read(); let inode = ROOT_INODE.lookup(&cmdline).unwrap(); processor().manager().add(Thread::new_user( diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index d108a7c..1a241ac 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -1,4 +1,4 @@ -use rcore_memory::memory_set::handler::{ByFrame, Delay, File}; +use rcore_memory::memory_set::handler::{Delay, File}; use rcore_memory::memory_set::MemoryAttr; use rcore_memory::paging::PageTable; use rcore_memory::Page; diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index af28065..e7c3318 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -2,7 +2,6 @@ use super::fs::IoVecs; use super::*; -use crate::drivers::SOCKET_ACTIVITY; use crate::fs::FileLike; use crate::net::{ Endpoint, LinkLevelEndpoint, NetlinkEndpoint, NetlinkSocketState, PacketSocketState, From 64b383b69c4d6e9514ec4cf135dda14c657cc905 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 2 May 2019 15:47:10 +0800 Subject: [PATCH 6/9] Save path even in release mode --- kernel/src/fs/file.rs | 32 ++------------------------------ kernel/src/fs/file_like.rs | 2 +- kernel/src/net/structs.rs | 3 ++- kernel/src/process/structs.rs | 3 +++ kernel/src/syscall/fs.rs | 10 ++++++++-- 5 files changed, 16 insertions(+), 34 deletions(-) diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index d41c5a5..9fd8119 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -10,9 +10,6 @@ pub struct FileHandle { inode: Arc, offset: u64, options: OpenOptions, - - // for debugging - #[cfg(debug_assertions)] path: String, } @@ -32,32 +29,15 @@ pub enum SeekFrom { } impl FileHandle { - pub fn new(inode: Arc, options: OpenOptions) -> Self { - #[cfg(debug_assertions)] - return FileHandle { - inode, - offset: 0, - options, - path: String::from("unknown"), - }; - #[cfg(not(debug_assertions))] + pub fn new(inode: Arc, options: OpenOptions, path: String) -> Self { return FileHandle { inode, offset: 0, options, + path, }; } - #[cfg(debug_assertions)] - pub fn set_path(&mut self, path: &str) { - self.path = String::from(path); - } - - #[cfg(not(debug_assertions))] - pub fn set_path(&mut self, _path: &str) { - unreachable!() - } - pub fn read(&mut self, buf: &mut [u8]) -> Result { let len = self.read_at(self.offset as usize, buf)?; self.offset += len as u64; @@ -147,19 +127,11 @@ impl FileHandle { impl fmt::Debug for FileHandle { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // for debugging - #[cfg(debug_assertions)] return f .debug_struct("FileHandle") .field("offset", &self.offset) .field("options", &self.options) .field("path", &self.path) .finish(); - #[cfg(not(debug_assertions))] - return f - .debug_struct("FileHandle") - .field("offset", &self.offset) - .field("options", &self.options) - .finish(); } } diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index 5f7ebc4..9c4913f 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -54,7 +54,7 @@ impl fmt::Debug for FileLike { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { FileLike::File(file) => write!(f, "File({:?})", file), - FileLike::Socket(_) => write!(f, "Socket(..)"), + FileLike::Socket(socket) => write!(f, "Socket({:?})", socket), } } } diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index 4dc9435..1892fc3 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -4,6 +4,7 @@ use crate::sync::SpinNoIrqLock as Mutex; use crate::syscall::*; use crate::util; use alloc::boxed::Box; +use alloc::fmt::Debug; use alloc::sync::Arc; use alloc::vec::Vec; use bitflags::*; @@ -50,7 +51,7 @@ pub enum Endpoint { } /// Common methods that a socket must have -pub trait Socket: Send + Sync { +pub trait Socket: Send + Sync + Debug { fn read(&self, data: &mut [u8]) -> (SysResult, Endpoint); fn write(&self, data: &[u8], sendto_endpoint: Option) -> SysResult; fn poll(&self) -> (bool, bool, bool); // (in, out, err) diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index bea6a9e..d5942ba 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -255,6 +255,7 @@ impl Thread { write: false, append: false, }, + String::from("stdin"), )), ); files.insert( @@ -266,6 +267,7 @@ impl Thread { write: true, append: false, }, + String::from("stdout"), )), ); files.insert( @@ -277,6 +279,7 @@ impl Thread { write: true, append: false, }, + String::from("stderr"), )), ); diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index de38f95..56d14ae 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -156,6 +156,11 @@ pub fn sys_select( // infinity 1 << 31 }; + + // for debugging + if cfg!(debug_assertions) { + debug!("files before select {:#?}", proc.files); + } drop(proc); let begin_time_ms = crate::trap::uptime_msec(); @@ -273,11 +278,10 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> proc.lookup_inode_at(dir_fd, &path, true)? }; - let mut file = FileHandle::new(inode, flags.to_options()); + let mut file = FileHandle::new(inode, flags.to_options(), String::from(path)); // for debugging if cfg!(debug_assertions) { - file.set_path(&path); debug!("files before open {:#?}", proc.files); } @@ -648,6 +652,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { write: false, append: false, }, + String::from(":pipe_r:"), ))); let write_fd = proc.add_file(FileLike::File(FileHandle::new( @@ -657,6 +662,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { write: true, append: false, }, + String::from(":pipe_w:"), ))); fds[0] = read_fd as u32; From feae733bb90406fddc9d98d59f07881471954ed8 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 2 May 2019 15:52:56 +0800 Subject: [PATCH 7/9] Implement poll for pipes --- kernel/src/fs/pipe.rs | 37 ++++++++++++++++++++++++++++++++++++- kernel/src/syscall/fs.rs | 4 ++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/kernel/src/fs/pipe.rs b/kernel/src/fs/pipe.rs index 8807380..6059e1a 100644 --- a/kernel/src/fs/pipe.rs +++ b/kernel/src/fs/pipe.rs @@ -57,7 +57,6 @@ impl Pipe { // TODO: better way to provide default impl? macro_rules! impl_inode { () => { - fn poll(&self) -> Result { Err(FsError::NotSupported) } fn metadata(&self) -> Result { Err(FsError::NotSupported) } fn set_metadata(&self, _metadata: &Metadata) -> Result<()> { Ok(()) } fn sync_all(&self) -> Result<()> { Ok(()) } @@ -104,5 +103,41 @@ impl INode for Pipe { Ok(0) } } + + fn poll(&self) -> Result { + let data = self.data.lock(); + match self.direction { + PipeEnd::Read => { + if data.buf.len() > 0 { + Ok(PollStatus { + read: true, + write: false, + error: false, + }) + } else { + Ok(PollStatus { + read: false, + write: false, + error: false, + }) + } + } + PipeEnd::Write => { + if data.buf.len() > 0 { + Ok(PollStatus { + read: false, + write: true, + error: false, + }) + } else { + Ok(PollStatus { + read: false, + write: false, + error: false, + }) + } + } + } + } impl_inode!(); } diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 56d14ae..49aebe5 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -652,7 +652,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { write: false, append: false, }, - String::from(":pipe_r:"), + String::from("pipe_r:[]"), ))); let write_fd = proc.add_file(FileLike::File(FileHandle::new( @@ -662,7 +662,7 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { write: true, append: false, }, - String::from(":pipe_w:"), + String::from("pipe_w:[]"), ))); fds[0] = read_fd as u32; From 6883127d5aba702d94f78c2c2e29dec35b887ecc Mon Sep 17 00:00:00 2001 From: WangRunji Date: Fri, 3 May 2019 00:35:00 +0800 Subject: [PATCH 8/9] update fs. add BlockCache --- kernel/Cargo.lock | 7 +++++-- kernel/src/drivers/block/ahci.rs | 4 +--- kernel/src/drivers/block/virtio_blk.rs | 2 +- kernel/src/drivers/mod.rs | 24 +++++++++++++++++------- kernel/src/fs/device.rs | 24 ++++++++++++++++-------- kernel/src/fs/mod.rs | 15 ++++++++++++--- user | 2 +- 7 files changed, 53 insertions(+), 25 deletions(-) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index c1dd7a0..e7232ad 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -396,12 +396,15 @@ dependencies = [ [[package]] name = "rcore-fs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs#6f282baf2fe928d2c9774e526e63125684855221" +source = "git+https://github.com/rcore-os/rcore-fs#41ccb1675cbea1df079f39fdc1bcd50c609df707" +dependencies = [ + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "rcore-fs-sfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs#6f282baf2fe928d2c9774e526e63125684855221" +source = "git+https://github.com/rcore-os/rcore-fs#41ccb1675cbea1df079f39fdc1bcd50c609df707" dependencies = [ "bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/kernel/src/drivers/block/ahci.rs b/kernel/src/drivers/block/ahci.rs index 189c6e4..f86b909 100644 --- a/kernel/src/drivers/block/ahci.rs +++ b/kernel/src/drivers/block/ahci.rs @@ -48,8 +48,6 @@ pub fn init(_irq: Option, header: usize, size: usize) -> Arc { let ahci = AHCI::new(header, size); let driver = Arc::new(AHCIDriver(Mutex::new(ahci))); DRIVERS.write().push(driver.clone()); - BLK_DRIVERS - .write() - .push(Arc::new(BlockDriver(driver.clone()))); + BLK_DRIVERS.write().push(driver.clone()); driver } diff --git a/kernel/src/drivers/block/virtio_blk.rs b/kernel/src/drivers/block/virtio_blk.rs index fd38b64..3a561f4 100644 --- a/kernel/src/drivers/block/virtio_blk.rs +++ b/kernel/src/drivers/block/virtio_blk.rs @@ -222,5 +222,5 @@ pub fn virtio_blk_init(node: &Node) { let driver = Arc::new(driver); DRIVERS.write().push(driver.clone()); - BLK_DRIVERS.write().push(Arc::new(BlockDriver(driver))); + BLK_DRIVERS.write().push(driver); } diff --git a/kernel/src/drivers/mod.rs b/kernel/src/drivers/mod.rs index de559ce..bc9bba8 100644 --- a/kernel/src/drivers/mod.rs +++ b/kernel/src/drivers/mod.rs @@ -7,7 +7,7 @@ use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address}; use spin::RwLock; use crate::sync::Condvar; -use rcore_fs::dev::BlockDevice; +use rcore_fs::dev::{self, BlockDevice, DevError}; #[allow(dead_code)] pub mod block; @@ -95,19 +95,29 @@ lazy_static! { // NOTE: RwLock only write when initializing drivers pub static ref DRIVERS: RwLock>> = RwLock::new(Vec::new()); pub static ref NET_DRIVERS: RwLock>> = RwLock::new(Vec::new()); - pub static ref BLK_DRIVERS: RwLock>> = RwLock::new(Vec::new()); + pub static ref BLK_DRIVERS: RwLock>> = RwLock::new(Vec::new()); } -pub struct BlockDriver(Arc); +pub struct BlockDriver(pub Arc); impl BlockDevice for BlockDriver { const BLOCK_SIZE_LOG2: u8 = 9; // 512 - fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool { - self.0.read_block(block_id, buf) + fn read_at(&self, block_id: usize, buf: &mut [u8]) -> dev::Result<()> { + match self.0.read_block(block_id, buf) { + true => Ok(()), + false => Err(DevError), + } } - fn write_at(&self, block_id: usize, buf: &[u8]) -> bool { - self.0.write_block(block_id, buf) + fn write_at(&self, block_id: usize, buf: &[u8]) -> dev::Result<()> { + match self.0.write_block(block_id, buf) { + true => Ok(()), + false => Err(DevError), + } + } + + fn sync(&self) -> dev::Result<()> { + Ok(()) } } diff --git a/kernel/src/fs/device.rs b/kernel/src/fs/device.rs index dc33ed8..dfe2cc4 100644 --- a/kernel/src/fs/device.rs +++ b/kernel/src/fs/device.rs @@ -19,34 +19,42 @@ impl MemBuf { } impl Device for MemBuf { - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option { + fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { let slice = self.0.read(); let len = buf.len().min(slice.len() - offset); buf[..len].copy_from_slice(&slice[offset..offset + len]); - Some(len) + Ok(len) } - fn write_at(&self, offset: usize, buf: &[u8]) -> Option { + fn write_at(&self, offset: usize, buf: &[u8]) -> Result { let mut slice = self.0.write(); let len = buf.len().min(slice.len() - offset); slice[offset..offset + len].copy_from_slice(&buf[..len]); - Some(len) + Ok(len) + } + fn sync(&self) -> Result<()> { + Ok(()) } } #[cfg(target_arch = "x86_64")] impl BlockDevice for ide::IDE { const BLOCK_SIZE_LOG2: u8 = 9; - fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool { + fn read_at(&self, block_id: usize, buf: &mut [u8]) -> Result<()> { use core::slice; assert!(buf.len() >= ide::BLOCK_SIZE); let buf = unsafe { slice::from_raw_parts_mut(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) }; - self.read(block_id as u64, 1, buf).is_ok() + self.read(block_id as u64, 1, buf).map_err(|_| DevError)?; + Ok(()) } - fn write_at(&self, block_id: usize, buf: &[u8]) -> bool { + fn write_at(&self, block_id: usize, buf: &[u8]) -> Result<()> { use core::slice; assert!(buf.len() >= ide::BLOCK_SIZE); let buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) }; - self.write(block_id as u64, 1, buf).is_ok() + self.write(block_id as u64, 1, buf).map_err(|_| DevError)?; + Ok(()) + } + fn sync(&self) -> Result<()> { + Ok(()) } } diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 7217ae3..4a378ad 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -1,8 +1,11 @@ use alloc::{sync::Arc, vec::Vec}; use rcore_fs::vfs::*; +use rcore_fs::dev::block_cache::BlockCache; use rcore_fs_sfs::SimpleFileSystem; +use crate::drivers::BlockDriver; + pub use self::file::*; pub use self::file_like::*; pub use self::pipe::Pipe; @@ -38,9 +41,15 @@ lazy_static! { let device = { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64", target_arch = "x86_64"))] { - crate::drivers::BLK_DRIVERS.read().iter() - .next().expect("Block device not found") - .clone() + let driver = BlockDriver( + crate::drivers::BLK_DRIVERS + .read().iter() + .next().expect("Block device not found") + .clone() + ); + // enable block cache + // Arc::new(BlockCache::new(driver, 0x100)) + Arc::new(driver) } #[cfg(target_arch = "aarch64")] { diff --git a/user b/user index aec8667..b6a3477 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit aec8667eb056cb564e301d6c0937da1e4500a4d3 +Subproject commit b6a347750531be125583107b6d0fc307366fdcc9 From 28aaae53b99b36ad4fbf5c27d52659c1474bda85 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Fri, 3 May 2019 11:33:56 +0800 Subject: [PATCH 9/9] Refactor ioctl numbers and add FIOCLEX --- kernel/src/fs/file_like.rs | 17 ++++++++++++----- kernel/src/fs/ioctl.rs | 36 ++++++++++++++++++++++++++++++++++++ kernel/src/fs/mod.rs | 5 +++-- kernel/src/fs/stdio.rs | 29 ++--------------------------- 4 files changed, 53 insertions(+), 34 deletions(-) create mode 100644 kernel/src/fs/ioctl.rs diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index 9c4913f..dbbdbe4 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -5,6 +5,7 @@ use crate::net::Socket; use crate::syscall::{SysError, SysResult}; use alloc::boxed::Box; use rcore_fs::vfs::PollStatus; +use super::ioctl::*; // TODO: merge FileLike to FileHandle ? // TODO: fix dup and remove Clone @@ -30,13 +31,19 @@ impl FileLike { Ok(len) } pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { - match self { - FileLike::File(file) => file.io_control(request as u32, arg1)?, - FileLike::Socket(socket) => { - socket.ioctl(request, arg1, arg2, arg3)?; + match request { + // TODO: place flags & path in FileLike in stead of FileHandle/Socket + FIOCLEX => Ok(0), + _ => { + match self { + FileLike::File(file) => file.io_control(request as u32, arg1)?, + FileLike::Socket(socket) => { + socket.ioctl(request, arg1, arg2, arg3)?; + } + } + Ok(0) } } - Ok(0) } pub fn poll(&self) -> Result { let status = match self { diff --git a/kernel/src/fs/ioctl.rs b/kernel/src/fs/ioctl.rs new file mode 100644 index 0000000..e9fa9ca --- /dev/null +++ b/kernel/src/fs/ioctl.rs @@ -0,0 +1,36 @@ +// for IOR and IOW: +// 32bits total, command in lower 16bits, size of the parameter structure in the lower 14 bits of the upper 16 bits +// higher 2 bits: 01 = write, 10 = read + +#[cfg(not(target_arch = "mips"))] +pub const TCGETS: usize = 0x5401; +#[cfg(target_arch = "mips")] +pub const TCGETS: usize = 0x540D; + +#[cfg(not(target_arch = "mips"))] +pub const TIOCGPGRP: usize = 0x540F; +// _IOR('t', 119, int) +#[cfg(target_arch = "mips")] +pub const TIOCGPGRP: usize = 0x4_004_74_77; + +#[cfg(not(target_arch = "mips"))] +pub const TIOCSPGRP: usize = 0x5410; +// _IOW('t', 118, int) +#[cfg(target_arch = "mips")] +pub const TIOCSPGRP: usize = 0x8_004_74_76; + +#[cfg(not(target_arch = "mips"))] +pub const TIOCGWINSZ: usize = 0x5413; +// _IOR('t', 104, struct winsize) +#[cfg(target_arch = "mips")] +pub const TIOCGWINSZ: usize = 0x4_008_74_68; + +#[cfg(not(target_arch = "mips"))] +pub const FIONCLEX: usize = 0x5450; +#[cfg(target_arch = "mips")] +pub const FIOCLEX: usize = 0x6602; + +#[cfg(not(target_arch = "mips"))] +pub const FIOCLEX: usize = 0x5451; +#[cfg(target_arch = "mips")] +pub const FIOCLEX: usize = 0x6601; \ No newline at end of file diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 4a378ad..a5e56a1 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -18,6 +18,7 @@ mod file_like; mod pipe; mod pseudo; mod stdio; +mod ioctl; /// Hard link user programs #[cfg(feature = "link_user")] @@ -48,8 +49,8 @@ lazy_static! { .clone() ); // enable block cache - // Arc::new(BlockCache::new(driver, 0x100)) - Arc::new(driver) + Arc::new(BlockCache::new(driver, 0x100)) + // Arc::new(driver) } #[cfg(target_arch = "aarch64")] { diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index e373a1d..11a342e 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -7,6 +7,7 @@ use rcore_fs::vfs::*; use crate::sync::Condvar; use crate::sync::SpinNoIrqLock as Mutex; +use super::ioctl::*; #[derive(Default)] pub struct Stdin { @@ -52,32 +53,6 @@ lazy_static! { pub static ref STDOUT: Arc = Arc::new(Stdout::default()); } -// 32bits total, command in lower 16bits, size of the parameter structure in the lower 14 bits of the upper 16 bits -// higher 2 bits: 01 = write, 10 = read - -#[cfg(not(target_arch = "mips"))] -const TCGETS: u32 = 0x5401; -#[cfg(target_arch = "mips")] -const TCGETS: u32 = 0x540D; - -#[cfg(not(target_arch = "mips"))] -const TIOCGPGRP: u32 = 0x540F; -// _IOR('t', 119, int) -#[cfg(target_arch = "mips")] -const TIOCGPGRP: u32 = 0x4_004_74_77; - -#[cfg(not(target_arch = "mips"))] -const TIOCSPGRP: u32 = 0x5410; -// _IOW('t', 118, int) -#[cfg(target_arch = "mips")] -const TIOCSPGRP: u32 = 0x8_004_74_76; - -#[cfg(not(target_arch = "mips"))] -const TIOCGWINSZ: u32 = 0x5413; -// _IOR('t', 104, struct winsize) -#[cfg(target_arch = "mips")] -const TIOCGWINSZ: u32 = 0x4_008_74_68; - // TODO: better way to provide default impl? macro_rules! impl_inode { () => { @@ -93,7 +68,7 @@ macro_rules! impl_inode { fn find(&self, _name: &str) -> Result> { Err(FsError::NotDir) } fn get_entry(&self, _id: usize) -> Result { Err(FsError::NotDir) } fn io_control(&self, cmd: u32, data: usize) -> Result<()> { - match cmd { + match cmd as usize { TCGETS | TIOCGWINSZ | TIOCSPGRP => { // pretend to be tty Ok(())