From c37accb63918924467a0d3432541a9e25af578be Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 26 Jun 2024 13:58:16 +0000 Subject: [PATCH] Add support to pin kprobe perf link As suggested by Lorenz removing perfEventLink Pin/UnPin so the RawLink Pin/Unpi methods take over and implement pinning for perf link kprobes. Signed-off-by: Jiri Olsa --- link/link.go | 2 +- link/perf_event.go | 29 ++++++++++------------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/link/link.go b/link/link.go index 9e8ca49c6..9c34616c9 100644 --- a/link/link.go +++ b/link/link.go @@ -119,7 +119,7 @@ func wrapRawLink(raw *RawLink) (_ Link, err error) { case UprobeMultiType: return &uprobeMultiLink{*raw}, nil case PerfEventType: - return nil, fmt.Errorf("recovering perf event fd: %w", ErrNotSupported) + return &perfEventLink{*raw, nil}, nil case TCXType: return &tcxLink{*raw}, nil case NetfilterType: diff --git a/link/perf_event.go b/link/perf_event.go index 89eab233b..1d8feb58c 100644 --- a/link/perf_event.go +++ b/link/perf_event.go @@ -99,30 +99,16 @@ type perfEventLink struct { func (pl *perfEventLink) isLink() {} -// Pinning requires the underlying perf event FD to stay open. -// -// | PerfEvent FD | BpfLink FD | Works | -// |--------------|------------|-------| -// | Open | Open | Yes | -// | Closed | Open | No | -// | Open | Closed | No (Pin() -> EINVAL) | -// | Closed | Closed | No (Pin() -> EINVAL) | -// -// There is currently no pretty way to recover the perf event FD -// when loading a pinned link, so leave as not supported for now. -func (pl *perfEventLink) Pin(string) error { - return fmt.Errorf("perf event link pin: %w", ErrNotSupported) -} - -func (pl *perfEventLink) Unpin() error { - return fmt.Errorf("perf event link unpin: %w", ErrNotSupported) -} - func (pl *perfEventLink) Close() error { if err := pl.fd.Close(); err != nil { return fmt.Errorf("perf link close: %w", err) } + // when created from pinned link + if pl.pe == nil { + return nil + } + if err := pl.pe.Close(); err != nil { return fmt.Errorf("perf event close: %w", err) } @@ -136,6 +122,11 @@ func (pl *perfEventLink) Update(prog *ebpf.Program) error { var _ PerfEvent = (*perfEventLink)(nil) func (pl *perfEventLink) PerfEvent() (*os.File, error) { + // when created from pinned link + if pl.pe == nil { + return nil, ErrNotSupported + } + fd, err := pl.pe.fd.Dup() if err != nil { return nil, err