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

x/sys/linux/perf: add package for Linux perf tracing #24918

Open
the80srobot opened this issue Apr 18, 2018 · 11 comments
Open

x/sys/linux/perf: add package for Linux perf tracing #24918

the80srobot opened this issue Apr 18, 2018 · 11 comments

Comments

@the80srobot
Copy link

Linux ships with a robust suite of performance counters and samplers accessed via the perf_event_open system call.

Recent changes to x/sys/unix make it possible to call perf_event_open from Go, but using the perf events system correctly is notoriously hard.

Having recently implemented a wrapper for perf events in Go, I would like to generalize and contribute it upstream.

As regards the code location: x/sys/windows seems to have specialized subpackages, so maybe similar structure under x/sys/unix would work.

@gopherbot gopherbot added this to the Proposal milestone Apr 18, 2018
@ianlancetaylor
Copy link
Contributor

Can you add an outline of the API? Thanks.

@aclements
Copy link
Member

This would be wonderful, though getting the API right will be tricky.

If it's any help, I have an implementation of the perf events API for internal use in the runtime in CL 77651 and a more user-friendly API for reading perf.data files here. The latter doesn't support perf_event_open at the moment, but it has Go-friendly definitions of many of the perf API types.

Also relevant: #21295.

@minux
Copy link
Member

minux commented Apr 18, 2018 via email

@pwaller
Copy link
Contributor

pwaller commented Apr 19, 2018

FWIW, I have also hacked together some limited bindings for this purpose over at https://github.com/pwaller/perf. I'm fine with code and ideas being taken from there (or not). I make no claims as to the suitability of it for that purpose :). Agree with @minux in that it seems linux specific.

@rsc
Copy link
Contributor

rsc commented Apr 23, 2018

It sounds like people believe this would be worth having, especially since @the80srobot, @aclements, and @pwaller have essentially written three independent packages. It also sounds like the next step is to propose a specific API. Maybe those three people should hammer out what the right API is?

@bradfitz
Copy link
Contributor

@ianlancetaylor and I think x/sys/linux/perf is probably a better home.

But sounds like nobody is opposed to this. Marking this Accepted. We can figure out API later.

@bradfitz bradfitz changed the title proposal: x/sys/unix/perf: performance tracing using the Linux perf support x/sys/linux/perf: add package for Linux perf tracing Jul 16, 2018
@bradfitz bradfitz modified the milestones: Proposal, Unplanned Jul 16, 2018
@gopherbot
Copy link

Change https://golang.org/cl/160097 mentions this issue: linux/perf: API proposal

@acln0
Copy link
Contributor

acln0 commented Jan 29, 2019

Hello. I have sent an API proposal in the hopes of moving this forward. Please take a look.

@acln0
Copy link
Contributor

acln0 commented Mar 18, 2019

I have been working on this issue for the last couple of weeks. I have built a working perf package, which covers a large portion of the perf API surface. I'm going to abandon https://golang.org/cl/160097, and send a new CL, with working code, that can be tested and used.

I am hoping that a CL with actual documentation and working code might be easier to review and get feedback on than the previous API sketch. Please take a look.

Thanks,
Andrei

@gopherbot
Copy link

Change https://golang.org/cl/168059 mentions this issue: unix/linux/perf: new package

adriansr pushed a commit to adriansr/golang-x-sys that referenced this issue Jul 18, 2019
This change adds a perf API client package, per golang/go#24918.

The package is created at import path golang.org/x/sys/unix/linux/perf
rather than golang.org/x/sys/linux/perf (as suggested in the issue),
because a unix/linux directory has been created in the sys repository
in the meantime, and it seems sensible to use it.

This CL implements the minimal functionality needed in order to start
using perf natively from Go with working code, and exploring what an
idiomatic Go API would look like.

A large portion of the perf API surface is covered, and seems to be
working. However, there is still much work to be done in terms of
figuring out API details, adding nice-to-have features, and testing
the code more in-depth.

README.md describes the current state of the package, as well as
the design of the tests. It also documents the kernel and system
configuration requirements for effective testing of package perf.

perf.go contains the central Event and Attr data structures,
definitions of event type constants, common operations on events,
and utility code used by both counting and sampling events.

count.go implements the counting side of the API.

record.go implements the sampling side of the API. It contains an
implementation of a context-aware ring buffer poller, as well as data
structures and decoders for all overflow record types.

group.go contains the Group API, offered because wiring events together
manually can be tiresome, and measuring multiple events together in
order to compare them is a fundamental M.O. of perf.

Finally, doc.go contains a few short code snippets, demonstrating
typical use of the package.

Package perf does not yet support reading perf.data files produced by
the Linux perf tool, in order to keep the scope of this change as small
as possible. Instead, this CL focuses only on the perf API itself.

Fixes golang/go#24918

Change-Id: I95c44479c2fa21ef5030c7d3b4c16a123b6871ae
@hodgesds
Copy link

hodgesds commented Aug 7, 2019

After also implementing yet another library my experience has been that it becomes extremely tricky to get meaningful data at the goroutine level due to the runtime (which is generally what everyone wants). Yes, you can call runtime.LockOSThread, but that doesn't work when your thread could get scheduled on a different core. You end up having to use unix.SchedSetaffinity to set the affinity of goroutine locked thread to a core. The configuration of the PerfEventAttr seems to be the most difficult thing to get right, but I'm interested to see where this goes.

adriansr pushed a commit to elastic/go-perf that referenced this issue Aug 22, 2019
This change adds a perf API client package, per golang/go#24918.

The package is created at import path golang.org/x/sys/unix/linux/perf
rather than golang.org/x/sys/linux/perf (as suggested in the issue),
because a unix/linux directory has been created in the sys repository
in the meantime, and it seems sensible to use it.

This CL implements the minimal functionality needed in order to start
using perf natively from Go with working code, and exploring what an
idiomatic Go API would look like.

A large portion of the perf API surface is covered, and seems to be
working. However, there is still much work to be done in terms of
figuring out API details, adding nice-to-have features, and testing
the code more in-depth.

README.md describes the current state of the package, as well as
the design of the tests. It also documents the kernel and system
configuration requirements for effective testing of package perf.

perf.go contains the central Event and Attr data structures,
definitions of event type constants, common operations on events,
and utility code used by both counting and sampling events.

count.go implements the counting side of the API.

record.go implements the sampling side of the API. It contains an
implementation of a context-aware ring buffer poller, as well as data
structures and decoders for all overflow record types.

group.go contains the Group API, offered because wiring events together
manually can be tiresome, and measuring multiple events together in
order to compare them is a fundamental M.O. of perf.

Finally, doc.go contains a few short code snippets, demonstrating
typical use of the package.

Package perf does not yet support reading perf.data files produced by
the Linux perf tool, in order to keep the scope of this change as small
as possible. Instead, this CL focuses only on the perf API itself.

Fixes golang/go#24918

Change-Id: I95c44479c2fa21ef5030c7d3b4c16a123b6871ae
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants