Allow disabling profiling at compile time.

This commit is contained in:
4lDO2
2023-10-08 15:33:55 +02:00
parent fac0e783ef
commit 529c491fa0
11 changed files with 37 additions and 13 deletions
+1
View File
@@ -50,6 +50,7 @@ doc = []
graphical_debug = []
lpss_debug = []
multi_core = ["acpi"]
profiling = []
#TODO: remove when threading issues are fixed
pti = []
qemu_debug = []
+2
View File
@@ -201,6 +201,8 @@ pub unsafe fn init_paging(stack_offset: usize, cpu_id: LogicalCpuId) {
pcr.percpu = PercpuBlock {
cpu_id,
switch_internals: Default::default(),
#[cfg(feature = "profiling")]
profiling: None,
};
}
+2 -2
View File
@@ -8,7 +8,6 @@ use hashbrown::HashMap;
use x86::segmentation::Descriptor as X86IdtEntry;
use x86::dtables::{self, DescriptorTablePointer};
use crate::profiling::maybe_setup_timer;
use crate::{interrupt::*, LogicalCpuId};
use crate::interrupt::irq::{__generic_interrupts_end, __generic_interrupts_start};
use crate::ipi::IpiKind;
@@ -255,7 +254,8 @@ pub unsafe fn init_generic(cpu_id: LogicalCpuId, idt: &mut Idt) {
current_idt[0x80].set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT);
idt.set_reserved_mut(0x80, true);
maybe_setup_timer(idt, cpu_id);
#[cfg(feature = "profiling")]
crate::profiling::maybe_setup_timer(idt, cpu_id);
dtables::lidt(&idtr);
}
+7
View File
@@ -46,7 +46,14 @@ interrupt_stack!(debug, @paranoid, |stack| {
});
interrupt_stack!(non_maskable, @paranoid, |stack| {
#[cfg(feature = "profiling")]
crate::profiling::nmi_handler(stack);
#[cfg(not(feature = "profiling"))]
{
println!("Non-maskable interrupt");
stack.dump();
}
});
interrupt_stack!(breakpoint, |stack| {
+1
View File
@@ -252,6 +252,7 @@ interrupt!(lapic_timer, || {
println!("Local apic timer interrupt");
lapic_eoi();
});
#[cfg(feature = "profiling")]
interrupt!(aux_timer, || {
lapic_eoi();
crate::ipi::ipi(IpiKind::Profile, IpiTarget::Other);
+3
View File
@@ -5,6 +5,8 @@ pub enum IpiKind {
Tlb = 0x41,
Switch = 0x42,
Pit = 0x43,
#[cfg(feature = "profiling")]
Profile = 0x44,
}
@@ -25,6 +27,7 @@ pub fn ipi(_kind: IpiKind, _target: IpiTarget) {}
pub fn ipi(kind: IpiKind, target: IpiTarget) {
use crate::device::local_apic::LOCAL_APIC;
#[cfg(feature = "profiling")]
if matches!(kind, IpiKind::Profile) {
let icr = (target as u64) << 18 | 1 << 14 | 0b100 << 8;
unsafe { LOCAL_APIC.set_icr(icr) };
+5 -3
View File
@@ -6,7 +6,7 @@
use core::slice;
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering, AtomicU32};
use crate::{allocator, memory, LogicalCpuId, profiling};
use crate::{allocator, memory, LogicalCpuId};
#[cfg(feature = "acpi")]
use crate::acpi;
use crate::arch::pti;
@@ -150,7 +150,8 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! {
// Setup kernel heap
allocator::init();
profiling::init();
#[cfg(feature = "profiling")]
crate::profiling::init();
// Set up double buffer for grpahical debug now that heap is available
#[cfg(feature = "graphical_debug")]
@@ -236,7 +237,8 @@ pub unsafe extern fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! {
// Set up GDT with TLS
gdt::init_paging(stack_end, cpu_id);
profiling::init();
#[cfg(feature = "profiling")]
crate::profiling::init();
// Set up IDT for AP
idt::init_paging_post_heap(cpu_id);
+5
View File
@@ -122,6 +122,7 @@ mod percpu;
mod ptrace;
/// Performance profiling of the kernel
#[cfg(feature = "profiling")]
pub mod profiling;
/// Schemes, filesystem handlers
@@ -190,6 +191,8 @@ fn kmain(cpu_count: u32, bootstrap: Bootstrap) -> ! {
info!("Env: {:?}", ::core::str::from_utf8(bootstrap.env));
BOOTSTRAP.call_once(|| bootstrap);
#[cfg(feature = "profiling")]
profiling::ready_for_profiling();
match context::contexts_mut().spawn(userspace_init) {
@@ -221,6 +224,7 @@ fn kmain(cpu_count: u32, bootstrap: Bootstrap) -> ! {
/// This is the main kernel entry point for secondary CPUs
#[allow(unreachable_code, unused_variables)]
fn kmain_ap(cpu_id: LogicalCpuId) -> ! {
#[cfg(feature = "profiling")]
profiling::maybe_run_profiling_helper_forever(cpu_id);
if cfg!(feature = "multi_core") {
@@ -229,6 +233,7 @@ fn kmain_ap(cpu_id: LogicalCpuId) -> ! {
let pid = syscall::getpid();
info!("AP {}: {:?}", cpu_id, pid);
#[cfg(feature = "profiling")]
profiling::ready_for_profiling();
loop {
+2 -2
View File
@@ -1,6 +1,5 @@
use crate::LogicalCpuId;
use crate::context::switch::ContextSwitchPercpu;
use crate::profiling::RingBuffer;
/// The percpu block, that stored all percpu variables.
pub struct PercpuBlock {
@@ -13,7 +12,8 @@ pub struct PercpuBlock {
// TODO: Put mailbox queues here, e.g. for TLB shootdown? Just be sure to 128-byte align it
// first to avoid cache invalidation.
pub profiling: Option<&'static RingBuffer>,
#[cfg(feature = "profiling")]
pub profiling: Option<&'static crate::profiling::RingBuffer>,
}
// PercpuBlock::current() is implemented somewhere in the arch-specific modules
+8 -6
View File
@@ -1,7 +1,6 @@
use core::sync::atomic::{AtomicUsize, Ordering};
use spin::RwLock;
use crate::LogicalCpuId;
use crate::arch::debug::Writer;
use crate::event;
use crate::scheme::*;
@@ -45,6 +44,8 @@ impl KernelScheme for DebugScheme {
let num = match path {
"" => !0,
#[cfg(feature = "profiling")]
p if p.starts_with("profiling-") => {
path[10..].parse().map_err(|_| Error::new(ENOENT))?
}
@@ -110,12 +111,13 @@ impl KernelScheme for DebugScheme {
*handles.get(&id).ok_or(Error::new(EBADF))?
};
if handle.num == !0 {
INPUT
.receive_into_user(buf, handle.flags & O_NONBLOCK != O_NONBLOCK, "DebugScheme::read")
} else {
crate::profiling::drain_buffer(LogicalCpuId::new(handle.num as u32), buf)
#[cfg(feature = "profiling")]
if handle.num != !0 {
return crate::profiling::drain_buffer(crate::LogicalCpuId::new(handle.num as u32), buf);
}
INPUT
.receive_into_user(buf, handle.flags & O_NONBLOCK != O_NONBLOCK, "DebugScheme::read")
}
fn kwrite(&self, id: usize, buf: UserSliceRo) -> Result<usize> {
+1
View File
@@ -27,6 +27,7 @@ static HANDLES: RwLock<BTreeMap<usize, Handle>> = RwLock::new(BTreeMap::new());
/// Add to the input queue
pub fn serio_input(index: usize, data: u8) {
#[cfg(feature = "profiling")]
crate::profiling::serio_command(index, data);
INPUT[index].send(data);