Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Even more minimal support for perf-event sampling #30

Closed
wants to merge 3 commits into from

Conversation

Phantomical
Copy link
Contributor

@Phantomical Phantomical commented Mar 21, 2023

@janaknat's comment on #22 lead to me rethinking some of the design on how to expose sampling. Instead of attempting to parse every possible type of emitted perf record, the solution instead is to not attempt to do any parsing and just expose the raw record bytes. That way people can start off by doing whatever parsing they want themselves and later on support for new message types can be added here on top of the existing sampler.

This PR shares most of its code with #22 with the following changes:

  • Sampler::next now returns a Record type which is a reference into the kernel ring buffer. When dropped, Record advances the tail pointer of the ring buffer.
  • Sampler is now constructed by calling counter.sampled(bufsize) since it no longer needs access to perf_event_attr.
  • All the parsing code introduced in Add minimal support for sampling #22 has now been removed and SampleType has been moved to the crate root.

When viewing the diff I recommend disabling whitespace-only changes (via the github ui or git diff -b) since it hides about 100 lines of indenting that does not have any effect on the behaviour of the code in question.

Commit Message

This commit introduces a minimal but mostly complete form of support for reading sampled perf_event events emitted by the kernel.

New public types being introduced

  • Sampler - A combination of an existing Counter with a memory mapped ring buffer. It is constructed from a Counter by calling sampled and is used to read Records
  • Record - A reference into the kernel ring buffer for a single record that allows accessing the emitted bytes. Upon being dropped, it advances the tail pointer within the ring buffer. It also provides some convenience methods for getting the referenced bytes in owned or contiguous forms.
  • SampleType - This is a set of bitflags which indicate what data the kernel should collect when sampling. It is a straightforward binding of the kernel PERF_SAMPLE_* enum values.

One thing to note is that this commit does not include any support for actually deserializing the records emitted by the kernel into something rust code can easily use. This can be added on top of the Sampler and Record types in a straightforward, albeit not necessarily easy, fashion. I consider it to be out of scope for this specific commit.

New Dependencies

This commit introduces one new dependency and one dev-dependency:

  • memmap2 - for memory mapping the kernel ring buffer
  • nix (dev) - for easy querying of the sysconf SC_PAGESIZE value which is needed to write the test case for a MMAP record.

Unsupported Features

This section can also be taken as notes for which features would make for a good starting point for future work.

  • Support for any of the various configuration flags needed to make the kernel generate any record type beyond PERF_RECORD_MMAP.
  • Support for parsing any of the record types. This may be best done in an external crate so it can be shared between the parsing needed for perf-event and that needed for parsing perf.data files.
  • Support for reading data out of the aux buffer.
  • Support for reading any of the extra information available within memory mapped buffer.

cc @jimblandy
Supercedes #22

This commit introduces a minimal but mostly complete form of support for
reading sampled perf_event events emitted by the kernel.

New public types being introduced
=================================
- Sampler - A combination of an existing Counter with a memory mapped
  ring buffer. It is constructed from a Counter by calling sampled and
  is used to read Records
- Record - A reference into the kernel ring buffer for a single record
  that allows accessing the emitted bytes. Upon being dropped, it
  advances the tail pointer within the ring buffer. It also provides
  some convenience methods for getting the referenced bytes in owned or
  contiguous forms.
- SampleType - This is a set of bitflags which indicate what data the
  kernel should collect when sampling. It is a straightforward binding
  of the kernel PERF_SAMPLE_* enum values.

One thing to note is that this commit does not include any support for
actually deserializing the records emitted by the kernel into something
rust code can easily use. This can be added on top of the Sampler and
Record types in a straightforward, albeit not necessarily easy, fashion.
I consider it to be out of scope for this specific commit.

New Dependencies
================
This commit introduces two new dependencies and one dev-dependency:
- memmap2   - for memory mapping the kernel ring buffer
- memoffset - for safe offset_of operations on pointers
- nix (dev) - for easy querying of the sysconf SC_PAGESIZE value which
  is needed to write the test case for a MMAP record.

Unsupported Features
====================
This section can also be taken as notes for which features would make
for a good starting point for future work.
- Support for any of the various configuration flags needed to make the
  kernel generate any record type beyond PERF_RECORD_MMAP.
- Support for parsing any of the record types. This may be best done in
  an external crate so it can be shared between the parsing needed for
  perf-event and that needed for parsing perf.data files.
- Support for reading data out of the aux buffer.
- Support for reading any of the extra information available within
  memory mapped buffer.
@jimblandy jimblandy closed this Apr 1, 2024
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