From 4545feec9a7742e9d181fb1e1553c3968005d288 Mon Sep 17 00:00:00 2001 From: Friday Ortiz Date: Wed, 15 Oct 2025 16:43:00 -0400 Subject: [PATCH] aya,test,xtask: add breakpoint support to enforced perf_event config combo branch * aya: enforce valid perf_event type & config combos Add guardrails for when setting event type and config for perf_event programs. The `PerfEventConfig` enum now defines the event `type` and `config` of interest. Remove public re-exports, and add idiomatic Rust types for: - perf_hw_id => HardwareEvent - perf_sw_ids => SoftwareEvent - perf_hw_cache_id => HwCacheEvent - perf_hw_cache_op_id => HwCacheOp - perf_hw_cache_op_result_id => HwCacheResult The motivation behind this is mainly for the `type` and `config` fields of `bpf_link_info.perf_event.event`. The newly added enums are planned to also be used in the `bpf_link_info` metadata. Although `Breakpoint`/`PERF_TYPE_BREAKPOINT` variant exists, it is not fully implemented. It's only usage at the moment is in link info. * add breakpoint support to perf_event config interface --------- Co-authored-by: Tyrone Wu --- aya/src/programs/mod.rs | 2 +- aya/src/programs/perf_event.rs | 408 +++++++++++++++--- aya/src/sys/perf_event.rs | 26 +- .../src/tests/perf_event_bp.rs | 18 +- xtask/public-api/aya.txt | 382 ++++++++++------ 5 files changed, 626 insertions(+), 210 deletions(-) diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index 13db6144..9b3f530f 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -111,7 +111,7 @@ pub use crate::programs::{ lirc_mode2::LircMode2, lsm::Lsm, lsm_cgroup::LsmCgroup, - perf_event::{PerfEvent, PerfEventScope, PerfTypeId, SamplePolicy}, + perf_event::{PerfEvent, PerfEventScope, SamplePolicy}, probe::ProbeKind, raw_trace_point::RawTracePoint, sk_lookup::SkLookup, diff --git a/aya/src/programs/perf_event.rs b/aya/src/programs/perf_event.rs index c30ed8ea..ec581dc9 100644 --- a/aya/src/programs/perf_event.rs +++ b/aya/src/programs/perf_event.rs @@ -8,14 +8,13 @@ use aya_obj::generated::{ HW_BREAKPOINT_LEN_7, HW_BREAKPOINT_LEN_8, HW_BREAKPOINT_R, HW_BREAKPOINT_RW, HW_BREAKPOINT_W, HW_BREAKPOINT_X, bpf_link_type, bpf_prog_type::BPF_PROG_TYPE_PERF_EVENT, + perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids, + perf_type_id, perf_type_id::{ PERF_TYPE_BREAKPOINT, PERF_TYPE_HARDWARE, PERF_TYPE_HW_CACHE, PERF_TYPE_RAW, PERF_TYPE_SOFTWARE, PERF_TYPE_TRACEPOINT, }, }; -pub use aya_obj::generated::{ - perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids, -}; use crate::{ programs::{ @@ -27,34 +26,268 @@ use crate::{ sys::{SyscallError, bpf_link_get_info_by_fd, perf_event_open}, }; -/// The type of perf event +/// The type of perf event and their respective configuration. +#[doc(alias = "perf_type_id")] +#[derive(Debug, Clone, Copy)] +pub enum PerfEventConfig { + /// The hardware event to report. + #[doc(alias = "PERF_TYPE_HARDWARE")] + Hardware(HardwareEvent), + /// The software event to report. + #[doc(alias = "PERF_TYPE_SOFTWARE")] + Software(SoftwareEvent), + /// The kernel trace point event to report. + #[doc(alias = "PERF_TYPE_TRACEPOINT")] + TracePoint { + /// The ID of the tracing event. This can be obtained from + /// `/sys/kernel/debug/tracing/events/*/*/id` if `ftrace` is enabled in the kernel. + event_id: u64, + }, + /// The hardware cache event to report. + #[doc(alias = "PERF_TYPE_HW_CACHE")] + HwCache { + /// The hardware cache event. + event: HwCacheEvent, + /// The hardware cache operation. + operation: HwCacheOp, + /// The hardware cache result of interest. + result: HwCacheResult, + }, + /// The "raw" implementation-specific event to report. + #[doc(alias = "PERF_TYPE_RAW")] + Raw { + /// The "raw" event value, which is not covered by the "generalized" events. This is CPU + /// implementation defined events. + event_id: u64, + }, + /// A hardware breakpoint. + #[doc(alias = "PERF_TYPE_BREAKPOINT")] + Breakpoint { + /// The address to set the breakpoint on + address: u64, + /// The breakpoint size. For HwBreakpointX this must be sizeof(long). For + /// all other types it should be one of HwBreakpointLen1, HwBreakpointLen2,, + /// HwBreakpointLen4 or HwBreakpointLen8. + length: PerfBreakpointSize, + /// The breakpoint type, one of HW_BREAKPOINT_{R,W,RW,X} + type_: PerfBreakpointType, + }, + /// The dynamic PMU (Performance Monitor Unit) event to report. + /// + /// Available PMU's may be found under `/sys/bus/event_source/devices`. + Pmu { + /// The PMU type. + /// + /// This value can extracted from `/sys/bus/event_source/devices/*/type`. + pmu_type: u32, + /// The PMU config option. + /// + /// This value can extracted from `/sys/bus/event_source/devices/*/format/`, where the + /// `config:` indicates the bit position to set. + /// + /// For example, `config:3` => `config = 1 << 3`. + config: u64, + }, +} + +macro_rules! impl_to_u32 { + ($($t:ty, $fn:ident),*) => { + $(const fn $fn(id: $t) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::<$t>()]; + id as u32 + })* + }; +} + +impl_to_u32!( + perf_hw_id, + perf_hw_id_to_u32, + perf_sw_ids, + perf_sw_ids_to_u32, + perf_hw_cache_id, + perf_hw_cache_id_to_u32, + perf_hw_cache_op_id, + perf_hw_cache_op_id_to_u32, + perf_hw_cache_op_result_id, + perf_hw_cache_op_result_id_to_u32, + perf_type_id, + perf_type_id_to_u32 +); + +/// The "generalized" hardware CPU events provided by the kernel. +#[doc(alias = "perf_hw_id")] +#[derive(Debug, Clone, Copy)] #[repr(u32)] +pub enum HardwareEvent { + /// The total CPU cycles. + #[doc(alias = "PERF_COUNT_HW_CPU_CYCLES")] + CpuCycles = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_CPU_CYCLES), + /// Number of retired instructions. + #[doc(alias = "PERF_COUNT_HW_INSTRUCTIONS")] + Instructions = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_INSTRUCTIONS), + /// Number of cache accesses. + #[doc(alias = "PERF_COUNT_HW_CACHE_REFERENCES")] + CacheReferences = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_CACHE_REFERENCES), + /// Number of cache misses. + #[doc(alias = "PERF_COUNT_HW_CACHE_MISSES")] + CacheMisses = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_CACHE_MISSES), + /// Number of retired branch instructions. + #[doc(alias = "PERF_COUNT_HW_BRANCH_INSTRUCTIONS")] + BranchInstructions = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_BRANCH_INSTRUCTIONS), + /// Number of mispredicted branch instructions. + #[doc(alias = "PERF_COUNT_HW_BRANCH_MISSES")] + BranchMisses = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_BRANCH_MISSES), + /// Number of bus cycles. + #[doc(alias = "PERF_COUNT_HW_BUS_CYCLES")] + BusCycles = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_BUS_CYCLES), + /// Number of stalled cycles during issue. + #[doc(alias = "PERF_COUNT_HW_STALLED_CYCLES_FRONTEND")] + StalledCyclesFrontend = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_STALLED_CYCLES_FRONTEND), + /// Number of stalled cycles during retirement. + #[doc(alias = "PERF_COUNT_HW_STALLED_CYCLES_BACKEND")] + StalledCyclesBackend = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_STALLED_CYCLES_BACKEND), + /// The total CPU cycles, which is not affected by CPU frequency scaling. + #[doc(alias = "PERF_COUNT_HW_REF_CPU_CYCLES")] + RefCpuCycles = perf_hw_id_to_u32(perf_hw_id::PERF_COUNT_HW_REF_CPU_CYCLES), +} + +impl HardwareEvent { + const fn into_primitive(self) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::()]; + self as u32 + } +} + +/// The software-defined events provided by the kernel. +#[doc(alias = "perf_sw_ids")] #[derive(Debug, Clone, Copy)] -pub enum PerfTypeId { - /// PERF_TYPE_HARDWARE - Hardware = PERF_TYPE_HARDWARE as u32, - /// PERF_TYPE_SOFTWARE - Software = PERF_TYPE_SOFTWARE as u32, - /// PERF_TYPE_TRACEPOINT - TracePoint = PERF_TYPE_TRACEPOINT as u32, - /// PERF_TYPE_HW_CACHE - HwCache = PERF_TYPE_HW_CACHE as u32, - /// PERF_TYPE_RAW - Raw = PERF_TYPE_RAW as u32, - /// PERF_TYPE_BREAKPOINT - Breakpoint = PERF_TYPE_BREAKPOINT as u32, +#[repr(u32)] +pub enum SoftwareEvent { + /// The CPU clock timer. + #[doc(alias = "PERF_COUNT_SW_CPU_CLOCK")] + CpuClock = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_CPU_CLOCK), + /// The clock count specific to the task that is running. + #[doc(alias = "PERF_COUNT_SW_TASK_CLOCK")] + TaskClock = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_TASK_CLOCK), + /// Number of page faults. + #[doc(alias = "PERF_COUNT_SW_PAGE_FAULTS")] + PageFaults = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_PAGE_FAULTS), + /// Numer of context switches. + #[doc(alias = "PERF_COUNT_SW_CONTEXT_SWITCHES")] + ContextSwitches = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_CONTEXT_SWITCHES), + /// Number of times the process has migrated to a new CPU. + #[doc(alias = "PERF_COUNT_SW_CPU_MIGRATIONS")] + CpuMigrations = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_CPU_MIGRATIONS), + /// Number of minor page faults. + #[doc(alias = "PERF_COUNT_SW_PAGE_FAULTS_MIN")] + PageFaultsMin = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_PAGE_FAULTS_MIN), + /// Number of major page faults. + #[doc(alias = "PERF_COUNT_SW_PAGE_FAULTS_MAJ")] + PageFaultsMaj = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_PAGE_FAULTS_MAJ), + /// Number of alignment faults. + #[doc(alias = "PERF_COUNT_SW_ALIGNMENT_FAULTS")] + AlignmentFaults = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_ALIGNMENT_FAULTS), + /// Number of emulation faults. + #[doc(alias = "PERF_COUNT_SW_EMULATION_FAULTS")] + EmulationFaults = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_EMULATION_FAULTS), + /// Placeholder event that counts nothing. + #[doc(alias = "PERF_COUNT_SW_DUMMY")] + Dummy = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_DUMMY), + /// Generates raw sample data from BPF. + #[doc(alias = "PERF_COUNT_SW_BPF_OUTPUT")] + BpfOutput = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_BPF_OUTPUT), + /// Number of context switches to a task when switching to a different cgroup. + #[doc(alias = "PERF_COUNT_SW_CGROUP_SWITCHES")] + CgroupSwitches = perf_sw_ids_to_u32(perf_sw_ids::PERF_COUNT_SW_CGROUP_SWITCHES), } -/// A hardware breakpoint configuration -#[derive(Debug, Clone)] -pub struct PerfBreakpoint { - /// The address to set the breakpoint on - pub address: u64, - /// The breakpoint size. For HwBreakpointX this must be sizeof(long). For - /// all other types it should be one of HwBreakpointLen1, HwBreakpointLen2,, - /// HwBreakpointLen4 or HwBreakpointLen8. - pub length: PerfBreakpointSize, - /// The breakpoint type, one of HW_BREAKPOINT_{R,W,RW,X} - pub type_: PerfBreakpointType, + +impl SoftwareEvent { + const fn into_primitive(self) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::()]; + self as u32 + } +} + +/// The hardware CPU cache events. +#[doc(alias = "perf_hw_cache_id")] +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +pub enum HwCacheEvent { + /// Measures Level 1 data cache. + #[doc(alias = "PERF_COUNT_HW_CACHE_L1D")] + L1d = perf_hw_cache_id_to_u32(perf_hw_cache_id::PERF_COUNT_HW_CACHE_L1D), + /// Measures Level 1 data cache. + #[doc(alias = "PERF_COUNT_HW_CACHE_L1I")] + L1i = perf_hw_cache_id_to_u32(perf_hw_cache_id::PERF_COUNT_HW_CACHE_L1I), + /// Measures Last-level cache. + #[doc(alias = "PERF_COUNT_HW_CACHE_LL")] + Ll = perf_hw_cache_id_to_u32(perf_hw_cache_id::PERF_COUNT_HW_CACHE_LL), + /// Measures Data TLB (Translation Lookaside Buffer). + #[doc(alias = "PERF_COUNT_HW_CACHE_DTLB")] + Dtlb = perf_hw_cache_id_to_u32(perf_hw_cache_id::PERF_COUNT_HW_CACHE_DTLB), + /// Measures Instruction TLB (Translation Lookaside Buffer). + #[doc(alias = "PERF_COUNT_HW_CACHE_ITLB")] + Itlb = perf_hw_cache_id_to_u32(perf_hw_cache_id::PERF_COUNT_HW_CACHE_ITLB), + /// Measures branch prediction. + #[doc(alias = "PERF_COUNT_HW_CACHE_BPU")] + Bpu = perf_hw_cache_id_to_u32(perf_hw_cache_id::PERF_COUNT_HW_CACHE_BPU), + /// Measures local memory accesses. + #[doc(alias = "PERF_COUNT_HW_CACHE_NODE")] + Node = perf_hw_cache_id_to_u32(perf_hw_cache_id::PERF_COUNT_HW_CACHE_NODE), +} + +impl HwCacheEvent { + const fn into_primitive(self) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::()]; + self as u32 + } +} + +/// The hardware CPU cache operations. +#[doc(alias = "perf_hw_cache_op_id")] +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +pub enum HwCacheOp { + /// Read access. + #[doc(alias = "PERF_COUNT_HW_CACHE_OP_READ")] + Read = perf_hw_cache_op_id_to_u32(perf_hw_cache_op_id::PERF_COUNT_HW_CACHE_OP_READ), + /// Write access. + #[doc(alias = "PERF_COUNT_HW_CACHE_OP_WRITE")] + Write = perf_hw_cache_op_id_to_u32(perf_hw_cache_op_id::PERF_COUNT_HW_CACHE_OP_WRITE), + /// Prefetch access. + #[doc(alias = "PERF_COUNT_HW_CACHE_OP_PREFETCH")] + Prefetch = perf_hw_cache_op_id_to_u32(perf_hw_cache_op_id::PERF_COUNT_HW_CACHE_OP_PREFETCH), +} + +impl HwCacheOp { + const fn into_primitive(self) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::()]; + self as u32 + } +} + +/// The hardware CPU cache result. +#[doc(alias = "perf_hw_cache_op_result_id")] +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +pub enum HwCacheResult { + /// Cache accesses. + #[doc(alias = "PERF_COUNT_HW_CACHE_RESULT_ACCESS")] + Access = perf_hw_cache_op_result_id_to_u32( + perf_hw_cache_op_result_id::PERF_COUNT_HW_CACHE_RESULT_ACCESS, + ), + /// Cache missed accesses. + #[doc(alias = "PERF_COUNT_HW_CACHE_RESULT_MISS")] + Miss = perf_hw_cache_op_result_id_to_u32( + perf_hw_cache_op_result_id::PERF_COUNT_HW_CACHE_RESULT_MISS, + ), +} + +impl HwCacheResult { + const fn into_primitive(self) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::()]; + self as u32 + } } /// Type of hardware breakpoint, determines if we break on read, write, or execute. @@ -62,39 +295,67 @@ pub struct PerfBreakpoint { #[derive(Debug, Clone, Copy)] pub enum PerfBreakpointType { /// HW_BREAKPOINT_EMPTY + #[doc(alias = "HW_BREAKPOINT_EMPTY")] HwBreakpointEmpty = HW_BREAKPOINT_EMPTY, /// HW_BREAKPOINT_R + #[doc(alias = "HW_BREAKPOINT_R")] HwBreakpointR = HW_BREAKPOINT_R, /// HW_BREAKPOINT_W + #[doc(alias = "HW_BREAKPOINT_W")] HwBreakpointW = HW_BREAKPOINT_W, /// HW_BREAKPOINT_RW + #[doc(alias = "HW_BREAKPOINT_RW")] HwBreakpointRW = HW_BREAKPOINT_RW, /// HW_BREAKPOINT_X + #[doc(alias = "HW_BREAKPOINT_X")] HwBreakpointX = HW_BREAKPOINT_X, /// HW_BREAKPOINT_INVALID + #[doc(alias = "HW_BREAKPOINT_INVALID")] HwBreakpointInvalid = HW_BREAKPOINT_INVALID, } +impl PerfBreakpointType { + pub(crate) const fn into_primitive(self) -> u32 { + const _: [(); 4] = [(); std::mem::size_of::()]; + self as u32 + } +} + /// The size of the breakpoint being measured -#[repr(u32)] +#[repr(u64)] #[derive(Debug, Clone, Copy)] pub enum PerfBreakpointSize { /// HW_BREAKPOINT_LEN_1 - HwBreakpointLen1 = HW_BREAKPOINT_LEN_1, + #[doc(alias = "HW_BREAKPOINT_LEN_1")] + HwBreakpointLen1 = HW_BREAKPOINT_LEN_1 as u64, /// HW_BREAKPOINT_LEN_2 - HwBreakpointLen2 = HW_BREAKPOINT_LEN_2, + #[doc(alias = "HW_BREAKPOINT_LEN_2")] + HwBreakpointLen2 = HW_BREAKPOINT_LEN_2 as u64, /// HW_BREAKPOINT_LEN_3 - HwBreakpointLen3 = HW_BREAKPOINT_LEN_3, + #[doc(alias = "HW_BREAKPOINT_LEN_3")] + HwBreakpointLen3 = HW_BREAKPOINT_LEN_3 as u64, /// HW_BREAKPOINT_LEN_4 - HwBreakpointLen4 = HW_BREAKPOINT_LEN_4, + #[doc(alias = "HW_BREAKPOINT_LEN_4")] + HwBreakpointLen4 = HW_BREAKPOINT_LEN_4 as u64, /// HW_BREAKPOINT_LEN_5 - HwBreakpointLen5 = HW_BREAKPOINT_LEN_5, + #[doc(alias = "HW_BREAKPOINT_LEN_5")] + HwBreakpointLen5 = HW_BREAKPOINT_LEN_5 as u64, /// HW_BREAKPOINT_LEN_6 - HwBreakpointLen6 = HW_BREAKPOINT_LEN_6, + #[doc(alias = "HW_BREAKPOINT_LEN_6")] + HwBreakpointLen6 = HW_BREAKPOINT_LEN_6 as u64, /// HW_BREAKPOINT_LEN_7 - HwBreakpointLen7 = HW_BREAKPOINT_LEN_7, + #[doc(alias = "HW_BREAKPOINT_LEN_7")] + HwBreakpointLen7 = HW_BREAKPOINT_LEN_7 as u64, /// HW_BREAKPOINT_LEN_8 - HwBreakpointLen8 = HW_BREAKPOINT_LEN_8, + #[doc(alias = "HW_BREAKPOINT_LEN_8")] + HwBreakpointLen8 = HW_BREAKPOINT_LEN_8 as u64, +} + +impl PerfBreakpointSize { + pub(crate) const fn into_primitive(self) -> u64 { + const _: [(); 8] = [(); std::mem::size_of::()]; + self as u64 + } } /// Sample Policy @@ -155,23 +416,24 @@ pub enum PerfEventScope { /// # #[error(transparent)] /// # Ebpf(#[from] aya::EbpfError) /// # } -/// # let mut bpf = aya::Ebpf::load(&[])?; -/// use aya::util::online_cpus; -/// use aya::programs::perf_event::{ -/// perf_sw_ids::PERF_COUNT_SW_CPU_CLOCK, PerfEvent, PerfEventScope, PerfTypeId, SamplePolicy, +/// use aya::{ +/// util::online_cpus, +/// programs::perf_event::{ +/// PerfEvent, PerfEventConfig, PerfEventScope, SamplePolicy, SoftwareEvent, +/// }, /// }; /// +/// # let mut bpf = aya::Ebpf::load(&[])?; /// let prog: &mut PerfEvent = bpf.program_mut("observe_cpu_clock").unwrap().try_into()?; /// prog.load()?; /// +/// let perf_type = PerfEventConfig::Software(SoftwareEvent::CpuClock); /// for cpu in online_cpus().map_err(|(_, error)| error)? { /// prog.attach( -/// PerfTypeId::Software, -/// PERF_COUNT_SW_CPU_CLOCK as u64, +/// perf_type, /// PerfEventScope::AllProcessesOneCpu { cpu }, /// SamplePolicy::Period(1000000), /// true, -/// None /// )?; /// } /// # Ok::<(), Error>(()) @@ -193,31 +455,54 @@ impl PerfEvent { /// Attaches to the given perf event. /// - /// The possible values and encoding of the `config` argument depends on the - /// `perf_type`. See `perf_sw_ids`, `perf_hw_id`, `perf_hw_cache_id`, - /// `perf_hw_cache_op_id` and `perf_hw_cache_op_result_id`. + /// [`perf_config`](PerfEventConfig) defines the event `type` and `config` of + /// interest. /// - /// The `bp` option must be specified if `perf_type` is `Breakpoint`. - /// - /// The `scope` argument determines which processes are sampled. If - /// `inherit` is true, any new processes spawned by those processes will - /// also automatically get sampled. + /// [`scope`](PerfEventScope) determines which processes are sampled. If + /// `inherit` is `true`, any new processes spawned by those processes will + /// also automatically be sampled. /// /// The returned value can be used to detach, see [PerfEvent::detach]. pub fn attach( &mut self, - perf_type: PerfTypeId, - config: u64, + perf_config: PerfEventConfig, scope: PerfEventScope, sample_policy: SamplePolicy, inherit: bool, - bp: Option, ) -> Result { - if matches!(perf_type, PerfTypeId::Breakpoint) && bp.is_none() { - return Err(ProgramError::IncompleteBreakpoint); - } let prog_fd = self.fd()?; let prog_fd = prog_fd.as_fd(); + + let (perf_type, config) = match perf_config { + PerfEventConfig::Pmu { pmu_type, config } => (pmu_type, config), + PerfEventConfig::Hardware(hw_event) => ( + perf_type_id_to_u32(PERF_TYPE_HARDWARE), + u64::from(hw_event.into_primitive()), + ), + PerfEventConfig::Software(sw_event) => ( + perf_type_id_to_u32(PERF_TYPE_SOFTWARE), + u64::from(sw_event.into_primitive()), + ), + PerfEventConfig::TracePoint { event_id } => { + (perf_type_id_to_u32(PERF_TYPE_TRACEPOINT), event_id) + } + PerfEventConfig::HwCache { + event, + operation, + result, + } => ( + perf_type_id_to_u32(PERF_TYPE_HW_CACHE), + u64::from(event.into_primitive()) + | (u64::from(operation.into_primitive()) << 8) + | (u64::from(result.into_primitive()) << 16), + ), + PerfEventConfig::Raw { event_id } => (perf_type_id_to_u32(PERF_TYPE_RAW), event_id), + PerfEventConfig::Breakpoint { + address: _, + length: _, + type_: _, + } => (perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), 0), + }; let (sample_period, sample_frequency) = match sample_policy { SamplePolicy::Period(period) => (period, None), SamplePolicy::Frequency(frequency) => (0, Some(frequency)), @@ -230,16 +515,17 @@ impl PerfEvent { PerfEventScope::AllProcessesOneCpu { cpu } => (-1, cpu as i32), }; let fd = perf_event_open( - perf_type as u32, + perf_type, config, pid, cpu, sample_period, sample_frequency, - matches!(perf_type, PerfTypeId::Breakpoint), + // wakeup=true for breakpoints, false for all other types + perf_type == perf_type_id_to_u32(PERF_TYPE_BREAKPOINT), inherit, 0, - bp, + Some(perf_config), ) .map_err(|io_error| SyscallError { call: "perf_event_open", diff --git a/aya/src/sys/perf_event.rs b/aya/src/sys/perf_event.rs index 19651b47..33941598 100644 --- a/aya/src/sys/perf_event.rs +++ b/aya/src/sys/perf_event.rs @@ -13,7 +13,7 @@ use aya_obj::generated::{ use libc::pid_t; use super::{PerfEventIoctlRequest, Syscall, syscall}; -use crate::programs::{PerfTypeId, perf_event::PerfBreakpoint}; +use crate::programs::perf_event::PerfEventConfig; #[expect(clippy::too_many_arguments)] pub(crate) fn perf_event_open( @@ -26,7 +26,7 @@ pub(crate) fn perf_event_open( wakeup: bool, inherit: bool, flags: u32, - bp: Option, + perf_config: Option, ) -> io::Result { let mut attr = unsafe { mem::zeroed::() }; @@ -44,18 +44,16 @@ pub(crate) fn perf_event_open( attr.__bindgen_anon_1.sample_period = sample_period; } - if perf_type == (PerfTypeId::Breakpoint as u32) { - if let Some(bp) = bp { - attr.bp_type = bp.type_ as u32; - attr.__bindgen_anon_3.bp_addr = bp.address; - attr.__bindgen_anon_4.bp_len = bp.length as u64; - attr.set_precise_ip(2); - } else { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "perf_type Breakpoint requires a PerfBreakpoint", - )); - } + if let Some(PerfEventConfig::Breakpoint { + address, + length, + type_, + }) = perf_config + { + attr.bp_type = type_.into_primitive(); + attr.__bindgen_anon_3.bp_addr = address; + attr.__bindgen_anon_4.bp_len = length.into_primitive(); + attr.set_precise_ip(2); } perf_event_sys(attr, pid, cpu, flags) diff --git a/test/integration-test/src/tests/perf_event_bp.rs b/test/integration-test/src/tests/perf_event_bp.rs index 699a4a54..bbeb86f2 100644 --- a/test/integration-test/src/tests/perf_event_bp.rs +++ b/test/integration-test/src/tests/perf_event_bp.rs @@ -6,10 +6,10 @@ use std::{ use aya::{ Ebpf, programs::{ - PerfEventScope, PerfTypeId, SamplePolicy, + PerfEventScope, SamplePolicy, perf_event::{ - PerfBreakpoint, PerfBreakpointSize::HwBreakpointLen1, - PerfBreakpointType::HwBreakpointRW, + PerfBreakpointSize::HwBreakpointLen1, PerfBreakpointType::HwBreakpointRW, + PerfEventConfig, }, }, util::online_cpus, @@ -95,16 +95,14 @@ fn perf_event_bp() { for cpu in online_cpus().unwrap() { info!("attaching to cpu {cpu}"); prog.attach( - PerfTypeId::Breakpoint, - 0u64, - PerfEventScope::AllProcessesOneCpu { cpu }, - SamplePolicy::Period(1), - true, - Some(PerfBreakpoint { + PerfEventConfig::Breakpoint { address: attach_addr, length: HwBreakpointLen1, type_: HwBreakpointRW, - }), + }, + PerfEventScope::AllProcessesOneCpu { cpu }, + SamplePolicy::Period(1), + true, ) .unwrap(); } diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 87a2d43e..2390f95d 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -5293,12 +5293,165 @@ pub fn aya::programs::perf_attach::PerfLinkId::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::perf_attach::PerfLinkId pub fn aya::programs::perf_attach::PerfLinkId::from(t: T) -> T pub mod aya::programs::perf_event -pub use aya::programs::perf_event::perf_hw_cache_id -pub use aya::programs::perf_event::perf_hw_cache_op_id -pub use aya::programs::perf_event::perf_hw_cache_op_result_id -pub use aya::programs::perf_event::perf_hw_id -pub use aya::programs::perf_event::perf_sw_ids -#[repr(u32)] pub enum aya::programs::perf_event::PerfBreakpointSize +#[repr(u32)] pub enum aya::programs::perf_event::HardwareEvent +pub aya::programs::perf_event::HardwareEvent::BranchInstructions = 4 +pub aya::programs::perf_event::HardwareEvent::BranchMisses = 5 +pub aya::programs::perf_event::HardwareEvent::BusCycles = 6 +pub aya::programs::perf_event::HardwareEvent::CacheMisses = 3 +pub aya::programs::perf_event::HardwareEvent::CacheReferences = 2 +pub aya::programs::perf_event::HardwareEvent::CpuCycles = 0 +pub aya::programs::perf_event::HardwareEvent::Instructions = 1 +pub aya::programs::perf_event::HardwareEvent::RefCpuCycles = 9 +pub aya::programs::perf_event::HardwareEvent::StalledCyclesBackend = 8 +pub aya::programs::perf_event::HardwareEvent::StalledCyclesFrontend = 7 +impl core::clone::Clone for aya::programs::perf_event::HardwareEvent +pub fn aya::programs::perf_event::HardwareEvent::clone(&self) -> aya::programs::perf_event::HardwareEvent +impl core::fmt::Debug for aya::programs::perf_event::HardwareEvent +pub fn aya::programs::perf_event::HardwareEvent::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::HardwareEvent +impl core::marker::Freeze for aya::programs::perf_event::HardwareEvent +impl core::marker::Send for aya::programs::perf_event::HardwareEvent +impl core::marker::Sync for aya::programs::perf_event::HardwareEvent +impl core::marker::Unpin for aya::programs::perf_event::HardwareEvent +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::HardwareEvent +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::HardwareEvent +impl core::convert::Into for aya::programs::perf_event::HardwareEvent where U: core::convert::From +pub fn aya::programs::perf_event::HardwareEvent::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::HardwareEvent where U: core::convert::Into +pub type aya::programs::perf_event::HardwareEvent::Error = core::convert::Infallible +pub fn aya::programs::perf_event::HardwareEvent::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::HardwareEvent where U: core::convert::TryFrom +pub type aya::programs::perf_event::HardwareEvent::Error = >::Error +pub fn aya::programs::perf_event::HardwareEvent::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::HardwareEvent where T: core::clone::Clone +pub type aya::programs::perf_event::HardwareEvent::Owned = T +pub fn aya::programs::perf_event::HardwareEvent::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::HardwareEvent::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::HardwareEvent where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::HardwareEvent::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::HardwareEvent where T: ?core::marker::Sized +pub fn aya::programs::perf_event::HardwareEvent::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::HardwareEvent where T: ?core::marker::Sized +pub fn aya::programs::perf_event::HardwareEvent::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::HardwareEvent where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::HardwareEvent::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::HardwareEvent +pub fn aya::programs::perf_event::HardwareEvent::from(t: T) -> T +#[repr(u32)] pub enum aya::programs::perf_event::HwCacheEvent +pub aya::programs::perf_event::HwCacheEvent::Bpu = 5 +pub aya::programs::perf_event::HwCacheEvent::Dtlb = 3 +pub aya::programs::perf_event::HwCacheEvent::Itlb = 4 +pub aya::programs::perf_event::HwCacheEvent::L1d = 0 +pub aya::programs::perf_event::HwCacheEvent::L1i = 1 +pub aya::programs::perf_event::HwCacheEvent::Ll = 2 +pub aya::programs::perf_event::HwCacheEvent::Node = 6 +impl core::clone::Clone for aya::programs::perf_event::HwCacheEvent +pub fn aya::programs::perf_event::HwCacheEvent::clone(&self) -> aya::programs::perf_event::HwCacheEvent +impl core::fmt::Debug for aya::programs::perf_event::HwCacheEvent +pub fn aya::programs::perf_event::HwCacheEvent::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::HwCacheEvent +impl core::marker::Freeze for aya::programs::perf_event::HwCacheEvent +impl core::marker::Send for aya::programs::perf_event::HwCacheEvent +impl core::marker::Sync for aya::programs::perf_event::HwCacheEvent +impl core::marker::Unpin for aya::programs::perf_event::HwCacheEvent +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::HwCacheEvent +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::HwCacheEvent +impl core::convert::Into for aya::programs::perf_event::HwCacheEvent where U: core::convert::From +pub fn aya::programs::perf_event::HwCacheEvent::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::HwCacheEvent where U: core::convert::Into +pub type aya::programs::perf_event::HwCacheEvent::Error = core::convert::Infallible +pub fn aya::programs::perf_event::HwCacheEvent::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::HwCacheEvent where U: core::convert::TryFrom +pub type aya::programs::perf_event::HwCacheEvent::Error = >::Error +pub fn aya::programs::perf_event::HwCacheEvent::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::HwCacheEvent where T: core::clone::Clone +pub type aya::programs::perf_event::HwCacheEvent::Owned = T +pub fn aya::programs::perf_event::HwCacheEvent::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::HwCacheEvent::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::HwCacheEvent where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheEvent::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::HwCacheEvent where T: ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheEvent::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::HwCacheEvent where T: ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheEvent::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::HwCacheEvent where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::HwCacheEvent::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::HwCacheEvent +pub fn aya::programs::perf_event::HwCacheEvent::from(t: T) -> T +#[repr(u32)] pub enum aya::programs::perf_event::HwCacheOp +pub aya::programs::perf_event::HwCacheOp::Prefetch = 2 +pub aya::programs::perf_event::HwCacheOp::Read = 0 +pub aya::programs::perf_event::HwCacheOp::Write = 1 +impl core::clone::Clone for aya::programs::perf_event::HwCacheOp +pub fn aya::programs::perf_event::HwCacheOp::clone(&self) -> aya::programs::perf_event::HwCacheOp +impl core::fmt::Debug for aya::programs::perf_event::HwCacheOp +pub fn aya::programs::perf_event::HwCacheOp::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::HwCacheOp +impl core::marker::Freeze for aya::programs::perf_event::HwCacheOp +impl core::marker::Send for aya::programs::perf_event::HwCacheOp +impl core::marker::Sync for aya::programs::perf_event::HwCacheOp +impl core::marker::Unpin for aya::programs::perf_event::HwCacheOp +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::HwCacheOp +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::HwCacheOp +impl core::convert::Into for aya::programs::perf_event::HwCacheOp where U: core::convert::From +pub fn aya::programs::perf_event::HwCacheOp::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::HwCacheOp where U: core::convert::Into +pub type aya::programs::perf_event::HwCacheOp::Error = core::convert::Infallible +pub fn aya::programs::perf_event::HwCacheOp::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::HwCacheOp where U: core::convert::TryFrom +pub type aya::programs::perf_event::HwCacheOp::Error = >::Error +pub fn aya::programs::perf_event::HwCacheOp::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::HwCacheOp where T: core::clone::Clone +pub type aya::programs::perf_event::HwCacheOp::Owned = T +pub fn aya::programs::perf_event::HwCacheOp::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::HwCacheOp::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::HwCacheOp where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheOp::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::HwCacheOp where T: ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheOp::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::HwCacheOp where T: ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheOp::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::HwCacheOp where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::HwCacheOp::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::HwCacheOp +pub fn aya::programs::perf_event::HwCacheOp::from(t: T) -> T +#[repr(u32)] pub enum aya::programs::perf_event::HwCacheResult +pub aya::programs::perf_event::HwCacheResult::Access = 0 +pub aya::programs::perf_event::HwCacheResult::Miss = 1 +impl core::clone::Clone for aya::programs::perf_event::HwCacheResult +pub fn aya::programs::perf_event::HwCacheResult::clone(&self) -> aya::programs::perf_event::HwCacheResult +impl core::fmt::Debug for aya::programs::perf_event::HwCacheResult +pub fn aya::programs::perf_event::HwCacheResult::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::HwCacheResult +impl core::marker::Freeze for aya::programs::perf_event::HwCacheResult +impl core::marker::Send for aya::programs::perf_event::HwCacheResult +impl core::marker::Sync for aya::programs::perf_event::HwCacheResult +impl core::marker::Unpin for aya::programs::perf_event::HwCacheResult +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::HwCacheResult +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::HwCacheResult +impl core::convert::Into for aya::programs::perf_event::HwCacheResult where U: core::convert::From +pub fn aya::programs::perf_event::HwCacheResult::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::HwCacheResult where U: core::convert::Into +pub type aya::programs::perf_event::HwCacheResult::Error = core::convert::Infallible +pub fn aya::programs::perf_event::HwCacheResult::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::HwCacheResult where U: core::convert::TryFrom +pub type aya::programs::perf_event::HwCacheResult::Error = >::Error +pub fn aya::programs::perf_event::HwCacheResult::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::HwCacheResult where T: core::clone::Clone +pub type aya::programs::perf_event::HwCacheResult::Owned = T +pub fn aya::programs::perf_event::HwCacheResult::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::HwCacheResult::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::HwCacheResult where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheResult::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::HwCacheResult where T: ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheResult::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::HwCacheResult where T: ?core::marker::Sized +pub fn aya::programs::perf_event::HwCacheResult::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::HwCacheResult where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::HwCacheResult::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::HwCacheResult +pub fn aya::programs::perf_event::HwCacheResult::from(t: T) -> T +#[repr(u64)] pub enum aya::programs::perf_event::PerfBreakpointSize pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen1 = 1 pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen2 = 2 pub aya::programs::perf_event::PerfBreakpointSize::HwBreakpointLen3 = 3 @@ -5380,6 +5533,57 @@ impl core::clone::CloneToUninit for aya::programs::perf_event::PerfBreakpoint pub unsafe fn aya::programs::perf_event::PerfBreakpointType::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya::programs::perf_event::PerfBreakpointType pub fn aya::programs::perf_event::PerfBreakpointType::from(t: T) -> T +pub enum aya::programs::perf_event::PerfEventConfig +pub aya::programs::perf_event::PerfEventConfig::Breakpoint +pub aya::programs::perf_event::PerfEventConfig::Breakpoint::address: u64 +pub aya::programs::perf_event::PerfEventConfig::Breakpoint::length: aya::programs::perf_event::PerfBreakpointSize +pub aya::programs::perf_event::PerfEventConfig::Breakpoint::type_: aya::programs::perf_event::PerfBreakpointType +pub aya::programs::perf_event::PerfEventConfig::Hardware(aya::programs::perf_event::HardwareEvent) +pub aya::programs::perf_event::PerfEventConfig::HwCache +pub aya::programs::perf_event::PerfEventConfig::HwCache::event: aya::programs::perf_event::HwCacheEvent +pub aya::programs::perf_event::PerfEventConfig::HwCache::operation: aya::programs::perf_event::HwCacheOp +pub aya::programs::perf_event::PerfEventConfig::HwCache::result: aya::programs::perf_event::HwCacheResult +pub aya::programs::perf_event::PerfEventConfig::Pmu +pub aya::programs::perf_event::PerfEventConfig::Pmu::config: u64 +pub aya::programs::perf_event::PerfEventConfig::Pmu::pmu_type: u32 +pub aya::programs::perf_event::PerfEventConfig::Raw +pub aya::programs::perf_event::PerfEventConfig::Raw::event_id: u64 +pub aya::programs::perf_event::PerfEventConfig::Software(aya::programs::perf_event::SoftwareEvent) +pub aya::programs::perf_event::PerfEventConfig::TracePoint +pub aya::programs::perf_event::PerfEventConfig::TracePoint::event_id: u64 +impl core::clone::Clone for aya::programs::perf_event::PerfEventConfig +pub fn aya::programs::perf_event::PerfEventConfig::clone(&self) -> aya::programs::perf_event::PerfEventConfig +impl core::fmt::Debug for aya::programs::perf_event::PerfEventConfig +pub fn aya::programs::perf_event::PerfEventConfig::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::PerfEventConfig +impl core::marker::Freeze for aya::programs::perf_event::PerfEventConfig +impl core::marker::Send for aya::programs::perf_event::PerfEventConfig +impl core::marker::Sync for aya::programs::perf_event::PerfEventConfig +impl core::marker::Unpin for aya::programs::perf_event::PerfEventConfig +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfEventConfig +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfEventConfig +impl core::convert::Into for aya::programs::perf_event::PerfEventConfig where U: core::convert::From +pub fn aya::programs::perf_event::PerfEventConfig::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::PerfEventConfig where U: core::convert::Into +pub type aya::programs::perf_event::PerfEventConfig::Error = core::convert::Infallible +pub fn aya::programs::perf_event::PerfEventConfig::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::PerfEventConfig where U: core::convert::TryFrom +pub type aya::programs::perf_event::PerfEventConfig::Error = >::Error +pub fn aya::programs::perf_event::PerfEventConfig::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::PerfEventConfig where T: core::clone::Clone +pub type aya::programs::perf_event::PerfEventConfig::Owned = T +pub fn aya::programs::perf_event::PerfEventConfig::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::PerfEventConfig::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::PerfEventConfig where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::PerfEventConfig::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::PerfEventConfig where T: ?core::marker::Sized +pub fn aya::programs::perf_event::PerfEventConfig::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::PerfEventConfig where T: ?core::marker::Sized +pub fn aya::programs::perf_event::PerfEventConfig::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::PerfEventConfig where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::PerfEventConfig::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::PerfEventConfig +pub fn aya::programs::perf_event::PerfEventConfig::from(t: T) -> T pub enum aya::programs::perf_event::PerfEventScope pub aya::programs::perf_event::PerfEventScope::AllProcessesOneCpu pub aya::programs::perf_event::PerfEventScope::AllProcessesOneCpu::cpu: u32 @@ -5423,46 +5627,6 @@ impl core::clone::CloneToUninit for aya::programs::perf_event::PerfEventScope pub unsafe fn aya::programs::perf_event::PerfEventScope::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya::programs::perf_event::PerfEventScope pub fn aya::programs::perf_event::PerfEventScope::from(t: T) -> T -#[repr(u32)] pub enum aya::programs::perf_event::PerfTypeId -pub aya::programs::perf_event::PerfTypeId::Breakpoint = 5 -pub aya::programs::perf_event::PerfTypeId::Hardware = 0 -pub aya::programs::perf_event::PerfTypeId::HwCache = 3 -pub aya::programs::perf_event::PerfTypeId::Raw = 4 -pub aya::programs::perf_event::PerfTypeId::Software = 1 -pub aya::programs::perf_event::PerfTypeId::TracePoint = 2 -impl core::clone::Clone for aya::programs::perf_event::PerfTypeId -pub fn aya::programs::perf_event::PerfTypeId::clone(&self) -> aya::programs::perf_event::PerfTypeId -impl core::fmt::Debug for aya::programs::perf_event::PerfTypeId -pub fn aya::programs::perf_event::PerfTypeId::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Copy for aya::programs::perf_event::PerfTypeId -impl core::marker::Freeze for aya::programs::perf_event::PerfTypeId -impl core::marker::Send for aya::programs::perf_event::PerfTypeId -impl core::marker::Sync for aya::programs::perf_event::PerfTypeId -impl core::marker::Unpin for aya::programs::perf_event::PerfTypeId -impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfTypeId -impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfTypeId -impl core::convert::Into for aya::programs::perf_event::PerfTypeId where U: core::convert::From -pub fn aya::programs::perf_event::PerfTypeId::into(self) -> U -impl core::convert::TryFrom for aya::programs::perf_event::PerfTypeId where U: core::convert::Into -pub type aya::programs::perf_event::PerfTypeId::Error = core::convert::Infallible -pub fn aya::programs::perf_event::PerfTypeId::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya::programs::perf_event::PerfTypeId where U: core::convert::TryFrom -pub type aya::programs::perf_event::PerfTypeId::Error = >::Error -pub fn aya::programs::perf_event::PerfTypeId::try_into(self) -> core::result::Result>::Error> -impl alloc::borrow::ToOwned for aya::programs::perf_event::PerfTypeId where T: core::clone::Clone -pub type aya::programs::perf_event::PerfTypeId::Owned = T -pub fn aya::programs::perf_event::PerfTypeId::clone_into(&self, target: &mut T) -pub fn aya::programs::perf_event::PerfTypeId::to_owned(&self) -> T -impl core::any::Any for aya::programs::perf_event::PerfTypeId where T: 'static + ?core::marker::Sized -pub fn aya::programs::perf_event::PerfTypeId::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya::programs::perf_event::PerfTypeId where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfTypeId::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya::programs::perf_event::PerfTypeId where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfTypeId::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for aya::programs::perf_event::PerfTypeId where T: core::clone::Clone -pub unsafe fn aya::programs::perf_event::PerfTypeId::clone_to_uninit(&self, dest: *mut u8) -impl core::convert::From for aya::programs::perf_event::PerfTypeId -pub fn aya::programs::perf_event::PerfTypeId::from(t: T) -> T pub enum aya::programs::perf_event::SamplePolicy pub aya::programs::perf_event::SamplePolicy::Frequency(u64) pub aya::programs::perf_event::SamplePolicy::Period(u64) @@ -5498,46 +5662,56 @@ impl core::clone::CloneToUninit for aya::programs::perf_event::SamplePolicy w pub unsafe fn aya::programs::perf_event::SamplePolicy::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya::programs::perf_event::SamplePolicy pub fn aya::programs::perf_event::SamplePolicy::from(t: T) -> T -pub struct aya::programs::perf_event::PerfBreakpoint -pub aya::programs::perf_event::PerfBreakpoint::address: u64 -pub aya::programs::perf_event::PerfBreakpoint::length: aya::programs::perf_event::PerfBreakpointSize -pub aya::programs::perf_event::PerfBreakpoint::type_: aya::programs::perf_event::PerfBreakpointType -impl core::clone::Clone for aya::programs::perf_event::PerfBreakpoint -pub fn aya::programs::perf_event::PerfBreakpoint::clone(&self) -> aya::programs::perf_event::PerfBreakpoint -impl core::fmt::Debug for aya::programs::perf_event::PerfBreakpoint -pub fn aya::programs::perf_event::PerfBreakpoint::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Freeze for aya::programs::perf_event::PerfBreakpoint -impl core::marker::Send for aya::programs::perf_event::PerfBreakpoint -impl core::marker::Sync for aya::programs::perf_event::PerfBreakpoint -impl core::marker::Unpin for aya::programs::perf_event::PerfBreakpoint -impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfBreakpoint -impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfBreakpoint -impl core::convert::Into for aya::programs::perf_event::PerfBreakpoint where U: core::convert::From -pub fn aya::programs::perf_event::PerfBreakpoint::into(self) -> U -impl core::convert::TryFrom for aya::programs::perf_event::PerfBreakpoint where U: core::convert::Into -pub type aya::programs::perf_event::PerfBreakpoint::Error = core::convert::Infallible -pub fn aya::programs::perf_event::PerfBreakpoint::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya::programs::perf_event::PerfBreakpoint where U: core::convert::TryFrom -pub type aya::programs::perf_event::PerfBreakpoint::Error = >::Error -pub fn aya::programs::perf_event::PerfBreakpoint::try_into(self) -> core::result::Result>::Error> -impl alloc::borrow::ToOwned for aya::programs::perf_event::PerfBreakpoint where T: core::clone::Clone -pub type aya::programs::perf_event::PerfBreakpoint::Owned = T -pub fn aya::programs::perf_event::PerfBreakpoint::clone_into(&self, target: &mut T) -pub fn aya::programs::perf_event::PerfBreakpoint::to_owned(&self) -> T -impl core::any::Any for aya::programs::perf_event::PerfBreakpoint where T: 'static + ?core::marker::Sized -pub fn aya::programs::perf_event::PerfBreakpoint::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya::programs::perf_event::PerfBreakpoint where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfBreakpoint::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya::programs::perf_event::PerfBreakpoint where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfBreakpoint::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for aya::programs::perf_event::PerfBreakpoint where T: core::clone::Clone -pub unsafe fn aya::programs::perf_event::PerfBreakpoint::clone_to_uninit(&self, dest: *mut u8) -impl core::convert::From for aya::programs::perf_event::PerfBreakpoint -pub fn aya::programs::perf_event::PerfBreakpoint::from(t: T) -> T +#[repr(u32)] pub enum aya::programs::perf_event::SoftwareEvent +pub aya::programs::perf_event::SoftwareEvent::AlignmentFaults = 7 +pub aya::programs::perf_event::SoftwareEvent::BpfOutput = 10 +pub aya::programs::perf_event::SoftwareEvent::CgroupSwitches = 11 +pub aya::programs::perf_event::SoftwareEvent::ContextSwitches = 3 +pub aya::programs::perf_event::SoftwareEvent::CpuClock = 0 +pub aya::programs::perf_event::SoftwareEvent::CpuMigrations = 4 +pub aya::programs::perf_event::SoftwareEvent::Dummy = 9 +pub aya::programs::perf_event::SoftwareEvent::EmulationFaults = 8 +pub aya::programs::perf_event::SoftwareEvent::PageFaults = 2 +pub aya::programs::perf_event::SoftwareEvent::PageFaultsMaj = 6 +pub aya::programs::perf_event::SoftwareEvent::PageFaultsMin = 5 +pub aya::programs::perf_event::SoftwareEvent::TaskClock = 1 +impl core::clone::Clone for aya::programs::perf_event::SoftwareEvent +pub fn aya::programs::perf_event::SoftwareEvent::clone(&self) -> aya::programs::perf_event::SoftwareEvent +impl core::fmt::Debug for aya::programs::perf_event::SoftwareEvent +pub fn aya::programs::perf_event::SoftwareEvent::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya::programs::perf_event::SoftwareEvent +impl core::marker::Freeze for aya::programs::perf_event::SoftwareEvent +impl core::marker::Send for aya::programs::perf_event::SoftwareEvent +impl core::marker::Sync for aya::programs::perf_event::SoftwareEvent +impl core::marker::Unpin for aya::programs::perf_event::SoftwareEvent +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::SoftwareEvent +impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::SoftwareEvent +impl core::convert::Into for aya::programs::perf_event::SoftwareEvent where U: core::convert::From +pub fn aya::programs::perf_event::SoftwareEvent::into(self) -> U +impl core::convert::TryFrom for aya::programs::perf_event::SoftwareEvent where U: core::convert::Into +pub type aya::programs::perf_event::SoftwareEvent::Error = core::convert::Infallible +pub fn aya::programs::perf_event::SoftwareEvent::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::perf_event::SoftwareEvent where U: core::convert::TryFrom +pub type aya::programs::perf_event::SoftwareEvent::Error = >::Error +pub fn aya::programs::perf_event::SoftwareEvent::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya::programs::perf_event::SoftwareEvent where T: core::clone::Clone +pub type aya::programs::perf_event::SoftwareEvent::Owned = T +pub fn aya::programs::perf_event::SoftwareEvent::clone_into(&self, target: &mut T) +pub fn aya::programs::perf_event::SoftwareEvent::to_owned(&self) -> T +impl core::any::Any for aya::programs::perf_event::SoftwareEvent where T: 'static + ?core::marker::Sized +pub fn aya::programs::perf_event::SoftwareEvent::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::perf_event::SoftwareEvent where T: ?core::marker::Sized +pub fn aya::programs::perf_event::SoftwareEvent::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::perf_event::SoftwareEvent where T: ?core::marker::Sized +pub fn aya::programs::perf_event::SoftwareEvent::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for aya::programs::perf_event::SoftwareEvent where T: core::clone::Clone +pub unsafe fn aya::programs::perf_event::SoftwareEvent::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for aya::programs::perf_event::SoftwareEvent +pub fn aya::programs::perf_event::SoftwareEvent::from(t: T) -> T pub struct aya::programs::perf_event::PerfEvent impl aya::programs::perf_event::PerfEvent pub const aya::programs::perf_event::PerfEvent::PROGRAM_TYPE: aya::programs::ProgramType -pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfTypeId, config: u64, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool, bp: core::option::Option) -> core::result::Result +pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_config: aya::programs::perf_event::PerfEventConfig, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError> impl aya::programs::perf_event::PerfEvent pub fn aya::programs::perf_event::PerfEvent::detach(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<(), aya::programs::ProgramError> @@ -7852,46 +8026,6 @@ impl core::clone::CloneToUninit for aya::programs::perf_event::PerfEventScope pub unsafe fn aya::programs::perf_event::PerfEventScope::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya::programs::perf_event::PerfEventScope pub fn aya::programs::perf_event::PerfEventScope::from(t: T) -> T -#[repr(u32)] pub enum aya::programs::PerfTypeId -pub aya::programs::PerfTypeId::Breakpoint = 5 -pub aya::programs::PerfTypeId::Hardware = 0 -pub aya::programs::PerfTypeId::HwCache = 3 -pub aya::programs::PerfTypeId::Raw = 4 -pub aya::programs::PerfTypeId::Software = 1 -pub aya::programs::PerfTypeId::TracePoint = 2 -impl core::clone::Clone for aya::programs::perf_event::PerfTypeId -pub fn aya::programs::perf_event::PerfTypeId::clone(&self) -> aya::programs::perf_event::PerfTypeId -impl core::fmt::Debug for aya::programs::perf_event::PerfTypeId -pub fn aya::programs::perf_event::PerfTypeId::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Copy for aya::programs::perf_event::PerfTypeId -impl core::marker::Freeze for aya::programs::perf_event::PerfTypeId -impl core::marker::Send for aya::programs::perf_event::PerfTypeId -impl core::marker::Sync for aya::programs::perf_event::PerfTypeId -impl core::marker::Unpin for aya::programs::perf_event::PerfTypeId -impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::perf_event::PerfTypeId -impl core::panic::unwind_safe::UnwindSafe for aya::programs::perf_event::PerfTypeId -impl core::convert::Into for aya::programs::perf_event::PerfTypeId where U: core::convert::From -pub fn aya::programs::perf_event::PerfTypeId::into(self) -> U -impl core::convert::TryFrom for aya::programs::perf_event::PerfTypeId where U: core::convert::Into -pub type aya::programs::perf_event::PerfTypeId::Error = core::convert::Infallible -pub fn aya::programs::perf_event::PerfTypeId::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for aya::programs::perf_event::PerfTypeId where U: core::convert::TryFrom -pub type aya::programs::perf_event::PerfTypeId::Error = >::Error -pub fn aya::programs::perf_event::PerfTypeId::try_into(self) -> core::result::Result>::Error> -impl alloc::borrow::ToOwned for aya::programs::perf_event::PerfTypeId where T: core::clone::Clone -pub type aya::programs::perf_event::PerfTypeId::Owned = T -pub fn aya::programs::perf_event::PerfTypeId::clone_into(&self, target: &mut T) -pub fn aya::programs::perf_event::PerfTypeId::to_owned(&self) -> T -impl core::any::Any for aya::programs::perf_event::PerfTypeId where T: 'static + ?core::marker::Sized -pub fn aya::programs::perf_event::PerfTypeId::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for aya::programs::perf_event::PerfTypeId where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfTypeId::borrow(&self) -> &T -impl core::borrow::BorrowMut for aya::programs::perf_event::PerfTypeId where T: ?core::marker::Sized -pub fn aya::programs::perf_event::PerfTypeId::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for aya::programs::perf_event::PerfTypeId where T: core::clone::Clone -pub unsafe fn aya::programs::perf_event::PerfTypeId::clone_to_uninit(&self, dest: *mut u8) -impl core::convert::From for aya::programs::perf_event::PerfTypeId -pub fn aya::programs::perf_event::PerfTypeId::from(t: T) -> T pub enum aya::programs::ProbeKind pub aya::programs::ProbeKind::KProbe pub aya::programs::ProbeKind::KRetProbe @@ -9490,7 +9624,7 @@ pub fn aya::programs::lsm_cgroup::LsmCgroup::from(t: T) -> T pub struct aya::programs::PerfEvent impl aya::programs::perf_event::PerfEvent pub const aya::programs::perf_event::PerfEvent::PROGRAM_TYPE: aya::programs::ProgramType -pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfTypeId, config: u64, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool, bp: core::option::Option) -> core::result::Result +pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_config: aya::programs::perf_event::PerfEventConfig, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError> impl aya::programs::perf_event::PerfEvent pub fn aya::programs::perf_event::PerfEvent::detach(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<(), aya::programs::ProgramError>