Skip to content

Fix cgroup-skb-egress for new perf event array API#268

Merged
tamird merged 1 commit into
aya-rs:mainfrom
Brskt:fix-perf-event-array-api
May 5, 2026
Merged

Fix cgroup-skb-egress for new perf event array API#268
tamird merged 1 commit into
aya-rs:mainfrom
Brskt:fix-perf-event-array-api

Conversation

@Brskt
Copy link
Copy Markdown
Contributor

@Brskt Brskt commented May 5, 2026

PR aya-rs/aya#1554 replaced read_events with for_each; the
cgroup-skb-egress example no longer compiles. Migrate to the new
closure API and concat head + tail to handle samples that wrap
the ring boundary.


This change is Reviewable

@netlify
Copy link
Copy Markdown

netlify Bot commented May 5, 2026

Deploy Preview for aya-rs ready!

Name Link
🔨 Latest commit 3d10076
🔍 Latest deploy log https://app.netlify.com/projects/aya-rs/deploys/69fa519272ad9100098d8383
😎 Deploy Preview https://deploy-preview-268--aya-rs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Member

@tamird tamird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tamird reviewed 1 file and all commit messages, and made 1 comment.
Reviewable status: 1 of 2 files reviewed, 1 unresolved discussion (waiting on Brskt).


examples/cgroup-skb-egress/cgroup-skb-egress/src/main.rs line 73 at r1 (raw file):

                    PerfEvent::Sample { head, tail } => {
                        // Samples can straddle the ring's wrap boundary; copy a contiguous window.
                        const N: usize = size_of::<PacketLog>();

PacketLog is Pod, right? Currently we are copying this twice: once from the sample to the stack buffer and then again into the PacketLog. Perhaps instead we could use MaybeUnint<PacketLog>? We would probably want https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_bytes_mut here but that's unstable so we can leave a TODO and use a handwritten implementation for now.

WDYT?

@Brskt Brskt force-pushed the fix-perf-event-array-api branch from 327e1fc to 39094f8 Compare May 5, 2026 18:44
Copy link
Copy Markdown
Contributor Author

@Brskt Brskt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Brskt made 1 comment.
Reviewable status: 1 of 2 files reviewed, 1 unresolved discussion (waiting on tamird).


examples/cgroup-skb-egress/cgroup-skb-egress/src/main.rs line 73 at r1 (raw file):

Previously, tamird (Tamir Duberstein) wrote…

PacketLog is Pod, right? Currently we are copying this twice: once from the sample to the stack buffer and then again into the PacketLog. Perhaps instead we could use MaybeUnint<PacketLog>? We would probably want https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_bytes_mut here but that's unstable so we can leave a TODO and use a handwritten implementation for now.

WDYT?

Sure, looks good via Pod. Done with a small as_bytes_mut shim and a TODO.

Copy link
Copy Markdown
Member

@tamird tamird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tamird reviewed all commit messages, made 1 comment, and resolved 1 discussion.
Reviewable status: 1 of 2 files reviewed, 1 unresolved discussion (waiting on Brskt).


examples/cgroup-skb-egress/cgroup-skb-egress/src/main.rs line 103 at r2 (raw file):

                            );
                            data.assume_init()
                        };

Could we do something like

let bytes = as_bytes_mut(&mut data);
for (src, dst) in head.iter().chain(tail.iter()).zip(bytes) {
  dst.write(src);
}

otherwise if you want to copy through the pointer then you can just write

let mut data = MaybeUninit::<PacketLog>::uninit();
let dst = data.as_mut_ptr().cast::<u8>();
...

Code quote:

                        let bytes = as_bytes_mut(&mut data);
                        let head_len = head.len().min(bytes.len());
                        let dst = bytes.as_mut_ptr().cast::<u8>();
                        // SAFETY: source and destination are non-overlapping, and the writes
                        // cover all of `bytes`; PacketLog is Pod so any byte pattern is valid.
                        let data = unsafe {
                            std::ptr::copy_nonoverlapping(
                                head.as_ptr(),
                                dst,
                                head_len,
                            );
                            std::ptr::copy_nonoverlapping(
                                tail.as_ptr(),
                                dst.add(head_len),
                                bytes.len() - head_len,
                            );
                            data.assume_init()
                        };

aya replaced PerfEventArrayBuffer::read_events with closure-based
try_fold/fold/for_each that yields PerfEvent::Sample{head, tail}
borrowed from the kernel ring. Drain the buffer in one closure call
and write the wrap-aware payload into a MaybeUninit<PacketLog> before
calling assume_init, since samples can straddle the ring's wrap boundary.

Drop the bytes dependency (BytesMut was the only consumer) and surface
PerfEvent::Lost via warn!.
@Brskt Brskt force-pushed the fix-perf-event-array-api branch from 39094f8 to 3d10076 Compare May 5, 2026 20:22
Copy link
Copy Markdown
Contributor Author

@Brskt Brskt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Brskt made 1 comment.
Reviewable status: 1 of 2 files reviewed, 1 unresolved discussion (waiting on tamird).


examples/cgroup-skb-egress/cgroup-skb-egress/src/main.rs line 103 at r2 (raw file):

Previously, tamird (Tamir Duberstein) wrote…

Could we do something like

let bytes = as_bytes_mut(&mut data);
for (src, dst) in head.iter().chain(tail.iter()).zip(bytes) {
  dst.write(src);
}

otherwise if you want to copy through the pointer then you can just write

let mut data = MaybeUninit::<PacketLog>::uninit();
let dst = data.as_mut_ptr().cast::<u8>();
...

Yeah, the iterator path is cleaner. Done with a debug_assert_eq! for the kernel invariant.

Copy link
Copy Markdown
Member

@tamird tamird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@tamird reviewed 1 file and all commit messages, made 1 comment, and resolved 1 discussion.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on Brskt).

@tamird tamird merged commit 3fb1e05 into aya-rs:main May 5, 2026
6 checks passed
@Brskt Brskt deleted the fix-perf-event-array-api branch May 6, 2026 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants