-
Notifications
You must be signed in to change notification settings - Fork 659
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
[RFC] introduce periodic BPF programs #924
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package link | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/cilium/ebpf" | ||
"github.com/cilium/ebpf/internal" | ||
) | ||
|
||
// PeriodicOptions defines additional parameters that will be used | ||
// when loading periodic samplers. | ||
type PeriodicOptions struct { | ||
// Arbitrary value that can be fetched from an eBPF program | ||
// via `bpf_get_attach_cookie()`. | ||
// | ||
// Needs kernel 5.15+. | ||
Cookie uint64 | ||
} | ||
|
||
// Periodic attaches the given eBPF program to a periodic perf event on given | ||
// cpu and given frequency. | ||
// | ||
// This is mainly useful when doing sample-based tracing or monitoring. | ||
// | ||
// Losing the reference to the resulting Link (tp) will close the Periodic event | ||
// and prevent further execution of prog. The Link must be Closed during | ||
// program shutdown to avoid leaking system resources. | ||
func Periodic(frequency uint64, cpu int, prog *ebpf.Program, opts *PeriodicOptions) (Link, error) { | ||
possibleCPUs, err := internal.PossibleCPUs() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if frequency == 0 { | ||
return nil, fmt.Errorf("frequency can not be 0: %w", errInvalidInput) | ||
} | ||
if cpu < 0 || cpu > possibleCPUs { | ||
return nil, fmt.Errorf("cpu must be greater to 0 and lower than %d: %w", possibleCPUs, errInvalidInput) | ||
} | ||
if prog == nil { | ||
return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) | ||
} | ||
if prog.Type() != ebpf.PerfEvent { | ||
return nil, fmt.Errorf("eBPF program type %s is not a PerfEvent: %w", prog.Type(), errInvalidInput) | ||
} | ||
|
||
fd, err := openPeriodicPerfEvent(frequency, cpu) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var cookie uint64 | ||
if opts != nil { | ||
cookie = opts.Cookie | ||
} | ||
|
||
pe := &perfEvent{ | ||
typ: periodicEvent, | ||
cookie: cookie, | ||
fd: fd, | ||
} | ||
|
||
lnk, err := attachPerfEvent(pe, prog) | ||
if err != nil { | ||
pe.Close() | ||
return nil, err | ||
} | ||
|
||
return lnk, nil | ||
} | ||
|
||
// PeriodicAllCpus attaches the given eBPF program to a periodic event fired at | ||
// given frequency on each cpu. | ||
// | ||
// See Periodic above for more information. | ||
func PeriodicAllCpus(frequency uint64, prog *ebpf.Program, opts *PeriodicOptions) ([]Link, error) { | ||
possibleCPUs, err := internal.PossibleCPUs() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
links := make([]Link, possibleCPUs) | ||
|
||
for i := 0; i < len(links); i++ { | ||
links[i], err = Periodic(frequency, i, prog, opts) | ||
if err != nil { | ||
// Links are automatically closed "some" time after the last reference is lost | ||
return nil, fmt.Errorf("failed to link periodic prog on CPU %d: %w", i, err) | ||
} | ||
} | ||
|
||
return links, nil | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a number of combinations of
pid
andcpu
that the perf subsystem accepts for periodic events:This function signature only allows to set the CPU . But I do think there is a valid use case where people want to attach an eBPF program via perf only to a single PID - e.g. for debugging purposes.