Skip to content

Commit 460cb92

Browse files
josefbacikd-e-s-o
authored andcommitted
libbpf-rs: add attach_perf_event_with_opts hook
In order to easily provide the ability to attach cookies to perf events, add a hook for libbf's bpf_program__attach_perf_event_opts. Signed-off-by: Josef Bacik <[email protected]>
1 parent fbe4ffc commit 460cb92

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

libbpf-rs/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Unreleased
1313
- Adjusted `UprobeOpts::func_name` to be an `Option`
1414
- Implemented `Sync` for `Link`
1515
- Updated `libbpf-sys` dependency to `1.5.0`
16+
- Added `Program::attach_perf_event_with_opts` for attaching to perf events.
1617

1718

1819
0.25.0-beta.1

libbpf-rs/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ pub use crate::program::OpenProgram;
149149
pub use crate::program::OpenProgramImpl;
150150
pub use crate::program::OpenProgramMut;
151151
pub use crate::program::Output as ProgramOutput;
152+
pub use crate::program::PerfEventOpts;
152153
pub use crate::program::Program;
153154
pub use crate::program::ProgramAttachType;
154155
pub use crate::program::ProgramImpl;

libbpf-rs/src/program.rs

+46
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,35 @@ pub struct KprobeMultiOpts {
129129
pub _non_exhaustive: (),
130130
}
131131

132+
/// Options to optionally be provided when attaching to a perf event.
133+
#[derive(Clone, Debug, Default)]
134+
pub struct PerfEventOpts {
135+
/// Custom user-provided value accessible through `bpf_get_attach_cookie`.
136+
pub cookie: u64,
137+
/// Force use of the old style ioctl attachment instead of the newer BPF link method.
138+
pub force_ioctl_attach: bool,
139+
#[doc(hidden)]
140+
pub _non_exhaustive: (),
141+
}
142+
143+
impl From<PerfEventOpts> for libbpf_sys::bpf_perf_event_opts {
144+
fn from(opts: PerfEventOpts) -> Self {
145+
let PerfEventOpts {
146+
cookie,
147+
force_ioctl_attach,
148+
_non_exhaustive,
149+
} = opts;
150+
151+
#[allow(clippy::needless_update)]
152+
libbpf_sys::bpf_perf_event_opts {
153+
sz: size_of::<Self>() as _,
154+
bpf_cookie: cookie,
155+
force_ioctl_attach,
156+
// bpf_perf_event_opts might have padding fields on some platform
157+
..Default::default()
158+
}
159+
}
160+
}
132161

133162
/// An immutable parsed but not yet loaded BPF program.
134163
pub type OpenProgram<'obj> = OpenProgramImpl<'obj>;
@@ -818,6 +847,23 @@ impl<'obj> ProgramMut<'obj> {
818847
Ok(link)
819848
}
820849

850+
/// Attach this program to a [perf event](https://linux.die.net/man/2/perf_event_open),
851+
/// providing additional options.
852+
pub fn attach_perf_event_with_opts(&self, pfd: i32, opts: PerfEventOpts) -> Result<Link> {
853+
let libbpf_opts = libbpf_sys::bpf_perf_event_opts::from(opts);
854+
let ptr = unsafe {
855+
libbpf_sys::bpf_program__attach_perf_event_opts(
856+
self.ptr.as_ptr(),
857+
pfd,
858+
&libbpf_opts as *const _,
859+
)
860+
};
861+
let ptr = validate_bpf_ret(ptr).context("failed to attach perf event")?;
862+
// SAFETY: the pointer came from libbpf and has been checked for errors.
863+
let link = unsafe { Link::new(ptr) };
864+
Ok(link)
865+
}
866+
821867
/// Attach this program to a [userspace
822868
/// probe](https://www.kernel.org/doc/html/latest/trace/uprobetracer.html).
823869
pub fn attach_uprobe<T: AsRef<Path>>(

0 commit comments

Comments
 (0)