From c5be26776b5649707fd24b99bd82a1b9c8b77260 Mon Sep 17 00:00:00 2001
From: Tyrone Wu <wudevelops@gmail.com>
Date: Tue, 8 Oct 2024 17:45:28 +0000
Subject: [PATCH] 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.
---
 aya/src/programs/mod.rs        |   2 +-
 aya/src/programs/perf_event.rs | 259 +++++++++++++++++++++----
 xtask/public-api/aya.txt       | 338 ++++++++++++++++++++++++---------
 3 files changed, 480 insertions(+), 119 deletions(-)

diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs
index 00d61b01..ae106f90 100644
--- a/aya/src/programs/mod.rs
+++ b/aya/src/programs/mod.rs
@@ -98,7 +98,7 @@ pub use crate::programs::{
     links::{CgroupAttachMode, Link, LinkOrder},
     lirc_mode2::LircMode2,
     lsm::Lsm,
-    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 587d6499..b3905fa4 100644
--- a/aya/src/programs/perf_event.rs
+++ b/aya/src/programs/perf_event.rs
@@ -2,13 +2,11 @@
 
 use std::os::fd::AsFd as _;
 
-pub use crate::generated::{
-    perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids,
-};
 use crate::{
     generated::{
         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_BREAKPOINT, PERF_TYPE_HARDWARE, PERF_TYPE_HW_CACHE, PERF_TYPE_RAW,
             PERF_TYPE_SOFTWARE, PERF_TYPE_TRACEPOINT,
@@ -23,22 +21,195 @@ use crate::{
     sys::{bpf_link_get_info_by_fd, perf_event_open, SyscallError},
 };
 
-/// The type of perf event
-#[repr(u32)]
+/// The type of perf event and their respective configuration.
+#[doc(alias = "perf_type_id")]
 #[derive(Debug, Clone)]
-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,
+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.
+    ///
+    /// Note: this variant is not fully implemented at the moment.
+    // TODO: Variant not fully implemented due to additional `perf_event_attr` fields like
+    //       `bp_type`, `bp_addr`, etc.
+    #[doc(alias = "PERF_TYPE_BREAKPOINT")]
+    Breakpoint,
+    /// 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:<value>` indicates the bit position to set.
+        ///
+        /// For example, `config:3` => `config = 1 << 3`.
+        config: u64,
+    },
+}
+
+/// The "generalized" hardware CPU events provided by the kernel.
+#[doc(alias = "perf_hw_id")]
+#[derive(Debug, Clone, Copy)]
+pub enum HardwareEvent {
+    /// The total CPU cycles.
+    #[doc(alias = "PERF_COUNT_HW_CPU_CYCLES")]
+    CpuCycles = perf_hw_id::PERF_COUNT_HW_CPU_CYCLES as isize,
+    /// Number of retired instructions.
+    #[doc(alias = "PERF_COUNT_HW_INSTRUCTIONS")]
+    Instructions = perf_hw_id::PERF_COUNT_HW_INSTRUCTIONS as isize,
+    /// Number of cache accesses.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_REFERENCES")]
+    CacheReferences = perf_hw_id::PERF_COUNT_HW_CACHE_REFERENCES as isize,
+    /// Number of cache misses.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_MISSES")]
+    CacheMisses = perf_hw_id::PERF_COUNT_HW_CACHE_MISSES as isize,
+    /// Number of retired branch instructions.
+    #[doc(alias = "PERF_COUNT_HW_BRANCH_INSTRUCTIONS")]
+    BranchInstructions = perf_hw_id::PERF_COUNT_HW_BRANCH_INSTRUCTIONS as isize,
+    /// Number of mispredicted branch instructions.
+    #[doc(alias = "PERF_COUNT_HW_BRANCH_MISSES")]
+    BranchMisses = perf_hw_id::PERF_COUNT_HW_BRANCH_MISSES as isize,
+    /// Number of bus cycles.
+    #[doc(alias = "PERF_COUNT_HW_BUS_CYCLES")]
+    BusCycles = perf_hw_id::PERF_COUNT_HW_BUS_CYCLES as isize,
+    /// Number of stalled cycles during issue.
+    #[doc(alias = "PERF_COUNT_HW_STALLED_CYCLES_FRONTEND")]
+    StalledCyclesFrontend = perf_hw_id::PERF_COUNT_HW_STALLED_CYCLES_FRONTEND as isize,
+    /// Number of stalled cycles during retirement.
+    #[doc(alias = "PERF_COUNT_HW_STALLED_CYCLES_BACKEND")]
+    StalledCyclesBackend = perf_hw_id::PERF_COUNT_HW_STALLED_CYCLES_BACKEND as isize,
+    /// The total CPU cycles, which is not affected by CPU frequency scaling.
+    #[doc(alias = "PERF_COUNT_HW_REF_CPU_CYCLES")]
+    RefCpuCycles = perf_hw_id::PERF_COUNT_HW_REF_CPU_CYCLES as isize,
+}
+
+/// The software-defined events provided by the kernel.
+#[doc(alias = "perf_sw_ids")]
+#[derive(Debug, Clone, Copy)]
+pub enum SoftwareEvent {
+    /// The CPU clock timer.
+    #[doc(alias = "PERF_COUNT_SW_CPU_CLOCK")]
+    CpuClock = perf_sw_ids::PERF_COUNT_SW_CPU_CLOCK as isize,
+    /// The clock count specific to the task that is running.
+    #[doc(alias = "PERF_COUNT_SW_TASK_CLOCK")]
+    TaskClock = perf_sw_ids::PERF_COUNT_SW_TASK_CLOCK as isize,
+    /// Number of page faults.
+    #[doc(alias = "PERF_COUNT_SW_PAGE_FAULTS")]
+    PageFaults = perf_sw_ids::PERF_COUNT_SW_PAGE_FAULTS as isize,
+    /// Numer of context switches.
+    #[doc(alias = "PERF_COUNT_SW_CONTEXT_SWITCHES")]
+    ContextSwitches = perf_sw_ids::PERF_COUNT_SW_CONTEXT_SWITCHES as isize,
+    /// Number of times the process has migrated to a new CPU.
+    #[doc(alias = "PERF_COUNT_SW_CPU_MIGRATIONS")]
+    CpuMigrations = perf_sw_ids::PERF_COUNT_SW_CPU_MIGRATIONS as isize,
+    /// Number of minor page faults.
+    #[doc(alias = "PERF_COUNT_SW_PAGE_FAULTS_MIN")]
+    PageFaultsMin = perf_sw_ids::PERF_COUNT_SW_PAGE_FAULTS_MIN as isize,
+    /// Number of major page faults.
+    #[doc(alias = "PERF_COUNT_SW_PAGE_FAULTS_MAJ")]
+    PageFaultsMaj = perf_sw_ids::PERF_COUNT_SW_PAGE_FAULTS_MAJ as isize,
+    /// Number of alignment faults.
+    #[doc(alias = "PERF_COUNT_SW_ALIGNMENT_FAULTS")]
+    AlignmentFaults = perf_sw_ids::PERF_COUNT_SW_ALIGNMENT_FAULTS as isize,
+    /// Number of emulation faults.
+    #[doc(alias = "PERF_COUNT_SW_EMULATION_FAULTS")]
+    EmulationFaults = perf_sw_ids::PERF_COUNT_SW_EMULATION_FAULTS as isize,
+    /// Placeholder event that counts nothing.
+    #[doc(alias = "PERF_COUNT_SW_DUMMY")]
+    Dummy = perf_sw_ids::PERF_COUNT_SW_DUMMY as isize,
+    /// Generates raw sample data from BPF.
+    #[doc(alias = "PERF_COUNT_SW_BPF_OUTPUT")]
+    BpfOutput = perf_sw_ids::PERF_COUNT_SW_BPF_OUTPUT as isize,
+    /// Number of context switches to a task when switching to a different cgroup.
+    #[doc(alias = "PERF_COUNT_SW_CGROUP_SWITCHES")]
+    CgroupSwitches = perf_sw_ids::PERF_COUNT_SW_CGROUP_SWITCHES as isize,
+}
+
+/// The hardware CPU cache events.
+#[doc(alias = "perf_hw_cache_id")]
+#[derive(Debug, Clone, Copy)]
+pub enum HwCacheEvent {
+    /// Measures Level 1 data cache.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_L1D")]
+    L1d = perf_hw_cache_id::PERF_COUNT_HW_CACHE_L1D as isize,
+    /// Measures Level 1 data cache.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_L1I")]
+    L1i = perf_hw_cache_id::PERF_COUNT_HW_CACHE_L1I as isize,
+    /// Measures Last-level cache.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_LL")]
+    Ll = perf_hw_cache_id::PERF_COUNT_HW_CACHE_LL as isize,
+    /// Measures Data TLB (Translation Lookaside Buffer).
+    #[doc(alias = "PERF_COUNT_HW_CACHE_DTLB")]
+    Dtlb = perf_hw_cache_id::PERF_COUNT_HW_CACHE_DTLB as isize,
+    /// Measures Instruction TLB (Translation Lookaside Buffer).
+    #[doc(alias = "PERF_COUNT_HW_CACHE_ITLB")]
+    Itlb = perf_hw_cache_id::PERF_COUNT_HW_CACHE_ITLB as isize,
+    /// Measures branch prediction.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_BPU")]
+    Bpu = perf_hw_cache_id::PERF_COUNT_HW_CACHE_BPU as isize,
+    /// Measures local memory accesses.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_NODE")]
+    Node = perf_hw_cache_id::PERF_COUNT_HW_CACHE_NODE as isize,
+}
+
+/// The hardware CPU cache operations.
+#[doc(alias = "perf_hw_cache_op_id")]
+#[derive(Debug, Clone, Copy)]
+pub enum HwCacheOp {
+    /// Read access.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_OP_READ")]
+    Read = perf_hw_cache_op_id::PERF_COUNT_HW_CACHE_OP_READ as isize,
+    /// Write access.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_OP_WRITE")]
+    Write = perf_hw_cache_op_id::PERF_COUNT_HW_CACHE_OP_WRITE as isize,
+    /// Prefetch access.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_OP_PREFETCH")]
+    Prefetch = perf_hw_cache_op_id::PERF_COUNT_HW_CACHE_OP_PREFETCH as isize,
+}
+
+/// The hardware CPU cache result.
+#[doc(alias = "perf_hw_cache_op_result_id")]
+#[derive(Debug, Clone, Copy)]
+pub enum HwCacheResult {
+    /// Cache accesses.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_RESULT_ACCESS")]
+    Access = perf_hw_cache_op_result_id::PERF_COUNT_HW_CACHE_RESULT_ACCESS as isize,
+    /// Cache missed accesses.
+    #[doc(alias = "PERF_COUNT_HW_CACHE_RESULT_MISS")]
+    Miss = perf_hw_cache_op_result_id::PERF_COUNT_HW_CACHE_RESULT_MISS as isize,
 }
 
 /// Sample Policy
@@ -100,19 +271,21 @@ 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.clone(),
 ///         PerfEventScope::AllProcessesOneCpu { cpu },
 ///         SamplePolicy::Period(1000000),
 ///         true,
@@ -134,25 +307,45 @@ 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`.
-    ///
-    /// The `scope` argument determines which processes are sampled. If `inherit`
-    /// is true, any new processes spawned by those processes will also
+    /// The [`perf_type`](PerfEventConfig) defines the event `type` and `config` of interest.
+    /// The [`scope`](PerfEventScope) argument determines which processes are sampled.
+    /// If `inherit` is `true`, any new processes spawned by those processes will also
     /// automatically get sampled.
     ///
     /// The returned value can be used to detach, see [PerfEvent::detach].
     pub fn attach(
         &mut self,
-        perf_type: PerfTypeId,
-        config: u64,
+        perf_type: PerfEventConfig,
         scope: PerfEventScope,
         sample_policy: SamplePolicy,
         inherit: bool,
     ) -> Result<PerfEventLinkId, ProgramError> {
         let prog_fd = self.fd()?;
         let prog_fd = prog_fd.as_fd();
+
+        let (perf_type, config) = match perf_type {
+            PerfEventConfig::Pmu { pmu_type, config } => (pmu_type, config),
+            // To handle `perf_type_id` event_type together
+            _ => {
+                let (perf_type, config) = match perf_type {
+                    PerfEventConfig::Hardware(hw_event) => (PERF_TYPE_HARDWARE, hw_event as u64),
+                    PerfEventConfig::Software(sw_event) => (PERF_TYPE_SOFTWARE, sw_event as u64),
+                    PerfEventConfig::TracePoint { event_id } => (PERF_TYPE_TRACEPOINT, event_id),
+                    PerfEventConfig::HwCache {
+                        event,
+                        operation,
+                        result,
+                    } => (
+                        PERF_TYPE_HW_CACHE,
+                        (event as u64) | ((operation as u64) << 8) | ((result as u64) << 16),
+                    ),
+                    PerfEventConfig::Raw { event_id } => (PERF_TYPE_RAW, event_id),
+                    PerfEventConfig::Breakpoint => (PERF_TYPE_BREAKPOINT, 0),
+                    PerfEventConfig::Pmu { .. } => unreachable!(), // not possible due to earlier match
+                };
+                (perf_type as u32, config)
+            }
+        };
         let (sample_period, sample_frequency) = match sample_policy {
             SamplePolicy::Period(period) => (period, None),
             SamplePolicy::Frequency(frequency) => (0, Some(frequency)),
@@ -165,7 +358,7 @@ impl PerfEvent {
             PerfEventScope::AllProcessesOneCpu { cpu } => (-1, cpu as i32),
         };
         let fd = perf_event_open(
-            perf_type as u32,
+            perf_type,
             config,
             pid,
             cpu,
diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt
index 3d5c5874..34f1be11 100644
--- a/xtask/public-api/aya.txt
+++ b/xtask/public-api/aya.txt
@@ -4539,11 +4539,211 @@ pub fn aya::programs::perf_attach::PerfLinkId::borrow_mut(&mut self) -> &mut T
 impl<T> core::convert::From<T> 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
+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<T, U> core::convert::Into<U> for aya::programs::perf_event::HardwareEvent where U: core::convert::From<T>
+pub fn aya::programs::perf_event::HardwareEvent::into(self) -> U
+impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::HardwareEvent where U: core::convert::Into<T>
+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<T, <T as core::convert::TryFrom<U>>::Error>
+impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::HardwareEvent where U: core::convert::TryFrom<T>
+pub type aya::programs::perf_event::HardwareEvent::Error = <U as core::convert::TryFrom<T>>::Error
+pub fn aya::programs::perf_event::HardwareEvent::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
+impl<T> 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<T> 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<T> core::borrow::Borrow<T> for aya::programs::perf_event::HardwareEvent where T: core::marker::Sized
+pub fn aya::programs::perf_event::HardwareEvent::borrow(&self) -> &T
+impl<T> core::borrow::BorrowMut<T> 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<T> 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, dst: *mut T)
+impl<T> core::convert::From<T> for aya::programs::perf_event::HardwareEvent
+pub fn aya::programs::perf_event::HardwareEvent::from(t: T) -> T
+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<T, U> core::convert::Into<U> for aya::programs::perf_event::HwCacheEvent where U: core::convert::From<T>
+pub fn aya::programs::perf_event::HwCacheEvent::into(self) -> U
+impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::HwCacheEvent where U: core::convert::Into<T>
+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<T, <T as core::convert::TryFrom<U>>::Error>
+impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::HwCacheEvent where U: core::convert::TryFrom<T>
+pub type aya::programs::perf_event::HwCacheEvent::Error = <U as core::convert::TryFrom<T>>::Error
+pub fn aya::programs::perf_event::HwCacheEvent::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
+impl<T> 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<T> 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<T> core::borrow::Borrow<T> for aya::programs::perf_event::HwCacheEvent where T: core::marker::Sized
+pub fn aya::programs::perf_event::HwCacheEvent::borrow(&self) -> &T
+impl<T> core::borrow::BorrowMut<T> 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<T> 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, dst: *mut T)
+impl<T> core::convert::From<T> for aya::programs::perf_event::HwCacheEvent
+pub fn aya::programs::perf_event::HwCacheEvent::from(t: T) -> T
+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<T, U> core::convert::Into<U> for aya::programs::perf_event::HwCacheOp where U: core::convert::From<T>
+pub fn aya::programs::perf_event::HwCacheOp::into(self) -> U
+impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::HwCacheOp where U: core::convert::Into<T>
+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<T, <T as core::convert::TryFrom<U>>::Error>
+impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::HwCacheOp where U: core::convert::TryFrom<T>
+pub type aya::programs::perf_event::HwCacheOp::Error = <U as core::convert::TryFrom<T>>::Error
+pub fn aya::programs::perf_event::HwCacheOp::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
+impl<T> 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<T> 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<T> core::borrow::Borrow<T> for aya::programs::perf_event::HwCacheOp where T: core::marker::Sized
+pub fn aya::programs::perf_event::HwCacheOp::borrow(&self) -> &T
+impl<T> core::borrow::BorrowMut<T> 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<T> 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, dst: *mut T)
+impl<T> core::convert::From<T> for aya::programs::perf_event::HwCacheOp
+pub fn aya::programs::perf_event::HwCacheOp::from(t: T) -> T
+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<T, U> core::convert::Into<U> for aya::programs::perf_event::HwCacheResult where U: core::convert::From<T>
+pub fn aya::programs::perf_event::HwCacheResult::into(self) -> U
+impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::HwCacheResult where U: core::convert::Into<T>
+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<T, <T as core::convert::TryFrom<U>>::Error>
+impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::HwCacheResult where U: core::convert::TryFrom<T>
+pub type aya::programs::perf_event::HwCacheResult::Error = <U as core::convert::TryFrom<T>>::Error
+pub fn aya::programs::perf_event::HwCacheResult::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
+impl<T> 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<T> 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<T> core::borrow::Borrow<T> for aya::programs::perf_event::HwCacheResult where T: core::marker::Sized
+pub fn aya::programs::perf_event::HwCacheResult::borrow(&self) -> &T
+impl<T> core::borrow::BorrowMut<T> 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<T> 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, dst: *mut T)
+impl<T> core::convert::From<T> for aya::programs::perf_event::HwCacheResult
+pub fn aya::programs::perf_event::HwCacheResult::from(t: T) -> T
+pub enum aya::programs::perf_event::PerfEventConfig
+pub aya::programs::perf_event::PerfEventConfig::Breakpoint
+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::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<T, U> core::convert::Into<U> for aya::programs::perf_event::PerfEventConfig where U: core::convert::From<T>
+pub fn aya::programs::perf_event::PerfEventConfig::into(self) -> U
+impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::PerfEventConfig where U: core::convert::Into<T>
+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<T, <T as core::convert::TryFrom<U>>::Error>
+impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::PerfEventConfig where U: core::convert::TryFrom<T>
+pub type aya::programs::perf_event::PerfEventConfig::Error = <U as core::convert::TryFrom<T>>::Error
+pub fn aya::programs::perf_event::PerfEventConfig::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
+impl<T> 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<T> 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<T> core::borrow::Borrow<T> for aya::programs::perf_event::PerfEventConfig where T: core::marker::Sized
+pub fn aya::programs::perf_event::PerfEventConfig::borrow(&self) -> &T
+impl<T> core::borrow::BorrowMut<T> 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<T> 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, dst: *mut T)
+impl<T> core::convert::From<T> 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
@@ -4587,45 +4787,6 @@ impl<T> core::clone::CloneToUninit for aya::programs::perf_event::PerfEventScope
 pub unsafe fn aya::programs::perf_event::PerfEventScope::clone_to_uninit(&self, dst: *mut T)
 impl<T> core::convert::From<T> 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::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<T, U> core::convert::Into<U> for aya::programs::perf_event::PerfTypeId where U: core::convert::From<T>
-pub fn aya::programs::perf_event::PerfTypeId::into(self) -> U
-impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::PerfTypeId where U: core::convert::Into<T>
-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<T, <T as core::convert::TryFrom<U>>::Error>
-impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::PerfTypeId where U: core::convert::TryFrom<T>
-pub type aya::programs::perf_event::PerfTypeId::Error = <U as core::convert::TryFrom<T>>::Error
-pub fn aya::programs::perf_event::PerfTypeId::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
-impl<T> 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<T> 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<T> core::borrow::Borrow<T> for aya::programs::perf_event::PerfTypeId where T: core::marker::Sized
-pub fn aya::programs::perf_event::PerfTypeId::borrow(&self) -> &T
-impl<T> core::borrow::BorrowMut<T> 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<T> 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, dst: *mut T)
-impl<T> core::convert::From<T> 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)
@@ -4661,9 +4822,55 @@ impl<T> core::clone::CloneToUninit for aya::programs::perf_event::SamplePolicy w
 pub unsafe fn aya::programs::perf_event::SamplePolicy::clone_to_uninit(&self, dst: *mut T)
 impl<T> core::convert::From<T> for aya::programs::perf_event::SamplePolicy
 pub fn aya::programs::perf_event::SamplePolicy::from(t: T) -> T
+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<T, U> core::convert::Into<U> for aya::programs::perf_event::SoftwareEvent where U: core::convert::From<T>
+pub fn aya::programs::perf_event::SoftwareEvent::into(self) -> U
+impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::SoftwareEvent where U: core::convert::Into<T>
+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<T, <T as core::convert::TryFrom<U>>::Error>
+impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::SoftwareEvent where U: core::convert::TryFrom<T>
+pub type aya::programs::perf_event::SoftwareEvent::Error = <U as core::convert::TryFrom<T>>::Error
+pub fn aya::programs::perf_event::SoftwareEvent::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
+impl<T> 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<T> 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<T> core::borrow::Borrow<T> for aya::programs::perf_event::SoftwareEvent where T: core::marker::Sized
+pub fn aya::programs::perf_event::SoftwareEvent::borrow(&self) -> &T
+impl<T> core::borrow::BorrowMut<T> 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<T> 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, dst: *mut T)
+impl<T> core::convert::From<T> 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 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) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
+pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfEventConfig, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::detach(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::take_link(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<aya::programs::perf_event::PerfEventLink, aya::programs::ProgramError>
@@ -6726,45 +6933,6 @@ impl<T> core::clone::CloneToUninit for aya::programs::perf_event::PerfEventScope
 pub unsafe fn aya::programs::perf_event::PerfEventScope::clone_to_uninit(&self, dst: *mut T)
 impl<T> core::convert::From<T> 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::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<T, U> core::convert::Into<U> for aya::programs::perf_event::PerfTypeId where U: core::convert::From<T>
-pub fn aya::programs::perf_event::PerfTypeId::into(self) -> U
-impl<T, U> core::convert::TryFrom<U> for aya::programs::perf_event::PerfTypeId where U: core::convert::Into<T>
-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<T, <T as core::convert::TryFrom<U>>::Error>
-impl<T, U> core::convert::TryInto<U> for aya::programs::perf_event::PerfTypeId where U: core::convert::TryFrom<T>
-pub type aya::programs::perf_event::PerfTypeId::Error = <U as core::convert::TryFrom<T>>::Error
-pub fn aya::programs::perf_event::PerfTypeId::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
-impl<T> 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<T> 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<T> core::borrow::Borrow<T> for aya::programs::perf_event::PerfTypeId where T: core::marker::Sized
-pub fn aya::programs::perf_event::PerfTypeId::borrow(&self) -> &T
-impl<T> core::borrow::BorrowMut<T> 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<T> 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, dst: *mut T)
-impl<T> core::convert::From<T> 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
@@ -8131,7 +8299,7 @@ impl<T> core::convert::From<T> for aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::from(t: T) -> T
 pub struct aya::programs::PerfEvent
 impl aya::programs::perf_event::PerfEvent
-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) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
+pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfEventConfig, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::detach(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::take_link(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<aya::programs::perf_event::PerfEventLink, aya::programs::ProgramError>