From ba51589b0d01964d035076578d39d2afc71a757d Mon Sep 17 00:00:00 2001 From: tyrone-wu Date: Sun, 2 Jun 2024 00:31:10 +0000 Subject: [PATCH 1/2] aya,aya-obj: add bpf syscall function for BPF_ENABLE_STATS command Add bpf syscall function for BPF_ENABLE_STATS to enable stats tracking for benchmarking purposes, which returns a file descriptor handler. This also adds the aya-object api for bpf_stats_type. --- .../src/generated/linux_bindings_aarch64.rs | 5 + aya-obj/src/generated/linux_bindings_armv7.rs | 5 + .../src/generated/linux_bindings_riscv64.rs | 5 + .../src/generated/linux_bindings_x86_64.rs | 5 + aya-obj/src/lib.rs | 2 + aya-obj/src/stats.rs | 18 +++ aya/src/bpf.rs | 37 +++++- aya/src/sys/bpf.rs | 15 +++ xtask/public-api/aya-obj.txt | 112 ++++++++++++++++++ xtask/public-api/aya.txt | 2 + xtask/src/codegen/aya.rs | 1 + 11 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 aya-obj/src/stats.rs diff --git a/aya-obj/src/generated/linux_bindings_aarch64.rs b/aya-obj/src/generated/linux_bindings_aarch64.rs index 134fd4f7..89976cb7 100644 --- a/aya-obj/src/generated/linux_bindings_aarch64.rs +++ b/aya-obj/src/generated/linux_bindings_aarch64.rs @@ -476,6 +476,11 @@ pub const BPF_F_TOKEN_FD: _bindgen_ty_5 = 65536; pub const BPF_F_SEGV_ON_FAULT: _bindgen_ty_5 = 131072; pub const BPF_F_NO_USER_CONV: _bindgen_ty_5 = 262144; pub type _bindgen_ty_5 = ::core::ffi::c_uint; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum bpf_stats_type { + BPF_STATS_RUN_TIME = 0, +} #[repr(C)] #[derive(Copy, Clone)] pub union bpf_attr { diff --git a/aya-obj/src/generated/linux_bindings_armv7.rs b/aya-obj/src/generated/linux_bindings_armv7.rs index 9c2cb53f..75bb0000 100644 --- a/aya-obj/src/generated/linux_bindings_armv7.rs +++ b/aya-obj/src/generated/linux_bindings_armv7.rs @@ -476,6 +476,11 @@ pub const BPF_F_TOKEN_FD: _bindgen_ty_5 = 65536; pub const BPF_F_SEGV_ON_FAULT: _bindgen_ty_5 = 131072; pub const BPF_F_NO_USER_CONV: _bindgen_ty_5 = 262144; pub type _bindgen_ty_5 = ::core::ffi::c_uint; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum bpf_stats_type { + BPF_STATS_RUN_TIME = 0, +} #[repr(C)] #[derive(Copy, Clone)] pub union bpf_attr { diff --git a/aya-obj/src/generated/linux_bindings_riscv64.rs b/aya-obj/src/generated/linux_bindings_riscv64.rs index 134fd4f7..89976cb7 100644 --- a/aya-obj/src/generated/linux_bindings_riscv64.rs +++ b/aya-obj/src/generated/linux_bindings_riscv64.rs @@ -476,6 +476,11 @@ pub const BPF_F_TOKEN_FD: _bindgen_ty_5 = 65536; pub const BPF_F_SEGV_ON_FAULT: _bindgen_ty_5 = 131072; pub const BPF_F_NO_USER_CONV: _bindgen_ty_5 = 262144; pub type _bindgen_ty_5 = ::core::ffi::c_uint; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum bpf_stats_type { + BPF_STATS_RUN_TIME = 0, +} #[repr(C)] #[derive(Copy, Clone)] pub union bpf_attr { diff --git a/aya-obj/src/generated/linux_bindings_x86_64.rs b/aya-obj/src/generated/linux_bindings_x86_64.rs index 134fd4f7..89976cb7 100644 --- a/aya-obj/src/generated/linux_bindings_x86_64.rs +++ b/aya-obj/src/generated/linux_bindings_x86_64.rs @@ -476,6 +476,11 @@ pub const BPF_F_TOKEN_FD: _bindgen_ty_5 = 65536; pub const BPF_F_SEGV_ON_FAULT: _bindgen_ty_5 = 131072; pub const BPF_F_NO_USER_CONV: _bindgen_ty_5 = 262144; pub type _bindgen_ty_5 = ::core::ffi::c_uint; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum bpf_stats_type { + BPF_STATS_RUN_TIME = 0, +} #[repr(C)] #[derive(Copy, Clone)] pub union bpf_attr { diff --git a/aya-obj/src/lib.rs b/aya-obj/src/lib.rs index ea0e5670..1a774642 100644 --- a/aya-obj/src/lib.rs +++ b/aya-obj/src/lib.rs @@ -91,10 +91,12 @@ pub mod maps; pub mod obj; pub mod programs; pub mod relocation; +pub mod stats; mod util; pub use maps::Map; pub use obj::*; +pub use stats::BpfStatsType; /// An error returned from the verifier. /// diff --git a/aya-obj/src/stats.rs b/aya-obj/src/stats.rs new file mode 100644 index 00000000..999ae87e --- /dev/null +++ b/aya-obj/src/stats.rs @@ -0,0 +1,18 @@ +//! BPF stats type for `BPF_ENABLE_STATS` + +use crate::generated::bpf_stats_type; + +/// The type of BPF statistic to enable. +#[derive(Copy, Clone, Debug)] +pub enum BpfStatsType { + /// Metrics for `run_time_ns` and `run_cnt`. + RunTime, +} + +impl From for bpf_stats_type { + fn from(value: BpfStatsType) -> Self { + match value { + BpfStatsType::RunTime => bpf_stats_type::BPF_STATS_RUN_TIME, + } + } +} diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 42a9a489..9b2bcb14 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -14,15 +14,15 @@ use aya_obj::{ btf::{BtfFeatures, BtfRelocationError}, generated::{BPF_F_SLEEPABLE, BPF_F_XDP_HAS_FRAGS}, relocation::EbpfRelocationError, - EbpfSectionKind, Features, + BpfStatsType, EbpfSectionKind, Features, }; use log::{debug, warn}; use thiserror::Error; use crate::{ generated::{ - bpf_map_type, bpf_map_type::*, AYA_PERF_EVENT_IOC_DISABLE, AYA_PERF_EVENT_IOC_ENABLE, - AYA_PERF_EVENT_IOC_SET_BPF, + bpf_map_type::{self, *}, + AYA_PERF_EVENT_IOC_DISABLE, AYA_PERF_EVENT_IOC_ENABLE, AYA_PERF_EVENT_IOC_SET_BPF, }, maps::{Map, MapData, MapError}, obj::{ @@ -36,12 +36,12 @@ use crate::{ SkMsg, SkSkb, SkSkbKind, SockOps, SocketFilter, TracePoint, UProbe, Xdp, }, sys::{ - bpf_load_btf, is_bpf_cookie_supported, is_bpf_global_data_supported, + bpf_enable_stats, bpf_load_btf, is_bpf_cookie_supported, is_bpf_global_data_supported, is_btf_datasec_supported, is_btf_decl_tag_supported, is_btf_enum64_supported, is_btf_float_supported, is_btf_func_global_supported, is_btf_func_supported, is_btf_supported, is_btf_type_tag_supported, is_perf_link_supported, is_probe_read_kernel_supported, is_prog_id_supported, is_prog_name_supported, - retry_with_verifier_logs, + retry_with_verifier_logs, SyscallError, }, util::{bytes_of, bytes_of_slice, page_size, possible_cpus, POSSIBLE_CPUS}, }; @@ -1068,6 +1068,29 @@ impl Ebpf { pub fn programs_mut(&mut self) -> impl Iterator { self.programs.iter_mut().map(|(s, p)| (s.as_str(), p)) } + + /// Enable global statistics tracking for all programs and returns a file descriptor handler. + /// + /// Statistics tracking will be disabled once the file descriptor is closed or released. + /// + /// Typical usage: + /// 1. Obtain fd from `enable_stats_fd` and bind it to a variable. + /// 2. Record the statistic of interest. + /// 3. Wait for a recorded period of time. + /// 4. Record the statistic of interest again, and calculate the difference. + /// 5. Close/release fd. + /// + /// # Examples + /// + /// ```no_run + /// # use aya::{Ebpf, EbpfError}; + /// # use aya_obj::BpfStatsType; + /// let _fd = Ebpf::enable_stats_fd(BpfStatsType::RunTime)?; + /// # Ok::<(), EbpfError>(()) + /// ``` + pub fn enable_stats_fd(stats_type: BpfStatsType) -> Result { + bpf_enable_stats(stats_type.into()) + } } /// The error type returned by [`Ebpf::load_file`] and [`Ebpf::load`]. @@ -1117,6 +1140,10 @@ pub enum EbpfError { #[error("program error: {0}")] /// A program error ProgramError(#[from] ProgramError), + + #[error("syscall error: {0}")] + /// A syscall error + SyscallError(#[from] SyscallError), } /// The error type returned by [`Bpf::load_file`] and [`Bpf::load`]. diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs index 1ae1dc95..8a41ee39 100644 --- a/aya/src/sys/bpf.rs +++ b/aya/src/sys/bpf.rs @@ -8,6 +8,7 @@ use std::{ }; use assert_matches::assert_matches; +use aya_obj::generated::bpf_stats_type; use libc::{ENOENT, ENOSPC}; use obj::{ btf::{BtfEnum64, Enum64}, @@ -1056,6 +1057,20 @@ pub(crate) fn iter_map_ids() -> impl Iterator> iter_obj_ids(bpf_cmd::BPF_MAP_GET_NEXT_ID, "bpf_map_get_next_id") } +pub(crate) fn bpf_enable_stats(bpf_stats_type: bpf_stats_type) -> Result { + let mut attr = unsafe { mem::zeroed::() }; + attr.enable_stats.type_ = bpf_stats_type as u32; + + // SAFETY: BPF_ENABLE_STATS returns a new file descriptor. + unsafe { fd_sys_bpf(bpf_cmd::BPF_ENABLE_STATS, &mut attr) }.map_err(|(code, io_error)| { + assert_eq!(code, -1); + SyscallError { + call: "bpf_enable_stats", + io_error, + } + }) +} + pub(crate) fn retry_with_verifier_logs( max_retries: usize, f: impl Fn(&mut [u8]) -> SysResult, diff --git a/xtask/public-api/aya-obj.txt b/xtask/public-api/aya-obj.txt index b1f960d0..104a22f5 100644 --- a/xtask/public-api/aya-obj.txt +++ b/xtask/public-api/aya-obj.txt @@ -1795,6 +1795,47 @@ impl core::clone::CloneToUninit for aya_obj::generated::bpf_prog_type where T pub unsafe fn aya_obj::generated::bpf_prog_type::clone_to_uninit(&self, dst: *mut T) impl core::convert::From for aya_obj::generated::bpf_prog_type pub fn aya_obj::generated::bpf_prog_type::from(t: T) -> T +#[repr(u32)] pub enum aya_obj::generated::bpf_stats_type +pub aya_obj::generated::bpf_stats_type::BPF_STATS_RUN_TIME = 0 +impl core::clone::Clone for aya_obj::generated::bpf_stats_type +pub fn aya_obj::generated::bpf_stats_type::clone(&self) -> aya_obj::generated::bpf_stats_type +impl core::cmp::Eq for aya_obj::generated::bpf_stats_type +impl core::cmp::PartialEq for aya_obj::generated::bpf_stats_type +pub fn aya_obj::generated::bpf_stats_type::eq(&self, other: &aya_obj::generated::bpf_stats_type) -> bool +impl core::convert::From for aya_obj::generated::bpf_stats_type +pub fn aya_obj::generated::bpf_stats_type::from(value: aya_obj::stats::BpfStatsType) -> Self +impl core::fmt::Debug for aya_obj::generated::bpf_stats_type +pub fn aya_obj::generated::bpf_stats_type::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::hash::Hash for aya_obj::generated::bpf_stats_type +pub fn aya_obj::generated::bpf_stats_type::hash<__H: core::hash::Hasher>(&self, state: &mut __H) +impl core::marker::Copy for aya_obj::generated::bpf_stats_type +impl core::marker::StructuralPartialEq for aya_obj::generated::bpf_stats_type +impl core::marker::Freeze for aya_obj::generated::bpf_stats_type +impl core::marker::Send for aya_obj::generated::bpf_stats_type +impl core::marker::Sync for aya_obj::generated::bpf_stats_type +impl core::marker::Unpin for aya_obj::generated::bpf_stats_type +impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::generated::bpf_stats_type +impl core::panic::unwind_safe::UnwindSafe for aya_obj::generated::bpf_stats_type +impl core::convert::Into for aya_obj::generated::bpf_stats_type where U: core::convert::From +pub fn aya_obj::generated::bpf_stats_type::into(self) -> U +impl core::convert::TryFrom for aya_obj::generated::bpf_stats_type where U: core::convert::Into +pub type aya_obj::generated::bpf_stats_type::Error = core::convert::Infallible +pub fn aya_obj::generated::bpf_stats_type::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya_obj::generated::bpf_stats_type where U: core::convert::TryFrom +pub type aya_obj::generated::bpf_stats_type::Error = >::Error +pub fn aya_obj::generated::bpf_stats_type::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya_obj::generated::bpf_stats_type where T: core::clone::Clone +pub type aya_obj::generated::bpf_stats_type::Owned = T +pub fn aya_obj::generated::bpf_stats_type::clone_into(&self, target: &mut T) +pub fn aya_obj::generated::bpf_stats_type::to_owned(&self) -> T +impl core::any::Any for aya_obj::generated::bpf_stats_type where T: 'static + core::marker::Sized +pub fn aya_obj::generated::bpf_stats_type::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya_obj::generated::bpf_stats_type where T: core::marker::Sized +pub fn aya_obj::generated::bpf_stats_type::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya_obj::generated::bpf_stats_type where T: core::marker::Sized +pub fn aya_obj::generated::bpf_stats_type::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya_obj::generated::bpf_stats_type +pub fn aya_obj::generated::bpf_stats_type::from(t: T) -> T #[repr(u32)] pub enum aya_obj::generated::btf_func_linkage pub aya_obj::generated::btf_func_linkage::BTF_FUNC_EXTERN = 2 pub aya_obj::generated::btf_func_linkage::BTF_FUNC_GLOBAL = 1 @@ -7918,6 +7959,77 @@ impl core::borrow::BorrowMut for aya_obj::relocation::EbpfRelocationError pub fn aya_obj::relocation::EbpfRelocationError::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya_obj::relocation::EbpfRelocationError pub fn aya_obj::relocation::EbpfRelocationError::from(t: T) -> T +pub mod aya_obj::stats +pub enum aya_obj::stats::BpfStatsType +pub aya_obj::stats::BpfStatsType::RunTime +impl core::clone::Clone for aya_obj::stats::BpfStatsType +pub fn aya_obj::stats::BpfStatsType::clone(&self) -> aya_obj::stats::BpfStatsType +impl core::convert::From for aya_obj::generated::bpf_stats_type +pub fn aya_obj::generated::bpf_stats_type::from(value: aya_obj::stats::BpfStatsType) -> Self +impl core::fmt::Debug for aya_obj::stats::BpfStatsType +pub fn aya_obj::stats::BpfStatsType::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya_obj::stats::BpfStatsType +impl core::marker::Freeze for aya_obj::stats::BpfStatsType +impl core::marker::Send for aya_obj::stats::BpfStatsType +impl core::marker::Sync for aya_obj::stats::BpfStatsType +impl core::marker::Unpin for aya_obj::stats::BpfStatsType +impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::stats::BpfStatsType +impl core::panic::unwind_safe::UnwindSafe for aya_obj::stats::BpfStatsType +impl core::convert::Into for aya_obj::stats::BpfStatsType where U: core::convert::From +pub fn aya_obj::stats::BpfStatsType::into(self) -> U +impl core::convert::TryFrom for aya_obj::stats::BpfStatsType where U: core::convert::Into +pub type aya_obj::stats::BpfStatsType::Error = core::convert::Infallible +pub fn aya_obj::stats::BpfStatsType::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya_obj::stats::BpfStatsType where U: core::convert::TryFrom +pub type aya_obj::stats::BpfStatsType::Error = >::Error +pub fn aya_obj::stats::BpfStatsType::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya_obj::stats::BpfStatsType where T: core::clone::Clone +pub type aya_obj::stats::BpfStatsType::Owned = T +pub fn aya_obj::stats::BpfStatsType::clone_into(&self, target: &mut T) +pub fn aya_obj::stats::BpfStatsType::to_owned(&self) -> T +impl core::any::Any for aya_obj::stats::BpfStatsType where T: 'static + core::marker::Sized +pub fn aya_obj::stats::BpfStatsType::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya_obj::stats::BpfStatsType where T: core::marker::Sized +pub fn aya_obj::stats::BpfStatsType::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya_obj::stats::BpfStatsType where T: core::marker::Sized +pub fn aya_obj::stats::BpfStatsType::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya_obj::stats::BpfStatsType +pub fn aya_obj::stats::BpfStatsType::from(t: T) -> T +pub enum aya_obj::BpfStatsType +pub aya_obj::BpfStatsType::RunTime +impl core::clone::Clone for aya_obj::stats::BpfStatsType +pub fn aya_obj::stats::BpfStatsType::clone(&self) -> aya_obj::stats::BpfStatsType +impl core::convert::From for aya_obj::generated::bpf_stats_type +pub fn aya_obj::generated::bpf_stats_type::from(value: aya_obj::stats::BpfStatsType) -> Self +impl core::fmt::Debug for aya_obj::stats::BpfStatsType +pub fn aya_obj::stats::BpfStatsType::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Copy for aya_obj::stats::BpfStatsType +impl core::marker::Freeze for aya_obj::stats::BpfStatsType +impl core::marker::Send for aya_obj::stats::BpfStatsType +impl core::marker::Sync for aya_obj::stats::BpfStatsType +impl core::marker::Unpin for aya_obj::stats::BpfStatsType +impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::stats::BpfStatsType +impl core::panic::unwind_safe::UnwindSafe for aya_obj::stats::BpfStatsType +impl core::convert::Into for aya_obj::stats::BpfStatsType where U: core::convert::From +pub fn aya_obj::stats::BpfStatsType::into(self) -> U +impl core::convert::TryFrom for aya_obj::stats::BpfStatsType where U: core::convert::Into +pub type aya_obj::stats::BpfStatsType::Error = core::convert::Infallible +pub fn aya_obj::stats::BpfStatsType::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya_obj::stats::BpfStatsType where U: core::convert::TryFrom +pub type aya_obj::stats::BpfStatsType::Error = >::Error +pub fn aya_obj::stats::BpfStatsType::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for aya_obj::stats::BpfStatsType where T: core::clone::Clone +pub type aya_obj::stats::BpfStatsType::Owned = T +pub fn aya_obj::stats::BpfStatsType::clone_into(&self, target: &mut T) +pub fn aya_obj::stats::BpfStatsType::to_owned(&self) -> T +impl core::any::Any for aya_obj::stats::BpfStatsType where T: 'static + core::marker::Sized +pub fn aya_obj::stats::BpfStatsType::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya_obj::stats::BpfStatsType where T: core::marker::Sized +pub fn aya_obj::stats::BpfStatsType::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya_obj::stats::BpfStatsType where T: core::marker::Sized +pub fn aya_obj::stats::BpfStatsType::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya_obj::stats::BpfStatsType +pub fn aya_obj::stats::BpfStatsType::from(t: T) -> T pub enum aya_obj::EbpfSectionKind pub aya_obj::EbpfSectionKind::Bss pub aya_obj::EbpfSectionKind::Btf diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 6515c488..5b3bd197 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -8744,6 +8744,7 @@ pub aya::EbpfError::NoBTF pub aya::EbpfError::ParseError(aya_obj::obj::ParseError) pub aya::EbpfError::ProgramError(aya::programs::ProgramError) pub aya::EbpfError::RelocationError(aya_obj::relocation::EbpfRelocationError) +pub aya::EbpfError::SyscallError(crate::sys::SyscallError) pub aya::EbpfError::UnexpectedPinningType pub aya::EbpfError::UnexpectedPinningType::name: u32 impl core::convert::From for aya::EbpfError @@ -8790,6 +8791,7 @@ impl core::convert::From for aya::EbpfError pub fn aya::EbpfError::from(t: T) -> T pub struct aya::Ebpf impl aya::Ebpf +pub fn aya::Ebpf::enable_stats_fd(stats_type: aya_obj::stats::BpfStatsType) -> core::result::Result pub fn aya::Ebpf::load(data: &[u8]) -> core::result::Result pub fn aya::Ebpf::load_file>(path: P) -> core::result::Result pub fn aya::Ebpf::map(&self, name: &str) -> core::option::Option<&aya::maps::Map> diff --git a/xtask/src/codegen/aya.rs b/xtask/src/codegen/aya.rs index 935036d3..b1d3f18b 100644 --- a/xtask/src/codegen/aya.rs +++ b/xtask/src/codegen/aya.rs @@ -79,6 +79,7 @@ fn codegen_bindings(opts: &SysrootOptions, libbpf_dir: &Path) -> Result<(), anyh "bpf_lpm_trie_key", "bpf_cpumap_val", "bpf_devmap_val", + "bpf_stats_type", // BTF "btf_header", "btf_ext_info", From 34c744c0829135183dc54d86fc7e735f557a443c Mon Sep 17 00:00:00 2001 From: tyrone-wu Date: Tue, 28 May 2024 02:59:49 +0000 Subject: [PATCH 2/2] aya: expose run_time_ns and run_cnt fields in ProgramInfo Added functions to expose run_time_ns & run_cnt statistics from ProgramInfo/bpf_prog_info. --- aya/src/programs/mod.rs | 16 ++++++++++++++++ test/integration-test/src/tests/smoke.rs | 2 ++ xtask/public-api/aya.txt | 2 ++ 3 files changed, 20 insertions(+) diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index 675e36f0..0b72b885 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -1099,6 +1099,22 @@ impl ProgramInfo { Ok(ProgramFd(fd)) } + /// The duration the program has been running, in nanoseconds. + /// + /// Note this field is only updated for as long as [`BPF_ENABLE_STATS`](crate::Ebpf::enable_stats_fd) + /// is enabled with [`BPF_STATS_RUN_TIME`](aya_obj::BpfStatsType::RunTime) type set. + pub fn run_time_ns(&self) -> u64 { + self.0.run_time_ns + } + + /// The number of times the program has ran. + /// + /// Note this field is only updated for as long as [`BPF_ENABLE_STATS`](crate::Ebpf::enable_stats_fd) + /// is enabled with [`BPF_STATS_RUN_TIME`](aya_obj::BpfStatsType::RunTime) type set. + pub fn run_cnt(&self) -> u64 { + self.0.run_cnt + } + /// Loads a program from a pinned path in bpffs. pub fn from_pin>(path: P) -> Result { use std::os::unix::ffi::OsStrExt as _; diff --git a/test/integration-test/src/tests/smoke.rs b/test/integration-test/src/tests/smoke.rs index 708b889b..3a0afd7c 100644 --- a/test/integration-test/src/tests/smoke.rs +++ b/test/integration-test/src/tests/smoke.rs @@ -98,6 +98,8 @@ fn list_loaded_programs() { prog.verified_instruction_count(); prog.loaded_at(); prog.fd().unwrap(); + prog.run_time_ns(); + prog.run_cnt(); } #[test] diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 5b3bd197..2347711d 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -7930,6 +7930,8 @@ pub fn aya::programs::ProgramInfo::memory_locked(&self) -> core::result::Result< pub fn aya::programs::ProgramInfo::name(&self) -> &[u8] pub fn aya::programs::ProgramInfo::name_as_str(&self) -> core::option::Option<&str> pub fn aya::programs::ProgramInfo::program_type(&self) -> u32 +pub fn aya::programs::ProgramInfo::run_cnt(&self) -> u64 +pub fn aya::programs::ProgramInfo::run_time_ns(&self) -> u64 pub fn aya::programs::ProgramInfo::size_jitted(&self) -> u32 pub fn aya::programs::ProgramInfo::size_translated(&self) -> u32 pub fn aya::programs::ProgramInfo::tag(&self) -> u64