diff --git a/kernel/comps/console/src/lib.rs b/kernel/comps/console/src/lib.rs index 11955f6e..17e7ea81 100644 --- a/kernel/comps/console/src/lib.rs +++ b/kernel/comps/console/src/lib.rs @@ -13,7 +13,7 @@ use core::any::Any; use component::{init_component, ComponentInitError}; use ostd::{ mm::{Infallible, VmReader}, - sync::SpinLock, + sync::{LocalIrqDisabled, SpinLock, SpinLockGuard}, }; use spin::Once; @@ -52,6 +52,16 @@ pub fn all_devices() -> Vec<(String, Arc)> { .collect() } +pub fn all_devices_lock<'a>( +) -> SpinLockGuard<'a, BTreeMap>, LocalIrqDisabled> { + COMPONENT + .get() + .unwrap() + .console_device_table + .disable_irq() + .lock() +} + static COMPONENT: Once = Once::new(); #[init_component] diff --git a/kernel/comps/logger/src/console.rs b/kernel/comps/logger/src/console.rs index 9ece9fd6..d0402d6c 100644 --- a/kernel/comps/logger/src/console.rs +++ b/kernel/comps/logger/src/console.rs @@ -11,7 +11,11 @@ struct VirtioConsolesPrinter; impl Write for VirtioConsolesPrinter { fn write_str(&mut self, s: &str) -> core::fmt::Result { - for (_, device) in aster_console::all_devices() { + // We must call `all_devices_lock` instead of `all_devices` here, as `all_devices` invokes + // the clone method of String and Arc, which may lead to a deadlock when there is low memory + // in the heap (The heap allocator will log a message when memory is low.). + let devices = aster_console::all_devices_lock(); + for (_, device) in devices.iter() { device.send(s.as_bytes()); } Ok(())