Skip to content

Commit

Permalink
Merge pull request #701 from nrxus/perf-event-owned-fd
Browse files Browse the repository at this point in the history
aya: Return `OwnedFd` for `perf_event_open`.
  • Loading branch information
tamird committed Jul 31, 2023
2 parents e833a71 + dbfba18 commit 445cb8b
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 75 deletions.
30 changes: 17 additions & 13 deletions aya/src/maps/perf/perf_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use std::{
ffi::c_void,
io, mem,
os::fd::{AsRawFd, RawFd},
os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd},
ptr, slice,
sync::atomic::{self, AtomicPtr, Ordering},
};

use bytes::BytesMut;
use libc::{c_int, close, munmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE};
use libc::{c_int, munmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE};
use thiserror::Error;

use crate::{
generated::{
perf_event_header, perf_event_mmap_page,
perf_event_type::{PERF_RECORD_LOST, PERF_RECORD_SAMPLE},
},
sys::{perf_event_ioctl, perf_event_open_bpf},
sys::{perf_event_ioctl, perf_event_open_bpf, SysResult},
PERF_EVENT_IOC_DISABLE, PERF_EVENT_IOC_ENABLE,
};

Expand Down Expand Up @@ -88,7 +88,7 @@ pub(crate) struct PerfBuffer {
buf: AtomicPtr<perf_event_mmap_page>,
size: usize,
page_size: usize,
fd: RawFd,
fd: OwnedFd,
}

