perf_map: split in sub modules

pull/1/head
Alessandro Decina 4 years ago
parent 95a24c6f8b
commit 4be0c45305

@ -0,0 +1,5 @@
mod perf_buffer;
mod perf_map;
pub use perf_buffer::*;
pub use perf_map::*;

@ -1,29 +1,18 @@
use std::{
convert::TryFrom,
ffi::c_void,
io, mem,
ops::DerefMut,
os::unix::prelude::AsRawFd,
ptr, slice,
sync::{
atomic::{self, AtomicPtr, Ordering},
Arc,
},
sync::atomic::{self, AtomicPtr, Ordering},
};
use bytes::BytesMut;
use libc::{
c_int, close, munmap, sysconf, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE, _SC_PAGESIZE,
};
use libc::{c_int, close, munmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE};
use thiserror::Error;
use crate::{
generated::{
bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY, perf_event_header, perf_event_mmap_page,
perf_event_type::*,
},
maps::{Map, MapError, MapLockWriteGuard},
sys::{bpf_map_update_elem, perf_event_ioctl, perf_event_open},
generated::{perf_event_header, perf_event_mmap_page, perf_event_type::*},
sys::{perf_event_ioctl, perf_event_open},
RawFd, PERF_EVENT_IOC_DISABLE, PERF_EVENT_IOC_ENABLE,
};
@ -66,7 +55,7 @@ pub struct Events {
pub lost: usize,
}
struct PerfBuffer {
pub(crate) struct PerfBuffer {
buf: AtomicPtr<perf_event_mmap_page>,
size: usize,
page_size: usize,
@ -74,7 +63,7 @@ struct PerfBuffer {
}
impl PerfBuffer {
fn open(
pub(crate) fn open(
cpu_id: u32,
page_size: usize,
page_count: usize,
@ -259,98 +248,6 @@ impl Drop for PerfBuffer {
}
}
#[derive(Error, Debug)]
pub enum PerfMapError {
#[error("error parsing /sys/devices/system/cpu/online")]
InvalidOnlineCpuFile,
#[error("no CPUs specified")]
NoCpus,
#[error("invalid cpu {cpu_id}")]
InvalidCpu { cpu_id: u32 },
#[error("map error: {0}")]
MapError(#[from] MapError),
#[error("perf buffer error: {0}")]
PerfBufferError(#[from] PerfBufferError),
#[error(transparent)]
IOError(#[from] io::Error),
#[error("bpf_map_update_elem failed: {io_error}")]
UpdateElementError {
#[source]
io_error: io::Error,
},
}
pub struct PerfMapBuffer<T: DerefMut<Target = Map>> {
_map: Arc<T>,
buf: PerfBuffer,
}
impl<T: DerefMut<Target = Map>> PerfMapBuffer<T> {
pub fn read_events(&mut self, buffers: &mut [BytesMut]) -> Result<Events, PerfBufferError> {
self.buf.read_events(buffers)
}
}
impl<T: DerefMut<Target = Map>> AsRawFd for PerfMapBuffer<T> {
fn as_raw_fd(&self) -> RawFd {
self.buf.as_raw_fd()
}
}
pub struct PerfMap<T: DerefMut<Target = Map>> {
map: Arc<T>,
page_size: usize,
}
impl<T: DerefMut<Target = Map>> PerfMap<T> {
pub fn new(map: T) -> Result<PerfMap<T>, PerfMapError> {
let map_type = map.obj.def.map_type;
if map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY {
return Err(MapError::InvalidMapType {
map_type: map_type as u32,
})?;
}
Ok(PerfMap {
map: Arc::new(map),
// Safety: libc
page_size: unsafe { sysconf(_SC_PAGESIZE) } as usize,
})
}
pub fn open(
&mut self,
index: u32,
page_count: Option<usize>,
) -> Result<PerfMapBuffer<T>, PerfMapError> {
// FIXME: keep track of open buffers
let map_fd = self.map.fd_or_err()?;
let buf = PerfBuffer::open(index, self.page_size, page_count.unwrap_or(2))?;
bpf_map_update_elem(map_fd, &index, &buf.fd, 0)
.map_err(|(_, io_error)| PerfMapError::UpdateElementError { io_error })?;
Ok(PerfMapBuffer {
buf,
_map: self.map.clone(),
})
}
}
impl TryFrom<MapLockWriteGuard> for PerfMap<MapLockWriteGuard> {
type Error = PerfMapError;
fn try_from(a: MapLockWriteGuard) -> Result<PerfMap<MapLockWriteGuard>, PerfMapError> {
PerfMap::new(a)
}
}
#[cfg_attr(test, allow(unused_variables))]
unsafe fn mmap(
addr: *mut c_void,

@ -1,10 +1,4 @@
use std::{
convert::TryFrom,
io,
ops::DerefMut,
os::unix::io::{AsRawFd, RawFd},
sync::Arc,
};
use std::{convert::TryFrom, io, ops::DerefMut, os::unix::prelude::AsRawFd, sync::Arc};
use bytes::BytesMut;
use libc::{sysconf, _SC_PAGESIZE};
@ -12,11 +6,10 @@ use thiserror::Error;
use crate::{
generated::bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY,
maps::{
perf_map::{Events, PerfBuffer, PerfBufferError},
Map, MapError, MapRefMut,
},
maps::perf_map::{Events, PerfBuffer, PerfBufferError},
maps::{Map, MapError, MapRefMut},
sys::bpf_map_update_elem,
RawFd,
};
#[derive(Error, Debug)]
@ -52,10 +45,6 @@ pub struct PerfMapBuffer<T: DerefMut<Target = Map>> {
}
impl<T: DerefMut<Target = Map>> PerfMapBuffer<T> {
pub fn readable(&self) -> bool {
self.buf.readable()
}
pub fn read_events(&mut self, buffers: &mut [BytesMut]) -> Result<Events, PerfBufferError> {
self.buf.read_events(buffers)
}
@ -75,12 +64,11 @@ pub struct PerfMap<T: DerefMut<Target = Map>> {
impl<T: DerefMut<Target = Map>> PerfMap<T> {
pub fn new(map: T) -> Result<PerfMap<T>, PerfMapError> {
let map_type = map.obj.def.map_type;
if map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32 {
if map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY {
return Err(MapError::InvalidMapType {
map_type: map_type as u32,
})?;
}
let _fd = map.fd_or_err()?;
Ok(PerfMap {
map: Arc::new(map),

Loading…
Cancel
Save