From 78de1af348e2daab90777e2d8229daea893649a8 Mon Sep 17 00:00:00 2001 From: Chuandong Li Date: Sun, 2 Jul 2023 18:31:53 +0800 Subject: [PATCH] Update spin lock users to lock_irq_disabled() --- .../jinux-frame/src/arch/x86/device/serial.rs | 4 +- framework/jinux-frame/src/sync/rcu/monitor.rs | 4 +- framework/jinux-frame/src/sync/spin.rs | 6 +-- framework/jinux-frame/src/sync/wait.rs | 10 ++--- .../jinux-frame/src/vm/heap_allocator.rs | 6 +-- services/comps/framebuffer/src/lib.rs | 7 +++- services/comps/network/src/lib.rs | 2 +- services/comps/network/src/virtio.rs | 7 +++- .../libs/jinux-std/src/device/tty/driver.rs | 8 ++-- .../src/device/tty/line_discipline.rs | 42 +++++++++---------- services/libs/jinux-std/src/device/tty/mod.rs | 2 +- .../libs/jinux-std/src/net/iface/common.rs | 22 +++++----- services/libs/jinux-std/src/net/iface/mod.rs | 4 +- .../libs/jinux-std/src/net/iface/virtio.rs | 2 +- services/libs/jinux-std/src/prelude.rs | 2 +- 15 files changed, 69 insertions(+), 59 deletions(-) diff --git a/framework/jinux-frame/src/arch/x86/device/serial.rs b/framework/jinux-frame/src/arch/x86/device/serial.rs index 0dfe7d2a..c2da6180 100644 --- a/framework/jinux-frame/src/arch/x86/device/serial.rs +++ b/framework/jinux-frame/src/arch/x86/device/serial.rs @@ -51,7 +51,7 @@ pub(crate) fn init() { } pub fn register_serial_input_callback(f: impl Fn(u8) + Send + Sync + 'static) { - SERIAL_INPUT_CALLBACKS.lock().push(Arc::new(f)); + SERIAL_INPUT_CALLBACKS.lock_irq_disabled().push(Arc::new(f)); } pub(crate) fn callback_init() { @@ -67,7 +67,7 @@ where CONSOLE_IRQ_CALLBACK .get() .unwrap() - .lock() + .lock_irq_disabled() .on_active(callback); } diff --git a/framework/jinux-frame/src/sync/rcu/monitor.rs b/framework/jinux-frame/src/sync/rcu/monitor.rs index 73254dda..7a58abbc 100644 --- a/framework/jinux-frame/src/sync/rcu/monitor.rs +++ b/framework/jinux-frame/src/sync/rcu/monitor.rs @@ -35,7 +35,7 @@ impl RcuMonitor { // on the current CPU. If GP is complete, take the callbacks of the current // GP. let callbacks = { - let mut state = self.state.lock(); + let mut state = self.state.lock_irq_disabled(); if state.current_gp.is_complete() { return; } @@ -69,7 +69,7 @@ impl RcuMonitor { where F: FnOnce() -> () + Send + 'static, { - let mut state = self.state.lock(); + let mut state = self.state.lock_irq_disabled(); state.next_callbacks.push_back(Box::new(f)); diff --git a/framework/jinux-frame/src/sync/spin.rs b/framework/jinux-frame/src/sync/spin.rs index 04da13ee..6b5071d5 100644 --- a/framework/jinux-frame/src/sync/spin.rs +++ b/framework/jinux-frame/src/sync/spin.rs @@ -52,8 +52,8 @@ impl SpinLock { /// Acquire the spin lock without disabling local IRQs. /// - /// This method is twice as fast as the `lock_irq_disable` method. - /// So prefer using this method over the `lock_irq_disable` method + /// This method is twice as fast as the `lock_irq_disabled` method. + /// So prefer using this method over the `lock_irq_disabled` method /// when IRQ handlers are allowed to get executed while /// holding this lock. For example, if a lock is never used /// in the interrupt context, then it is ok to use this method @@ -137,7 +137,7 @@ impl<'a, T: fmt::Debug> fmt::Debug for SpinLockIrqDisabledGuard<'a, T> { impl<'a, T> !Send for SpinLockIrqDisabledGuard<'a, T> {} // Safety. `SpinLockIrqDisabledGuard` can be shared between tasks/threads in same CPU. -// As `lock_irq_disable()` disables interrupts to prevent race conditions caused by interrupts. +// As `lock_irq_disabled()` disables interrupts to prevent race conditions caused by interrupts. unsafe impl Sync for SpinLockIrqDisabledGuard<'_, T> {} pub struct SpinLockGuard<'a, T> { diff --git a/framework/jinux-frame/src/sync/wait.rs b/framework/jinux-frame/src/sync/wait.rs index 82001546..cdaa3290 100644 --- a/framework/jinux-frame/src/sync/wait.rs +++ b/framework/jinux-frame/src/sync/wait.rs @@ -53,14 +53,14 @@ impl WaitQueue { /// Wake one waiter thread, if there is one. pub fn wake_one(&self) { - if let Some(waiter) = self.waiters.lock().front() { + if let Some(waiter) = self.waiters.lock_irq_disabled().front() { waiter.wake_up(); } } /// Wake all not-exclusive waiter threads and at most one exclusive waiter. pub fn wake_all(&self) { - for waiter in self.waiters.lock().iter() { + for waiter in self.waiters.lock_irq_disabled().iter() { waiter.wake_up(); if waiter.is_exclusive() { break; @@ -72,15 +72,15 @@ impl WaitQueue { // Otherwise, add to the front of waitqueue fn enqueue(&self, waiter: &Arc) { if waiter.is_exclusive() { - self.waiters.lock().push_back(waiter.clone()) + self.waiters.lock_irq_disabled().push_back(waiter.clone()) } else { - self.waiters.lock().push_front(waiter.clone()); + self.waiters.lock_irq_disabled().push_front(waiter.clone()); } } /// removes all waiters that have finished wait fn finish_wait(&self) { - self.waiters.lock().retain(|waiter| !waiter.is_finished()) + self.waiters.lock_irq_disabled().retain(|waiter| !waiter.is_finished()) } } diff --git a/framework/jinux-frame/src/vm/heap_allocator.rs b/framework/jinux-frame/src/vm/heap_allocator.rs index 8917f10c..99e40573 100644 --- a/framework/jinux-frame/src/vm/heap_allocator.rs +++ b/framework/jinux-frame/src/vm/heap_allocator.rs @@ -32,20 +32,20 @@ impl LockedHeap { /// Safety: The range [start, start + size) must be a valid memory region. pub unsafe fn init(&self, start: *const u8, size: usize) { - self.0.lock().init(start as usize, size); + self.0.lock_irq_disabled().init(start as usize, size); } } unsafe impl GlobalAlloc for LockedHeap { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { self.0 - .lock() + .lock_irq_disabled() .alloc(layout) .map_or(0 as *mut u8, |allocation| allocation.as_ptr()) } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { debug_assert!(ptr as usize != 0); - self.0.lock().dealloc(NonNull::new_unchecked(ptr), layout) + self.0.lock_irq_disabled().dealloc(NonNull::new_unchecked(ptr), layout) } } diff --git a/services/comps/framebuffer/src/lib.rs b/services/comps/framebuffer/src/lib.rs index 1e86c34a..0e0b7fdf 100644 --- a/services/comps/framebuffer/src/lib.rs +++ b/services/comps/framebuffer/src/lib.rs @@ -204,5 +204,10 @@ macro_rules! println { pub fn _print(args: fmt::Arguments) { use core::fmt::Write; - WRITER.get().unwrap().lock().write_fmt(args).unwrap(); + WRITER + .get() + .unwrap() + .lock_irq_disabled() + .write_fmt(args) + .unwrap(); } diff --git a/services/comps/network/src/lib.rs b/services/comps/network/src/lib.rs index c67f2b5e..361d134f 100644 --- a/services/comps/network/src/lib.rs +++ b/services/comps/network/src/lib.rs @@ -54,6 +54,6 @@ pub fn register_net_device_irq_handler(callback: impl NetDeviceIrqHandler) { NETWORK_IRQ_HANDLERS .get() .unwrap() - .lock() + .lock_irq_disabled() .push(Arc::new(callback)) } diff --git a/services/comps/network/src/virtio.rs b/services/comps/network/src/virtio.rs index e97a531a..305e30b6 100644 --- a/services/comps/network/src/virtio.rs +++ b/services/comps/network/src/virtio.rs @@ -97,7 +97,12 @@ fn config_space_change(_: &TrapFrame) { /// Interrupt handler if network device receives some packet fn handle_network_event(trap_frame: &TrapFrame) { let irq_num = trap_frame.trap_num as u8; - for callback in NETWORK_IRQ_HANDLERS.get().unwrap().lock().iter() { + for callback in NETWORK_IRQ_HANDLERS + .get() + .unwrap() + .lock_irq_disabled() + .iter() + { callback(irq_num); } } diff --git a/services/libs/jinux-std/src/device/tty/driver.rs b/services/libs/jinux-std/src/device/tty/driver.rs index d9eb04a4..722b480e 100644 --- a/services/libs/jinux-std/src/device/tty/driver.rs +++ b/services/libs/jinux-std/src/device/tty/driver.rs @@ -30,7 +30,7 @@ impl TtyDriver { /// Return the tty device in driver's internal table. pub fn lookup(&self, index: usize) -> Result> { - let ttys = self.ttys.lock(); + let ttys = self.ttys.lock_irq_disabled(); // Return the tty device corresponding to idx if index >= ttys.len() { return_errno_with_message!(Errno::ENODEV, "lookup failed. No tty device"); @@ -43,12 +43,12 @@ impl TtyDriver { /// Install a new tty into the driver's internal tables. pub fn install(self: &Arc, tty: Arc) { tty.set_driver(Arc::downgrade(self)); - self.ttys.lock().push(tty); + self.ttys.lock_irq_disabled().push(tty); } /// remove a new tty into the driver's internal tables. pub fn remove(&self, index: usize) -> Result<()> { - let mut ttys = self.ttys.lock(); + let mut ttys = self.ttys.lock_irq_disabled(); if index >= ttys.len() { return_errno_with_message!(Errno::ENODEV, "lookup failed. No tty device"); } @@ -60,7 +60,7 @@ impl TtyDriver { pub fn receive_char(&self, item: u8) { // FIXME: should the char send to all ttys? - for tty in &*self.ttys.lock() { + for tty in &*self.ttys.lock_irq_disabled() { tty.receive_char(item); } } diff --git a/services/libs/jinux-std/src/device/tty/line_discipline.rs b/services/libs/jinux-std/src/device/tty/line_discipline.rs index fe016bd6..ca4c05af 100644 --- a/services/libs/jinux-std/src/device/tty/line_discipline.rs +++ b/services/libs/jinux-std/src/device/tty/line_discipline.rs @@ -75,7 +75,7 @@ impl LineDiscipline { /// push char to line discipline. This function should be called in input interrupt handler. pub fn push_char(&self, mut item: u8) { - let termios = self.termios.lock(); + let termios = self.termios.lock_irq_disabled(); if termios.contains_icrnl() { if item == b'\r' { item = b'\n' @@ -85,7 +85,7 @@ impl LineDiscipline { if item == *termios.get_special_char(CC_C_CHAR::VINTR) { // type Ctrl + C, signal SIGINT if termios.contains_isig() { - if let Some(fg) = *self.foreground.lock() { + if let Some(fg) = *self.foreground.lock_irq_disabled() { let kernel_signal = KernelSignal::new(SIGINT); let fg_group = process_table::pgid_to_process_group(fg).unwrap(); fg_group.kernel_signal(kernel_signal); @@ -94,7 +94,7 @@ impl LineDiscipline { } else if item == *termios.get_special_char(CC_C_CHAR::VQUIT) { // type Ctrl + \, signal SIGQUIT if termios.contains_isig() { - if let Some(fg) = *self.foreground.lock() { + if let Some(fg) = *self.foreground.lock_irq_disabled() { let kernel_signal = KernelSignal::new(SIGQUIT); let fg_group = process_table::pgid_to_process_group(fg).unwrap(); fg_group.kernel_signal(kernel_signal); @@ -102,29 +102,29 @@ impl LineDiscipline { } } else if item == *termios.get_special_char(CC_C_CHAR::VKILL) { // erase current line - self.current_line.lock().drain(); + self.current_line.lock_irq_disabled().drain(); } else if item == *termios.get_special_char(CC_C_CHAR::VERASE) { // type backspace - let mut current_line = self.current_line.lock(); + let mut current_line = self.current_line.lock_irq_disabled(); if !current_line.is_empty() { current_line.backspace(); } } else if meet_new_line(item, &termios) { // a new line was met. We currently add the item to buffer. // when we read content, the item should be skipped if it's EOF. - let mut current_line = self.current_line.lock(); + let mut current_line = self.current_line.lock_irq_disabled(); current_line.push_char(item); let current_line_chars = current_line.drain(); for char in current_line_chars { - self.read_buffer.lock().push_overwrite(char); + self.read_buffer.lock_irq_disabled().push_overwrite(char); } } else if item >= 0x20 && item < 0x7f { // printable character - self.current_line.lock().push_char(item); + self.current_line.lock_irq_disabled().push_char(item); } } else { // raw mode - self.read_buffer.lock().push_overwrite(item); + self.read_buffer.lock_irq_disabled().push_overwrite(item); // debug!("push char: {}", char::from(item)) } @@ -139,7 +139,7 @@ impl LineDiscipline { /// whether self is readable fn is_readable(&self) -> bool { - !self.read_buffer.lock().is_empty() + !self.read_buffer.lock_irq_disabled().is_empty() } // TODO: respect output flags @@ -201,13 +201,13 @@ impl LineDiscipline { } let (vmin, vtime) = { - let termios = self.termios.lock(); + let termios = self.termios.lock_irq_disabled(); let vmin = *termios.get_special_char(CC_C_CHAR::VMIN); let vtime = *termios.get_special_char(CC_C_CHAR::VTIME); (vmin, vtime) }; let read_len = { - let len = self.read_buffer.lock().len(); + let len = self.read_buffer.lock_irq_disabled().len(); let max_read_len = len.min(dst.len()); if vmin == 0 && vtime == 0 { // poll read @@ -236,7 +236,7 @@ impl LineDiscipline { /// returns immediately with the lesser of the number of bytes available or the number of bytes requested. /// If no bytes are available, completes immediately, returning 0. fn poll_read(&self, dst: &mut [u8]) -> usize { - let mut buffer = self.read_buffer.lock(); + let mut buffer = self.read_buffer.lock_irq_disabled(); let len = buffer.len(); let max_read_len = len.min(dst.len()); if max_read_len == 0 { @@ -245,7 +245,7 @@ impl LineDiscipline { let mut read_len = 0; for i in 0..max_read_len { if let Some(next_char) = buffer.pop() { - let termios = self.termios.lock(); + let termios = self.termios.lock_irq_disabled(); if termios.is_canonical_mode() { // canonical mode, read until meet new line if meet_new_line(next_char, &termios) { @@ -276,7 +276,7 @@ impl LineDiscipline { // MIN bytes are available, and returns the lesser of the two values. pub fn block_read(&self, dst: &mut [u8], vmin: u8) -> Result { let min_read_len = (vmin as usize).min(dst.len()); - let buffer_len = self.read_buffer.lock().len(); + let buffer_len = self.read_buffer.lock_irq_disabled().len(); if buffer_len < min_read_len { return_errno!(Errno::EAGAIN); } @@ -291,7 +291,7 @@ impl LineDiscipline { /// whether the current process belongs to foreground process group fn current_belongs_to_foreground(&self) -> bool { let current = current!(); - if let Some(fg_pgid) = *self.foreground.lock() { + if let Some(fg_pgid) = *self.foreground.lock_irq_disabled() { if let Some(process_group) = process_table::pgid_to_process_group(fg_pgid) { if process_group.contains_process(current.pid()) { return true; @@ -304,7 +304,7 @@ impl LineDiscipline { /// set foreground process group pub fn set_fg(&self, fg_pgid: Pgid) { - *self.foreground.lock() = Some(fg_pgid); + *self.foreground.lock_irq_disabled() = Some(fg_pgid); // Some background processes may be waiting on the wait queue, when set_fg, the background processes may be able to read. if self.is_readable() { self.pollee.add_events(IoEvents::IN); @@ -313,20 +313,20 @@ impl LineDiscipline { /// get foreground process group id pub fn fg_pgid(&self) -> Option { - *self.foreground.lock() + *self.foreground.lock_irq_disabled() } /// whether there is buffered data pub fn is_empty(&self) -> bool { - self.read_buffer.lock().len() == 0 + self.read_buffer.lock_irq_disabled().len() == 0 } pub fn termios(&self) -> KernelTermios { - *self.termios.lock() + *self.termios.lock_irq_disabled() } pub fn set_termios(&self, termios: KernelTermios) { - *self.termios.lock() = termios; + *self.termios.lock_irq_disabled() = termios; } } diff --git a/services/libs/jinux-std/src/device/tty/mod.rs b/services/libs/jinux-std/src/device/tty/mod.rs index 8bde2ae5..c974b5a9 100644 --- a/services/libs/jinux-std/src/device/tty/mod.rs +++ b/services/libs/jinux-std/src/device/tty/mod.rs @@ -45,7 +45,7 @@ impl Tty { } pub fn set_driver(&self, driver: Weak) { - *self.driver.lock() = driver; + *self.driver.lock_irq_disabled() = driver; } pub fn receive_char(&self, item: u8) { diff --git a/services/libs/jinux-std/src/net/iface/common.rs b/services/libs/jinux-std/src/net/iface/common.rs index 2a9415b1..bde9bd4b 100644 --- a/services/libs/jinux-std/src/net/iface/common.rs +++ b/services/libs/jinux-std/src/net/iface/common.rs @@ -38,20 +38,20 @@ impl IfaceCommon { } } - pub(super) fn interface(&self) -> SpinLockGuard { - self.interface.lock() + pub(super) fn interface(&self) -> SpinLockIrqDisabledGuard { + self.interface.lock_irq_disabled() } - pub(super) fn sockets(&self) -> SpinLockGuard> { - self.sockets.lock() + pub(super) fn sockets(&self) -> SpinLockIrqDisabledGuard> { + self.sockets.lock_irq_disabled() } pub(super) fn ipv4_addr(&self) -> Option { - self.interface.lock().ipv4_addr() + self.interface.lock_irq_disabled().ipv4_addr() } pub(super) fn netmask(&self) -> Option { - let interface = self.interface.lock(); + let interface = self.interface.lock_irq_disabled(); let ip_addrs = interface.ip_addrs(); ip_addrs.first().map(|cidr| match cidr { IpCidr::Ipv4(ipv4_cidr) => ipv4_cidr.netmask(), @@ -113,7 +113,7 @@ impl IfaceCommon { } let socket_family = socket.socket_family(); let pollee = socket.pollee(); - let mut sockets = self.sockets.lock(); + let mut sockets = self.sockets.lock_irq_disabled(); let handle = match socket.raw_socket_family() { AnyRawSocket::Tcp(tcp_socket) => sockets.add(tcp_socket), AnyRawSocket::Udp(udp_socket) => sockets.add(udp_socket), @@ -125,14 +125,14 @@ impl IfaceCommon { /// Remove a socket from the interface pub(super) fn remove_socket(&self, handle: SocketHandle) { - self.sockets.lock().remove(handle); + self.sockets.lock_irq_disabled().remove(handle); } pub(super) fn poll(&self, device: &mut D) { - let mut interface = self.interface.lock(); + let mut interface = self.interface.lock_irq_disabled(); let timestamp = get_network_timestamp(); let has_events = { - let mut sockets = self.sockets.lock(); + let mut sockets = self.sockets.lock_irq_disabled(); interface.poll(timestamp, device, &mut sockets) // drop sockets here to avoid deadlock }; @@ -143,7 +143,7 @@ impl IfaceCommon { }); } - let sockets = self.sockets.lock(); + let sockets = self.sockets.lock_irq_disabled(); if let Some(instant) = interface.poll_at(timestamp, &sockets) { self.next_poll_at_ms .store(instant.total_millis() as u64, Ordering::SeqCst); diff --git a/services/libs/jinux-std/src/net/iface/mod.rs b/services/libs/jinux-std/src/net/iface/mod.rs index 04fb0b4b..f53c44ac 100644 --- a/services/libs/jinux-std/src/net/iface/mod.rs +++ b/services/libs/jinux-std/src/net/iface/mod.rs @@ -65,11 +65,11 @@ mod internal { pub trait IfaceInternal { fn common(&self) -> &IfaceCommon; /// The inner socket set - fn sockets(&self) -> SpinLockGuard> { + fn sockets(&self) -> SpinLockIrqDisabledGuard> { self.common().sockets() } /// The inner iface. - fn iface_inner(&self) -> SpinLockGuard { + fn iface_inner(&self) -> SpinLockIrqDisabledGuard { self.common().interface() } /// The time we should do another poll. diff --git a/services/libs/jinux-std/src/net/iface/virtio.rs b/services/libs/jinux-std/src/net/iface/virtio.rs index 02e3e0cc..3caac6d4 100644 --- a/services/libs/jinux-std/src/net/iface/virtio.rs +++ b/services/libs/jinux-std/src/net/iface/virtio.rs @@ -112,7 +112,7 @@ impl Iface for IfaceVirtio { } fn poll(&self) { - let mut driver = self.driver.lock(); + let mut driver = self.driver.lock_irq_disabled(); self.common.poll(&mut *driver); self.process_dhcp(); } diff --git a/services/libs/jinux-std/src/prelude.rs b/services/libs/jinux-std/src/prelude.rs index 701fe1b1..1b03d418 100644 --- a/services/libs/jinux-std/src/prelude.rs +++ b/services/libs/jinux-std/src/prelude.rs @@ -18,7 +18,7 @@ pub(crate) use core::ffi::CStr; pub(crate) use int_to_c_enum::TryFromInt; pub(crate) use jinux_frame::config::PAGE_SIZE; // pub(crate) use jinux_frame::sync::{Mutex, MutexGuard}; -pub(crate) use jinux_frame::sync::{SpinLock, SpinLockGuard}; +pub(crate) use jinux_frame::sync::{SpinLock, SpinLockGuard, SpinLockIrqDisabledGuard}; pub(crate) use jinux_frame::vm::Vaddr; pub(crate) use jinux_frame::{print, println}; pub(crate) use log::{debug, error, info, trace, warn};