impl PerfBuffer {
Expand All @@ -102,16 +102,15 @@ impl PerfBuffer {
}

let fd = perf_event_open_bpf(cpu_id as i32)
.map_err(|(_, io_error)| PerfBufferError::OpenError { io_error })?
as RawFd;
.map_err(|(_, io_error)| PerfBufferError::OpenError { io_error })?;
let size = page_size * page_count;
let buf = unsafe {
mmap(
ptr::null_mut(),
size + page_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
fd.as_fd(),
0,
)
};
Expand All @@ -128,7 +127,7 @@ impl PerfBuffer {
page_size,
};

perf_event_ioctl(fd, PERF_EVENT_IOC_ENABLE, 0)
perf_event_ioctl(perf_buf.fd.as_fd(), PERF_EVENT_IOC_ENABLE, 0)
.map_err(|(_, io_error)| PerfBufferError::PerfEventEnableError { io_error })?;

Ok(perf_buf)
Expand Down Expand Up @@ -261,19 +260,24 @@ impl PerfBuffer {

impl AsRawFd for PerfBuffer {
fn as_raw_fd(&self) -> RawFd {
self.fd
self.fd.as_raw_fd()
}
}

impl AsFd for PerfBuffer {
fn as_fd(&self) -> BorrowedFd<'_> {
self.fd.as_fd()
}
}

impl Drop for PerfBuffer {
fn drop(&mut self) {
unsafe {
let _ = perf_event_ioctl(self.fd, PERF_EVENT_IOC_DISABLE, 0);
let _: SysResult<_> = perf_event_ioctl(self.fd.as_fd(), PERF_EVENT_IOC_DISABLE, 0);
munmap(
self.buf.load(Ordering::SeqCst) as *mut c_void,
self.size + self.page_size,
);
close(self.fd);
}
}
}
Expand All @@ -284,11 +288,11 @@ unsafe fn mmap(
len: usize,
prot: c_int,
flags: c_int,
fd: i32,
fd: BorrowedFd<'_>,
offset: libc::off_t,
) -> *mut c_void {
#[cfg(not(test))]
return libc::mmap(addr, len, prot, flags, fd, offset);
return libc::mmap(addr, len, prot, flags, fd.as_raw_fd(), offset);

#[cfg(test)]
use crate::sys::TEST_MMAP_RET;
Expand Down
37 changes: 17 additions & 20 deletions aya/src/programs/perf_attach.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//! Perf attach links.
use libc::close;
use std::os::fd::RawFd;
use std::os::fd::{AsFd as _, AsRawFd as _, OwnedFd, RawFd};

use crate::{
generated::bpf_attach_type::BPF_PERF_EVENT,
programs::{probe::detach_debug_fs, FdLink, Link, ProbeKind, ProgramError},
sys::{bpf_link_create, perf_event_ioctl},
sys::{bpf_link_create, perf_event_ioctl, SysResult},
FEATURES, PERF_EVENT_IOC_DISABLE, PERF_EVENT_IOC_ENABLE, PERF_EVENT_IOC_SET_BPF,
};

Expand Down Expand Up @@ -46,7 +45,7 @@ pub struct PerfLinkId(RawFd);
/// The attachment type of PerfEvent programs.
#[derive(Debug)]
pub struct PerfLink {
perf_fd: RawFd,
perf_fd: OwnedFd,
probe_kind: Option<ProbeKind>,
event_alias: Option<String>,
}
Expand All @@ -55,32 +54,30 @@ impl Link for PerfLink {
type Id = PerfLinkId;

fn id(&self) -> Self::Id {
PerfLinkId(self.perf_fd)
PerfLinkId(self.perf_fd.as_raw_fd())
}

fn detach(mut self) -> Result<(), ProgramError> {
let _ = perf_event_ioctl(self.perf_fd, PERF_EVENT_IOC_DISABLE, 0);
unsafe { close(self.perf_fd) };
let _: SysResult<_> = perf_event_ioctl(self.perf_fd.as_fd(), PERF_EVENT_IOC_DISABLE, 0);

if let Some(probe_kind) = self.probe_kind.take() {
if let Some(event_alias) = self.event_alias.take() {
let _ = detach_debug_fs(probe_kind, &event_alias);
let _: Result<_, _> = detach_debug_fs(probe_kind, &event_alias);
}
}

Ok(())
}
}

pub(crate) fn perf_attach(prog_fd: RawFd, fd: RawFd) -> Result<PerfLinkInner, ProgramError> {
pub(crate) fn perf_attach(prog_fd: RawFd, fd: OwnedFd) -> Result<PerfLinkInner, ProgramError> {
if FEATURES.bpf_perf_link() {
let link_fd =
bpf_link_create(prog_fd, fd, BPF_PERF_EVENT, None, 0).map_err(|(_, io_error)| {
ProgramError::SyscallError {
call: "bpf_link_create",
io_error,
}
})? as RawFd;
let link_fd = bpf_link_create(prog_fd, fd.as_raw_fd(), BPF_PERF_EVENT, None, 0).map_err(
|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create",
io_error,
},
)? as RawFd;
Ok(PerfLinkInner::FdLink(FdLink::new(link_fd)))
} else {
perf_attach_either(prog_fd, fd, None, None)
Expand All @@ -89,7 +86,7 @@ pub(crate) fn perf_attach(prog_fd: RawFd, fd: RawFd) -> Result<PerfLinkInner, Pr

pub(crate) fn perf_attach_debugfs(
prog_fd: RawFd,
fd: RawFd,
fd: OwnedFd,
probe_kind: ProbeKind,
event_alias: String,
) -> Result<PerfLinkInner, ProgramError> {
Expand All @@ -98,17 +95,17 @@ pub(crate) fn perf_attach_debugfs(

fn perf_attach_either(
prog_fd: RawFd,
fd: RawFd,
fd: OwnedFd,
probe_kind: Option<ProbeKind>,
event_alias: Option<String>,
) -> Result<PerfLinkInner, ProgramError> {
perf_event_ioctl(fd, PERF_EVENT_IOC_SET_BPF, prog_fd).map_err(|(_, io_error)| {
perf_event_ioctl(fd.as_fd(), PERF_EVENT_IOC_SET_BPF, prog_fd).map_err(|(_, io_error)| {
ProgramError::SyscallError {
call: "PERF_EVENT_IOC_SET_BPF",
io_error,
}
})?;
perf_event_ioctl(fd, PERF_EVENT_IOC_ENABLE, 0).map_err(|(_, io_error)| {
perf_event_ioctl(fd.as_fd(), PERF_EVENT_IOC_ENABLE, 0).map_err(|(_, io_error)| {
ProgramError::SyscallError {
call: "PERF_EVENT_IOC_ENABLE",
io_error,
Expand Down
2 changes: 1 addition & 1 deletion aya/src/programs/perf_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl PerfEvent {
.map_err(|(_code, io_error)| ProgramError::SyscallError {
call: "perf_event_open",
io_error,
})? as i32;
})?;

let link = perf_attach(self.data.fd_or_err()?, fd)?;
self.data.links.insert(PerfEventLink::new(link))
Expand Down
17 changes: 8 additions & 9 deletions aya/src/programs/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use libc::pid_t;
use std::{
fs::{self, OpenOptions},
io::{self, Write},
os::fd::OwnedFd,
path::Path,
process,
sync::atomic::{AtomicUsize, Ordering},
Expand Down Expand Up @@ -86,7 +87,7 @@ fn create_as_probe(
fn_name: &str,
offset: u64,
pid: Option<pid_t>,
) -> Result<i32, ProgramError> {
) -> Result<OwnedFd, ProgramError> {
use ProbeKind::*;

let perf_ty = match kind {
Expand All @@ -108,22 +109,20 @@ fn create_as_probe(
_ => None,
};

let fd = perf_event_open_probe(perf_ty, ret_bit, fn_name, offset, pid).map_err(
|(_code, io_error)| ProgramError::SyscallError {
perf_event_open_probe(perf_ty, ret_bit, fn_name, offset, pid).map_err(|(_code, io_error)| {
ProgramError::SyscallError {
call: "perf_event_open",
io_error,
},
)? as i32;

Ok(fd)
}
})
}

fn create_as_trace_point(
kind: ProbeKind,
name: &str,
offset: u64,
pid: Option<pid_t>,
) -> Result<(i32, String), ProgramError> {
) -> Result<(OwnedFd, String), ProgramError> {
use ProbeKind::*;

let tracefs = find_tracefs_path()?;
Expand All @@ -142,7 +141,7 @@ fn create_as_trace_point(
call: "perf_event_open",
io_error,
}
})? as i32;
})?;

Ok((fd, event_alias))
}
Expand Down
4 changes: 2 additions & 2 deletions aya/src/programs/trace_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ impl TracePoint {
let id = read_sys_fs_trace_point_id(tracefs, category, name)?;
let fd = perf_event_open_trace_point(id, None).map_err(|(_code, io_error)| {
ProgramError::SyscallError {
call: "perf_event_open",
call: "perf_event_open_trace_point",
io_error,
}
})? as i32;
})?;

let link = perf_attach(self.data.fd_or_err()?, fd)?;
self.data.links.insert(TracePointLink::new(link))
Expand Down
9 changes: 6 additions & 3 deletions aya/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ mod perf_event;
#[cfg(test)]
mod fake;

use std::{io, mem};
use std::{
io, mem,
os::fd::{AsRawFd as _, BorrowedFd},
};

use libc::{c_int, c_long, pid_t, SYS_bpf, SYS_perf_event_open};

Expand Down Expand Up @@ -34,7 +37,7 @@ pub(crate) enum Syscall<'a> {
flags: u32,
},
PerfEventIoctl {
fd: c_int,
fd: BorrowedFd<'a>,
request: c_int,
arg: c_int,
},
Expand Down Expand Up @@ -90,7 +93,7 @@ fn syscall(call: Syscall) -> SysResult<c_long> {
flags,
} => libc::syscall(SYS_perf_event_open, &attr, pid, cpu, group, flags),
Syscall::PerfEventIoctl { fd, request, arg } => {
libc::ioctl(fd, request.try_into().unwrap(), arg) as libc::c_long
libc::ioctl(fd.as_raw_fd(), request.try_into().unwrap(), arg) as libc::c_long
}
}
} {
Expand Down
Loading

0 comments on commit 445cb8b

Please sign in to comment.