From 3aded0e0a5c644569b0a268ea31c6c0edddea3b2 Mon Sep 17 00:00:00 2001 From: Omri Steiner Date: Fri, 2 May 2025 17:30:04 +0200 Subject: [PATCH] aya: move Mmap struct to aya::util --- aya/src/maps/mod.rs | 62 +-------------------------- aya/src/maps/perf/perf_buffer.rs | 4 +- aya/src/maps/ring_buf.rs | 11 ++--- aya/src/util.rs | 72 ++++++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 72 deletions(-) diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index 849b14bc..21bb2b4c 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -60,9 +60,7 @@ use std::{ }; use aya_obj::{EbpfSectionKind, InvalidTypeBinding, generated::bpf_map_type, parse_map_info}; -use libc::{ - MAP_FAILED, RLIM_INFINITY, RLIMIT_MEMLOCK, c_int, c_void, getrlimit, off_t, rlim_t, rlimit, -}; +use libc::{RLIM_INFINITY, RLIMIT_MEMLOCK, getrlimit, rlim_t, rlimit}; use log::warn; use thiserror::Error; @@ -71,7 +69,7 @@ use crate::{ pin::PinError, sys::{ SyscallError, bpf_create_map, bpf_get_object, bpf_map_freeze, bpf_map_get_fd_by_id, - bpf_map_get_next_key, bpf_map_update_elem_ptr, bpf_pin_object, mmap, munmap, + bpf_map_get_next_key, bpf_map_update_elem_ptr, bpf_pin_object, }, util::{KernelVersion, nr_cpus}, }; @@ -944,62 +942,6 @@ impl Deref for PerCpuValues { } } -// MMap corresponds to a memory-mapped region. -// -// The data is unmapped in Drop. -#[cfg_attr(test, derive(Debug))] -struct MMap { - ptr: ptr::NonNull, - len: usize, -} - -// Needed because NonNull is !Send and !Sync out of caution that the data -// might be aliased unsafely. -unsafe impl Send for MMap {} -unsafe impl Sync for MMap {} - -impl MMap { - fn new( - fd: BorrowedFd<'_>, - len: usize, - prot: c_int, - flags: c_int, - offset: off_t, - ) -> Result { - match unsafe { mmap(ptr::null_mut(), len, prot, flags, fd, offset) } { - MAP_FAILED => Err(SyscallError { - call: "mmap", - io_error: io::Error::last_os_error(), - }), - ptr => { - let ptr = ptr::NonNull::new(ptr).ok_or( - // This should never happen, but to be paranoid, and so we never need to talk - // about a null pointer, we check it anyway. - SyscallError { - call: "mmap", - io_error: io::Error::other("mmap returned null pointer"), - }, - )?; - Ok(Self { ptr, len }) - } - } - } -} - -impl AsRef<[u8]> for MMap { - fn as_ref(&self) -> &[u8] { - let Self { ptr, len } = self; - unsafe { std::slice::from_raw_parts(ptr.as_ptr().cast(), *len) } - } -} - -impl Drop for MMap { - fn drop(&mut self) { - let Self { ptr, len } = *self; - unsafe { munmap(ptr.as_ptr(), len) }; - } -} - #[cfg(test)] mod test_utils { use aya_obj::{ diff --git a/aya/src/maps/perf/perf_buffer.rs b/aya/src/maps/perf/perf_buffer.rs index 27554ac7..df0e4974 100644 --- a/aya/src/maps/perf/perf_buffer.rs +++ b/aya/src/maps/perf/perf_buffer.rs @@ -14,8 +14,8 @@ use libc::{MAP_SHARED, PROT_READ, PROT_WRITE}; use thiserror::Error; use crate::{ - maps::MMap, sys::{PerfEventIoctlRequest, SyscallError, perf_event_ioctl, perf_event_open_bpf}, + util::MMap, }; /// Perf buffer error. @@ -126,7 +126,7 @@ impl PerfBuffer { } fn buf(&self) -> ptr::NonNull { - self.mmap.ptr.cast() + self.mmap.ptr().cast() } pub(crate) fn readable(&self) -> bool { diff --git a/aya/src/maps/ring_buf.rs b/aya/src/maps/ring_buf.rs index e455329f..de02cc05 100644 --- a/aya/src/maps/ring_buf.rs +++ b/aya/src/maps/ring_buf.rs @@ -17,8 +17,8 @@ use aya_obj::generated::{BPF_RINGBUF_BUSY_BIT, BPF_RINGBUF_DISCARD_BIT, BPF_RING use libc::{MAP_SHARED, PROT_READ, PROT_WRITE}; use crate::{ - maps::{MMap, MapData, MapError}, - util::page_size, + maps::{MapData, MapError}, + util::{MMap, page_size}, }; /// A map that can be used to receive events from eBPF programs. @@ -201,10 +201,7 @@ impl ConsumerMetadata { impl AsRef for ConsumerMetadata { fn as_ref(&self) -> &AtomicUsize { - let Self { - mmap: MMap { ptr, .. }, - } = self; - unsafe { ptr.cast::().as_ref() } + unsafe { self.mmap.ptr().cast::().as_ref() } } } @@ -318,7 +315,7 @@ impl ProducerData { ref mut pos_cache, ref mut mask, } = self; - let pos = unsafe { mmap.ptr.cast().as_ref() }; + let pos = unsafe { mmap.ptr().cast().as_ref() }; let mmap_data = mmap.as_ref(); let data_pages = mmap_data.get(*data_offset..).unwrap_or_else(|| { panic!( diff --git a/aya/src/util.rs b/aya/src/util.rs index cd3b7ac6..30fdb112 100644 --- a/aya/src/util.rs +++ b/aya/src/util.rs @@ -8,15 +8,21 @@ use std::{ io::{self, BufRead, BufReader}, mem, num::ParseIntError, - slice, + os::fd::BorrowedFd, + ptr, slice, str::{FromStr, Utf8Error}, }; use aya_obj::generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK}; -use libc::{_SC_PAGESIZE, if_nametoindex, sysconf, uname, utsname}; +use libc::{ + _SC_PAGESIZE, MAP_FAILED, c_int, c_void, if_nametoindex, off_t, sysconf, uname, utsname, +}; use log::warn; -use crate::Pod; +use crate::{ + Pod, + sys::{SyscallError, mmap, munmap}, +}; /// Represents a kernel version, in major.minor.release version. // Adapted from https://docs.rs/procfs/latest/procfs/sys/kernel/struct.Version.html. @@ -431,6 +437,66 @@ pub(crate) fn bytes_of_bpf_name(bpf_name: &[core::ffi::c_char; 16]) -> &[u8] { unsafe { slice::from_raw_parts(bpf_name.as_ptr() as *const _, length) } } +// MMap corresponds to a memory-mapped region. +// +// The data is unmapped in Drop. +#[cfg_attr(test, derive(Debug))] +pub(crate) struct MMap { + ptr: ptr::NonNull, + len: usize, +} + +// Needed because NonNull is !Send and !Sync out of caution that the data +// might be aliased unsafely. +unsafe impl Send for MMap {} +unsafe impl Sync for MMap {} + +impl MMap { + pub(crate) fn new( + fd: BorrowedFd<'_>, + len: usize, + prot: c_int, + flags: c_int, + offset: off_t, + ) -> Result { + match unsafe { mmap(ptr::null_mut(), len, prot, flags, fd, offset) } { + MAP_FAILED => Err(SyscallError { + call: "mmap", + io_error: io::Error::last_os_error(), + }), + ptr => { + let ptr = ptr::NonNull::new(ptr).ok_or( + // This should never happen, but to be paranoid, and so we never need to talk + // about a null pointer, we check it anyway. + SyscallError { + call: "mmap", + io_error: io::Error::other("mmap returned null pointer"), + }, + )?; + Ok(Self { ptr, len }) + } + } + } + + pub(crate) fn ptr(&self) -> ptr::NonNull { + self.ptr + } +} + +impl AsRef<[u8]> for MMap { + fn as_ref(&self) -> &[u8] { + let Self { ptr, len } = self; + unsafe { std::slice::from_raw_parts(ptr.as_ptr().cast(), *len) } + } +} + +impl Drop for MMap { + fn drop(&mut self) { + let Self { ptr, len } = *self; + unsafe { munmap(ptr.as_ptr(), len) }; + } +} + #[cfg(test)] mod tests { use assert_matches::assert_matches;