From 04ebd3e268daa1adfde6f6bab0503d06df9aa269 Mon Sep 17 00:00:00 2001
From: Alessandro Decina <alessandro.d@gmail.com>
Date: Mon, 29 Jan 2024 21:00:33 +1100
Subject: [PATCH] aya: perf_event: add inherit argument to attach()

---
 aya/src/programs/perf_event.rs | 7 +++++++
 aya/src/sys/perf_event.rs      | 4 +++-
 xtask/public-api/aya.txt       | 4 ++--
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/aya/src/programs/perf_event.rs b/aya/src/programs/perf_event.rs
index b7b233cf..37b7ea4a 100644
--- a/aya/src/programs/perf_event.rs
+++ b/aya/src/programs/perf_event.rs
@@ -115,6 +115,7 @@ pub enum PerfEventScope {
 ///         PERF_COUNT_SW_CPU_CLOCK as u64,
 ///         PerfEventScope::AllProcessesOneCpu { cpu },
 ///         SamplePolicy::Period(1000000),
+///         true,
 ///     )?;
 /// }
 /// # Ok::<(), Error>(())
@@ -137,6 +138,10 @@ impl PerfEvent {
     /// `perf_type`. See `perf_sw_ids`, `perf_hw_id`, `perf_hw_cache_id`,
     /// `perf_hw_cache_op_id` and `perf_hw_cache_op_result_id`.
     ///
+    /// The `scope` argument determines which processes are sampled. If `inherit`
+    /// is true, any new processes spawned by those processes will also
+    /// automatically get sampled.
+    ///
     /// The returned value can be used to detach, see [PerfEvent::detach].
     pub fn attach(
         &mut self,
@@ -144,6 +149,7 @@ impl PerfEvent {
         config: u64,
         scope: PerfEventScope,
         sample_policy: SamplePolicy,
+        inherit: bool,
     ) -> Result<PerfEventLinkId, ProgramError> {
         let prog_fd = self.fd()?;
         let prog_fd = prog_fd.as_fd();
@@ -166,6 +172,7 @@ impl PerfEvent {
             sample_period,
             sample_frequency,
             false,
+            inherit,
             0,
         )
         .map_err(|(_code, io_error)| SyscallError {
diff --git a/aya/src/sys/perf_event.rs b/aya/src/sys/perf_event.rs
index b06f4fba..1d7af608 100644
--- a/aya/src/sys/perf_event.rs
+++ b/aya/src/sys/perf_event.rs
@@ -24,6 +24,7 @@ pub(crate) fn perf_event_open(
     sample_period: u64,
     sample_frequency: Option<u64>,
     wakeup: bool,
+    inherit: bool,
     flags: u32,
 ) -> SysResult<OwnedFd> {
     let mut attr = unsafe { mem::zeroed::<perf_event_attr>() };
@@ -32,7 +33,7 @@ pub(crate) fn perf_event_open(
     attr.size = mem::size_of::<perf_event_attr>() as u32;
     attr.type_ = perf_type;
     attr.sample_type = PERF_SAMPLE_RAW as u64;
-    // attr.inherits = if pid > 0 { 1 } else { 0 };
+    attr.set_inherit(if inherit { 1 } else { 0 });
     attr.__bindgen_anon_2.wakeup_events = u32::from(wakeup);
 
     if let Some(frequency) = sample_frequency {
@@ -54,6 +55,7 @@ pub(crate) fn perf_event_open_bpf(cpu: c_int) -> SysResult<OwnedFd> {
         1,
         None,
         true,
+        false,
         PERF_FLAG_FD_CLOEXEC,
     )
 }
diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt
index 0aa722a5..92f9acb3 100644
--- a/xtask/public-api/aya.txt
+++ b/xtask/public-api/aya.txt
@@ -4300,7 +4300,7 @@ impl<T> core::convert::From<T> for aya::programs::perf_event::SamplePolicy
 pub fn aya::programs::perf_event::SamplePolicy::from(t: T) -> T
 pub struct aya::programs::perf_event::PerfEvent
 impl aya::programs::perf_event::PerfEvent
-pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfTypeId, config: u64, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
+pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfTypeId, config: u64, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::detach(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::take_link(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<aya::programs::perf_event::PerfEventLink, aya::programs::ProgramError>
@@ -6704,7 +6704,7 @@ impl<T> core::convert::From<T> for aya::programs::lsm::Lsm
 pub fn aya::programs::lsm::Lsm::from(t: T) -> T
 pub struct aya::programs::PerfEvent
 impl aya::programs::perf_event::PerfEvent
-pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfTypeId, config: u64, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
+pub fn aya::programs::perf_event::PerfEvent::attach(&mut self, perf_type: aya::programs::perf_event::PerfTypeId, config: u64, scope: aya::programs::perf_event::PerfEventScope, sample_policy: aya::programs::perf_event::SamplePolicy, inherit: bool) -> core::result::Result<aya::programs::perf_event::PerfEventLinkId, aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::detach(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
 pub fn aya::programs::perf_event::PerfEvent::take_link(&mut self, link_id: aya::programs::perf_event::PerfEventLinkId) -> core::result::Result<aya::programs::perf_event::PerfEventLink, aya::programs::ProgramError>