debug: avoid debugging deadlocks

This commit is contained in:
Mark Poliakov 2025-02-15 20:18:30 +02:00
parent f716c50988
commit 82175f342e
2 changed files with 21 additions and 7 deletions

View File

@ -1,13 +1,12 @@
//! VirtIO queue implementation. //! VirtIO queue implementation.
use core::{future::poll_fn, mem::MaybeUninit, task::Poll, time::Duration}; use core::{future::poll_fn, mem::MaybeUninit, task::Poll};
use alloc::{boxed::Box, sync::Arc}; use alloc::{boxed::Box, sync::Arc};
use device_api::dma::DmaAllocator; use device_api::dma::DmaAllocator;
use libk::{ use libk::{
dma::{BusAddress, DmaBuffer, DmaSlice, DmaSliceMut}, dma::{BusAddress, DmaBuffer, DmaSlice, DmaSliceMut},
error::Error, error::Error,
task::runtime::psleep,
}; };
use libk_util::{ use libk_util::{
event::OneTimeEvent, hash_table::DefaultHashTable, sync::IrqSafeSpinlock, waker::QueueWaker, event::OneTimeEvent, hash_table::DefaultHashTable, sync::IrqSafeSpinlock, waker::QueueWaker,
@ -451,7 +450,7 @@ impl VirtQueue<VqManualNotification> {
if length != 0 { if length != 0 {
break; break;
} }
psleep(Duration::from_millis(1)); core::hint::spin_loop();
} }
Ok(length) Ok(length)
} }

View File

@ -7,15 +7,16 @@ use alloc::{
use core::{ use core::{
fmt, fmt,
str::FromStr, str::FromStr,
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, AtomicU32, Ordering},
}; };
use ring::RingLoggerSink; use ring::RingLoggerSink;
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit}; use libk_util::OneTimeInit;
use sink::DEBUG_SINKS; use sink::DEBUG_SINKS;
use yggdrasil_abi::error::Error; use yggdrasil_abi::error::Error;
use crate::{ use crate::{
arch::Cpu,
fs::sysfs::{ fs::sysfs::{
attribute::{StringAttribute, StringAttributeOps}, attribute::{StringAttribute, StringAttributeOps},
object::KObject, object::KObject,
@ -31,7 +32,7 @@ pub use panic::{panic_log, PanicLoggerSink};
pub use ring::add_kernel_log_file; pub use ring::add_kernel_log_file;
pub use sink::{add_early_sink, add_serial_sink, add_sink, disable_early_sinks, DebugSink}; pub use sink::{add_early_sink, add_serial_sink, add_sink, disable_early_sinks, DebugSink};
static DEBUG_LOCK: IrqSafeSpinlock<()> = IrqSafeSpinlock::new(()); static DEBUG_LOCK: AtomicU32 = AtomicU32::new(u32::MAX);
static MUTE_DEBUG: AtomicBool = AtomicBool::new(false); static MUTE_DEBUG: AtomicBool = AtomicBool::new(false);
pub struct MuteGuard(bool); pub struct MuteGuard(bool);
@ -104,6 +105,17 @@ impl From<log::Level> for LogLevel {
} }
} }
fn lock_debug() -> bool {
let cpu = Cpu::try_local().map_or(0, |cpu| cpu.id());
loop {
match DEBUG_LOCK.compare_exchange(u32::MAX, cpu, Ordering::Acquire, Ordering::Relaxed) {
Ok(_) => return true,
Err(x) if x == cpu => return false,
_ => core::hint::spin_loop(),
}
}
}
impl log::Log for KernelLoggerSink { impl log::Log for KernelLoggerSink {
fn enabled(&self, metadata: &log::Metadata) -> bool { fn enabled(&self, metadata: &log::Metadata) -> bool {
metadata.target() != "io" metadata.target() != "io"
@ -120,12 +132,15 @@ impl log::Log for KernelLoggerSink {
RingLoggerSink.log(record); RingLoggerSink.log(record);
let _guard = DEBUG_LOCK.lock(); if !lock_debug() {
return;
}
for sink in DEBUG_SINKS.read().iter() { for sink in DEBUG_SINKS.read().iter() {
if sink.enabled(record.metadata()) { if sink.enabled(record.metadata()) {
sink.log(record); sink.log(record);
} }
} }
DEBUG_LOCK.store(u32::MAX, Ordering::Release);
} }
fn flush(&self) {} fn flush(&self) {}