debug: avoid debugging deadlocks
This commit is contained in:
parent
f716c50988
commit
82175f342e
@ -1,13 +1,12 @@
|
||||
//! 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 device_api::dma::DmaAllocator;
|
||||
use libk::{
|
||||
dma::{BusAddress, DmaBuffer, DmaSlice, DmaSliceMut},
|
||||
error::Error,
|
||||
task::runtime::psleep,
|
||||
};
|
||||
use libk_util::{
|
||||
event::OneTimeEvent, hash_table::DefaultHashTable, sync::IrqSafeSpinlock, waker::QueueWaker,
|
||||
@ -451,7 +450,7 @@ impl VirtQueue<VqManualNotification> {
|
||||
if length != 0 {
|
||||
break;
|
||||
}
|
||||
psleep(Duration::from_millis(1));
|
||||
core::hint::spin_loop();
|
||||
}
|
||||
Ok(length)
|
||||
}
|
||||
|
@ -7,15 +7,16 @@ use alloc::{
|
||||
use core::{
|
||||
fmt,
|
||||
str::FromStr,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
sync::atomic::{AtomicBool, AtomicU32, Ordering},
|
||||
};
|
||||
use ring::RingLoggerSink;
|
||||
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
use libk_util::OneTimeInit;
|
||||
use sink::DEBUG_SINKS;
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use crate::{
|
||||
arch::Cpu,
|
||||
fs::sysfs::{
|
||||
attribute::{StringAttribute, StringAttributeOps},
|
||||
object::KObject,
|
||||
@ -31,7 +32,7 @@ pub use panic::{panic_log, PanicLoggerSink};
|
||||
pub use ring::add_kernel_log_file;
|
||||
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);
|
||||
|
||||
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 {
|
||||
fn enabled(&self, metadata: &log::Metadata) -> bool {
|
||||
metadata.target() != "io"
|
||||
@ -120,12 +132,15 @@ impl log::Log for KernelLoggerSink {
|
||||
|
||||
RingLoggerSink.log(record);
|
||||
|
||||
let _guard = DEBUG_LOCK.lock();
|
||||
if !lock_debug() {
|
||||
return;
|
||||
}
|
||||
for sink in DEBUG_SINKS.read().iter() {
|
||||
if sink.enabled(record.metadata()) {
|
||||
sink.log(record);
|
||||
}
|
||||
}
|
||||
DEBUG_LOCK.store(u32::MAX, Ordering::Release);
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user