aya,aya-obj: add BPF_ENABLE_STATS syscall function

Add bpf syscall function for BPF_ENABLE_STATS to enable stats tracking
for benchmarking purposes.

Additionally, move `#[cfg(test)]` annotation around the `Drop` trait
instead. Having separate functions causes some complications when
needing ownership/moving of the inner value `OwnedFd` when `Drop` is
manually implemented.
pull/959/head
tyrone-wu 3 months ago
parent a54532f848
commit fa6af6a204
No known key found for this signature in database
GPG Key ID: 978B1A1B79210AD6

@ -78,20 +78,20 @@
)] )]
mod bpf; mod bpf;
use aya_obj::generated;
pub mod maps; pub mod maps;
use aya_obj as obj;
pub mod pin; pub mod pin;
pub mod programs; pub mod programs;
pub use programs::loaded_programs; pub mod sys;
mod sys;
pub mod util; pub mod util;
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd}; use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
use aya_obj as obj;
use aya_obj::generated;
pub use bpf::*; pub use bpf::*;
pub use obj::btf::{Btf, BtfError}; pub use obj::btf::{Btf, BtfError};
pub use object::Endianness; pub use object::Endianness;
pub use programs::loaded_programs;
#[doc(hidden)] #[doc(hidden)]
pub use sys::netlink_set_link_up; pub use sys::netlink_set_link_up;
@ -139,6 +139,16 @@ impl MockableFd {
fd.as_ref().unwrap() fd.as_ref().unwrap()
} }
#[cfg(not(test))]
fn into_inner(self) -> OwnedFd {
self.fd
}
#[cfg(test)]
fn into_inner(mut self) -> OwnedFd {
self.fd.take().unwrap()
}
fn try_clone(&self) -> std::io::Result<Self> { fn try_clone(&self) -> std::io::Result<Self> {
let fd = self.inner(); let fd = self.inner();
let fd = fd.try_clone()?; let fd = fd.try_clone()?;
@ -175,13 +185,8 @@ impl FromRawFd for MockableFd {
} }
} }
#[cfg(test)]
impl Drop for MockableFd { impl Drop for MockableFd {
#[cfg(not(test))]
fn drop(&mut self) {
// Intentional no-op.
}
#[cfg(test)]
fn drop(&mut self) { fn drop(&mut self) {
use std::os::fd::AsRawFd as _; use std::os::fd::AsRawFd as _;

@ -11,6 +11,7 @@ use assert_matches::assert_matches;
use libc::{ENOENT, ENOSPC}; use libc::{ENOENT, ENOSPC};
use obj::{ use obj::{
btf::{BtfEnum64, Enum64}, btf::{BtfEnum64, Enum64},
generated::bpf_stats_type,
maps::{bpf_map_def, LegacyMap}, maps::{bpf_map_def, LegacyMap},
EbpfSectionKind, VerifierLog, EbpfSectionKind, VerifierLog,
}; };
@ -1054,6 +1055,22 @@ pub(crate) fn iter_map_ids() -> impl Iterator<Item = Result<u32, SyscallError>>
iter_obj_ids(bpf_cmd::BPF_MAP_GET_NEXT_ID, "bpf_map_get_next_id") iter_obj_ids(bpf_cmd::BPF_MAP_GET_NEXT_ID, "bpf_map_get_next_id")
} }
/// Introduced in kernel v5.8.
pub(crate) fn bpf_enable_stats(
stats_type: bpf_stats_type,
) -> Result<crate::MockableFd, SyscallError> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.enable_stats.type_ = 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(|(_, io_error)| {
SyscallError {
call: "bpf_enable_stats",
io_error,
}
})
}
pub(crate) fn retry_with_verifier_logs<T>( pub(crate) fn retry_with_verifier_logs<T>(
max_retries: usize, max_retries: usize,
f: impl Fn(&mut [u8]) -> SysResult<T>, f: impl Fn(&mut [u8]) -> SysResult<T>,

@ -1,3 +1,5 @@
//! A collection of system calls for performing eBPF related operations.
mod bpf; mod bpf;
mod netlink; mod netlink;
mod perf_event; mod perf_event;
@ -8,7 +10,7 @@ mod fake;
use std::{ use std::{
ffi::{c_int, c_void}, ffi::{c_int, c_void},
io, mem, io, mem,
os::fd::{AsRawFd as _, BorrowedFd}, os::fd::{AsRawFd as _, BorrowedFd, OwnedFd},
}; };
pub(crate) use bpf::*; pub(crate) use bpf::*;
@ -44,6 +46,7 @@ pub(crate) enum Syscall<'a> {
}, },
} }
/// A system call error.
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[error("`{call}` failed")] #[error("`{call}` failed")]
pub struct SyscallError { pub struct SyscallError {
@ -137,3 +140,53 @@ pub(crate) unsafe fn mmap(
#[cfg(test)] #[cfg(test)]
TEST_MMAP_RET.with(|ret| *ret.borrow()) TEST_MMAP_RET.with(|ret| *ret.borrow())
} }
/// The type of eBPF statistic to enable.
#[non_exhaustive]
#[doc(alias = "bpf_stats_type")]
#[derive(Copy, Clone, Debug)]
pub enum Stats {
/// Tracks `run_time_ns` and `run_cnt`.
#[doc(alias = "BPF_STATS_RUN_TIME")]
RunTime,
}
impl From<Stats> for crate::generated::bpf_stats_type {
fn from(value: Stats) -> Self {
use crate::generated::bpf_stats_type::*;
match value {
Stats::RunTime => BPF_STATS_RUN_TIME,
}
}
}
/// Enable global statistics tracking for eBPF programs and returns a
/// [file descriptor](`OwnedFd`) handler.
///
/// Statistics tracking is disabled when the [file descriptor](`OwnedFd`) is
/// dropped (either automatically when the variable goes out of scope or
/// manually through [`Drop`]).
///
/// Usage:
/// 1. Obtain fd from [`enable_stats`] 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 automatically or manually.
///
/// Introduced in kernel v5.8.
///
/// # Examples
///
/// ```no_run
/// # use aya::sys::{SyscallError};
/// use aya::sys::{enable_stats, Stats};
///
/// let _fd = enable_stats(Stats::RunTime)?;
/// # Ok::<(), SyscallError>(())
/// ```
#[doc(alias = "BPF_ENABLE_STATS")]
pub fn enable_stats(stats_type: Stats) -> Result<OwnedFd, SyscallError> {
bpf_enable_stats(stats_type.into()).map(|fd| fd.into_inner())
}

@ -1360,7 +1360,7 @@ pub aya::maps::MapError::PinError::error: aya::pin::PinError
pub aya::maps::MapError::PinError::name: core::option::Option<alloc::string::String> pub aya::maps::MapError::PinError::name: core::option::Option<alloc::string::String>
pub aya::maps::MapError::ProgIdNotSupported pub aya::maps::MapError::ProgIdNotSupported
pub aya::maps::MapError::ProgramNotLoaded pub aya::maps::MapError::ProgramNotLoaded
pub aya::maps::MapError::SyscallError(crate::sys::SyscallError) pub aya::maps::MapError::SyscallError(aya::sys::SyscallError)
pub aya::maps::MapError::Unsupported pub aya::maps::MapError::Unsupported
pub aya::maps::MapError::Unsupported::map_type: u32 pub aya::maps::MapError::Unsupported::map_type: u32
impl core::convert::From<aya::maps::MapError> for aya::EbpfError impl core::convert::From<aya::maps::MapError> for aya::EbpfError
@ -1369,6 +1369,8 @@ impl core::convert::From<aya::maps::MapError> for aya::maps::xdp::XdpMapError
pub fn aya::maps::xdp::XdpMapError::from(source: aya::maps::MapError) -> Self pub fn aya::maps::xdp::XdpMapError::from(source: aya::maps::MapError) -> Self
impl core::convert::From<aya::maps::MapError> for aya::programs::ProgramError impl core::convert::From<aya::maps::MapError> for aya::programs::ProgramError
pub fn aya::programs::ProgramError::from(source: aya::maps::MapError) -> Self pub fn aya::programs::ProgramError::from(source: aya::maps::MapError) -> Self
impl core::convert::From<aya::sys::SyscallError> for aya::maps::MapError
pub fn aya::maps::MapError::from(source: aya::sys::SyscallError) -> Self
impl core::convert::From<aya_obj::maps::InvalidMapTypeError> for aya::maps::MapError impl core::convert::From<aya_obj::maps::InvalidMapTypeError> for aya::maps::MapError
pub fn aya::maps::MapError::from(e: aya_obj::maps::InvalidMapTypeError) -> Self pub fn aya::maps::MapError::from(e: aya_obj::maps::InvalidMapTypeError) -> Self
impl core::convert::From<std::io::error::Error> for aya::maps::MapError impl core::convert::From<std::io::error::Error> for aya::maps::MapError
@ -2408,7 +2410,9 @@ pub aya::pin::PinError::InvalidPinPath::error: alloc::ffi::c_str::NulError
pub aya::pin::PinError::InvalidPinPath::path: std::path::PathBuf pub aya::pin::PinError::InvalidPinPath::path: std::path::PathBuf
pub aya::pin::PinError::NoFd pub aya::pin::PinError::NoFd
pub aya::pin::PinError::NoFd::name: alloc::string::String pub aya::pin::PinError::NoFd::name: alloc::string::String
pub aya::pin::PinError::SyscallError(crate::sys::SyscallError) pub aya::pin::PinError::SyscallError(aya::sys::SyscallError)
impl core::convert::From<aya::sys::SyscallError> for aya::pin::PinError
pub fn aya::pin::PinError::from(source: aya::sys::SyscallError) -> Self
impl core::error::Error for aya::pin::PinError impl core::error::Error for aya::pin::PinError
pub fn aya::pin::PinError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)> pub fn aya::pin::PinError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)>
impl core::fmt::Debug for aya::pin::PinError impl core::fmt::Debug for aya::pin::PinError
@ -3731,7 +3735,9 @@ pub fn aya::programs::kprobe::KProbeLinkId::from(t: T) -> T
pub mod aya::programs::links pub mod aya::programs::links
pub enum aya::programs::links::LinkError pub enum aya::programs::links::LinkError
pub aya::programs::links::LinkError::InvalidLink pub aya::programs::links::LinkError::InvalidLink
pub aya::programs::links::LinkError::SyscallError(crate::sys::SyscallError) pub aya::programs::links::LinkError::SyscallError(aya::sys::SyscallError)
impl core::convert::From<aya::sys::SyscallError> for aya::programs::links::LinkError
pub fn aya::programs::links::LinkError::from(source: aya::sys::SyscallError) -> Self
impl core::error::Error for aya::programs::links::LinkError impl core::error::Error for aya::programs::links::LinkError
pub fn aya::programs::links::LinkError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)> pub fn aya::programs::links::LinkError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)>
impl core::fmt::Debug for aya::programs::links::LinkError impl core::fmt::Debug for aya::programs::links::LinkError
@ -6824,7 +6830,7 @@ pub aya::programs::ProgramError::MapError(aya::maps::MapError)
pub aya::programs::ProgramError::NotAttached pub aya::programs::ProgramError::NotAttached
pub aya::programs::ProgramError::NotLoaded pub aya::programs::ProgramError::NotLoaded
pub aya::programs::ProgramError::SocketFilterError(aya::programs::socket_filter::SocketFilterError) pub aya::programs::ProgramError::SocketFilterError(aya::programs::socket_filter::SocketFilterError)
pub aya::programs::ProgramError::SyscallError(crate::sys::SyscallError) pub aya::programs::ProgramError::SyscallError(aya::sys::SyscallError)
pub aya::programs::ProgramError::TcError(aya::programs::tc::TcError) pub aya::programs::ProgramError::TcError(aya::programs::tc::TcError)
pub aya::programs::ProgramError::TracePointError(aya::programs::trace_point::TracePointError) pub aya::programs::ProgramError::TracePointError(aya::programs::trace_point::TracePointError)
pub aya::programs::ProgramError::UProbeError(aya::programs::uprobe::UProbeError) pub aya::programs::ProgramError::UProbeError(aya::programs::uprobe::UProbeError)
@ -6850,6 +6856,8 @@ impl core::convert::From<aya::programs::uprobe::UProbeError> for aya::programs::
pub fn aya::programs::ProgramError::from(source: aya::programs::uprobe::UProbeError) -> Self pub fn aya::programs::ProgramError::from(source: aya::programs::uprobe::UProbeError) -> Self
impl core::convert::From<aya::programs::xdp::XdpError> for aya::programs::ProgramError impl core::convert::From<aya::programs::xdp::XdpError> for aya::programs::ProgramError
pub fn aya::programs::ProgramError::from(source: aya::programs::xdp::XdpError) -> Self pub fn aya::programs::ProgramError::from(source: aya::programs::xdp::XdpError) -> Self
impl core::convert::From<aya::sys::SyscallError> for aya::programs::ProgramError
pub fn aya::programs::ProgramError::from(source: aya::sys::SyscallError) -> Self
impl core::convert::From<aya_obj::btf::btf::BtfError> for aya::programs::ProgramError impl core::convert::From<aya_obj::btf::btf::BtfError> for aya::programs::ProgramError
pub fn aya::programs::ProgramError::from(source: aya_obj::btf::btf::BtfError) -> Self pub fn aya::programs::ProgramError::from(source: aya_obj::btf::btf::BtfError) -> Self
impl core::convert::From<std::io::error::Error> for aya::programs::ProgramError impl core::convert::From<std::io::error::Error> for aya::programs::ProgramError
@ -8660,6 +8668,86 @@ pub type aya::programs::xdp::XdpLink::Id = aya::programs::xdp::XdpLinkId
pub fn aya::programs::xdp::XdpLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::xdp::XdpLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError>
pub fn aya::programs::xdp::XdpLink::id(&self) -> Self::Id pub fn aya::programs::xdp::XdpLink::id(&self) -> Self::Id
pub fn aya::programs::loaded_programs() -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>> pub fn aya::programs::loaded_programs() -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>>
pub mod aya::sys
#[non_exhaustive] pub enum aya::sys::Stats
pub aya::sys::Stats::RunTime
impl core::clone::Clone for aya::sys::Stats
pub fn aya::sys::Stats::clone(&self) -> aya::sys::Stats
impl core::convert::From<aya::sys::Stats> for aya_obj::generated::linux_bindings_x86_64::bpf_stats_type
pub fn aya_obj::generated::linux_bindings_x86_64::bpf_stats_type::from(value: aya::sys::Stats) -> Self
impl core::fmt::Debug for aya::sys::Stats
pub fn aya::sys::Stats::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Copy for aya::sys::Stats
impl core::marker::Freeze for aya::sys::Stats
impl core::marker::Send for aya::sys::Stats
impl core::marker::Sync for aya::sys::Stats
impl core::marker::Unpin for aya::sys::Stats
impl core::panic::unwind_safe::RefUnwindSafe for aya::sys::Stats
impl core::panic::unwind_safe::UnwindSafe for aya::sys::Stats
impl<T, U> core::convert::Into<U> for aya::sys::Stats where U: core::convert::From<T>
pub fn aya::sys::Stats::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::sys::Stats where U: core::convert::Into<T>
pub type aya::sys::Stats::Error = core::convert::Infallible
pub fn aya::sys::Stats::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::sys::Stats where U: core::convert::TryFrom<T>
pub type aya::sys::Stats::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::sys::Stats::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::borrow::ToOwned for aya::sys::Stats where T: core::clone::Clone
pub type aya::sys::Stats::Owned = T
pub fn aya::sys::Stats::clone_into(&self, target: &mut T)
pub fn aya::sys::Stats::to_owned(&self) -> T
impl<T> core::any::Any for aya::sys::Stats where T: 'static + core::marker::Sized
pub fn aya::sys::Stats::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::sys::Stats where T: core::marker::Sized
pub fn aya::sys::Stats::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::sys::Stats where T: core::marker::Sized
pub fn aya::sys::Stats::borrow_mut(&mut self) -> &mut T
impl<T> core::clone::CloneToUninit for aya::sys::Stats where T: core::clone::Clone
pub unsafe fn aya::sys::Stats::clone_to_uninit(&self, dst: *mut T)
impl<T> core::convert::From<T> for aya::sys::Stats
pub fn aya::sys::Stats::from(t: T) -> T
pub struct aya::sys::SyscallError
pub aya::sys::SyscallError::call: &'static str
pub aya::sys::SyscallError::io_error: std::io::error::Error
impl core::convert::From<aya::sys::SyscallError> for aya::maps::MapError
pub fn aya::maps::MapError::from(source: aya::sys::SyscallError) -> Self
impl core::convert::From<aya::sys::SyscallError> for aya::pin::PinError
pub fn aya::pin::PinError::from(source: aya::sys::SyscallError) -> Self
impl core::convert::From<aya::sys::SyscallError> for aya::programs::ProgramError
pub fn aya::programs::ProgramError::from(source: aya::sys::SyscallError) -> Self
impl core::convert::From<aya::sys::SyscallError> for aya::programs::links::LinkError
pub fn aya::programs::links::LinkError::from(source: aya::sys::SyscallError) -> Self
impl core::error::Error for aya::sys::SyscallError
pub fn aya::sys::SyscallError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)>
impl core::fmt::Debug for aya::sys::SyscallError
pub fn aya::sys::SyscallError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::fmt::Display for aya::sys::SyscallError
pub fn aya::sys::SyscallError::fmt(&self, __formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Freeze for aya::sys::SyscallError
impl core::marker::Send for aya::sys::SyscallError
impl core::marker::Sync for aya::sys::SyscallError
impl core::marker::Unpin for aya::sys::SyscallError
impl !core::panic::unwind_safe::RefUnwindSafe for aya::sys::SyscallError
impl !core::panic::unwind_safe::UnwindSafe for aya::sys::SyscallError
impl<T, U> core::convert::Into<U> for aya::sys::SyscallError where U: core::convert::From<T>
pub fn aya::sys::SyscallError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::sys::SyscallError where U: core::convert::Into<T>
pub type aya::sys::SyscallError::Error = core::convert::Infallible
pub fn aya::sys::SyscallError::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::sys::SyscallError where U: core::convert::TryFrom<T>
pub type aya::sys::SyscallError::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::sys::SyscallError::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::string::ToString for aya::sys::SyscallError where T: core::fmt::Display + core::marker::Sized
pub fn aya::sys::SyscallError::to_string(&self) -> alloc::string::String
impl<T> core::any::Any for aya::sys::SyscallError where T: 'static + core::marker::Sized
pub fn aya::sys::SyscallError::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::sys::SyscallError where T: core::marker::Sized
pub fn aya::sys::SyscallError::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::sys::SyscallError where T: core::marker::Sized
pub fn aya::sys::SyscallError::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::sys::SyscallError
pub fn aya::sys::SyscallError::from(t: T) -> T
pub fn aya::sys::enable_stats(stats_type: aya::sys::Stats) -> core::result::Result<std::os::fd::owned::OwnedFd, aya::sys::SyscallError>
pub mod aya::util pub mod aya::util
pub struct aya::util::KernelVersion pub struct aya::util::KernelVersion
impl aya::util::KernelVersion impl aya::util::KernelVersion

Loading…
Cancel
Save