Allow disabling profiling at compile time.
This commit is contained in:
@@ -50,6 +50,7 @@ doc = []
|
||||
graphical_debug = []
|
||||
lpss_debug = []
|
||||
multi_core = ["acpi"]
|
||||
profiling = []
|
||||
#TODO: remove when threading issues are fixed
|
||||
pti = []
|
||||
qemu_debug = []
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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| {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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> {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user