perf

package
v0.0.0-...-a55c778 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 6, 2024 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package perf allows reading from BPF perf event arrays.

A perf event array contains multiple perf event ringbuffers which can be used to exchange sample like data with user space.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrClosed = os.ErrClosed
)

Functions

func IsUnknownEvent

func IsUnknownEvent(err error) bool

IsUnknownEvent returns true if the error occurred because an unknown event was submitted to the perf event ring.

Types

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader allows reading bpf_perf_event_output from user space.

Example

ExampleReader submits a perf event using BPF, and then reads it in user space.

The BPF will look something like this:

struct map events __section("maps") = {
  .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
};

__section("xdp") int output_single(void *ctx) {
  unsigned char buf[] = {
    1, 2, 3, 4, 5
  };

   return perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &buf[0], 5);
 }

Also see BPF_F_CTXLEN_MASK if you want to sample packet data from SKB or XDP programs.

prog, events := bpfPerfEventOutputProgram()
defer prog.Close()
defer events.Close()

rd, err := NewReader(events, 4096)
if err != nil {
	panic(err)
}
defer rd.Close()

// Writes out a sample with content 1,2,3,4,4
ret, _, err := prog.Test(internal.EmptyBPFContext)
if err != nil || ret != 0 {
	panic("Can't write sample")
}

record, err := rd.Read()
if err != nil {
	panic(err)
}

// Data is padded with 0 for alignment
fmt.Println("Sample:", record.RawSample)
Output:

func NewReader

func NewReader(array *gbpf.Map, perCPUBuffer int) (*Reader, error)

NewReader creates a new reader with default options.

array must be a PerfEventArray. perCPUBuffer gives the size of the per CPU buffer in bytes. It is rounded up to the nearest multiple of the current page size.

func NewReaderWithOptions

func NewReaderWithOptions(array *gbpf.Map, perCPUBuffer int, opts ReaderOptions) (pr *Reader, err error)

NewReaderWithOptions creates a new reader with the given options.

func (*Reader) BufferSize

func (pr *Reader) BufferSize() int

BufferSize is the size in bytes of each per-CPU buffer

func (*Reader) Close

func (pr *Reader) Close() error

Close frees resources used by the reader.

It interrupts calls to Read.

Calls to perf_event_output from gBPF programs will return ENOENT after calling this method.

func (*Reader) Pause

func (pr *Reader) Pause() error

Pause stops all notifications from this Reader.

While the Reader is paused, any attempts to write to the event buffer from BPF programs will return -ENOENT.

Subsequent calls to Read will block until a call to Resume.

func (*Reader) Read

func (pr *Reader) Read() (Record, error)

Read the next record from the perf ring buffer.

The function blocks until there are at least Watermark bytes in one of the per CPU buffers. Records from buffers below the Watermark are not returned.

Records can contain between 0 and 7 bytes of trailing garbage from the ring depending on the input sample's length.

Calling Close interrupts the function.

Returns os.ErrDeadlineExceeded if a deadline was set and the perf ring buffer was empty. Otherwise returns a record and no error, even if the deadline was exceeded.

See Reader.ReadInto for a more efficient version of this method.

func (*Reader) ReadInto

func (pr *Reader) ReadInto(rec *Record) error

ReadInto is like Reader.Read except that it allows reusing Record and associated buffers.

Example

ReadRecord allows reducing memory allocations.

prog, events := bpfPerfEventOutputProgram()
defer prog.Close()
defer events.Close()

rd, err := NewReader(events, 4096)
if err != nil {
	panic(err)
}
defer rd.Close()

for i := 0; i < 2; i++ {
	// Write out two samples
	ret, _, err := prog.Test(internal.EmptyBPFContext)
	if err != nil || ret != 0 {
		panic("Can't write sample")
	}
}

var rec Record
for i := 0; i < 2; i++ {
	if err := rd.ReadInto(&rec); err != nil {
		panic(err)
	}

	fmt.Println("Sample:", rec.RawSample[:5])
}
Output:

func (*Reader) Resume

func (pr *Reader) Resume() error

Resume allows this perf reader to emit notifications.

Subsequent calls to Read will block until the next event notification.

func (*Reader) SetDeadline

func (pr *Reader) SetDeadline(t time.Time)

SetDeadline controls how long Read and ReadInto will block waiting for samples.

Passing a zero time.Time will remove the deadline. Passing a deadline in the past will prevent the reader from blocking if there are no records to be read.

type ReaderOptions

type ReaderOptions struct {
	// The number of events required in any per CPU buffer before
	// Read will process data. This is mutually exclusive with Watermark.
	// The default is zero, which means Watermark will take precedence.
	WakeupEvents int
	// The number of written bytes required in any per CPU buffer before
	// Read will process data. Must be smaller than PerCPUBuffer.
	// The default is to start processing as soon as data is available.
	Watermark int
	// This perf ring buffer is overwritable, once full the oldest event will be
	// overwritten by newest.
	Overwritable bool
}

ReaderOptions control the behaviour of the user space reader.

type Record

type Record struct {
	// The CPU this record was generated on.
	CPU int

	// The data submitted via bpf_perf_event_output.
	// Due to a kernel bug, this can contain between 0 and 7 bytes of trailing
	// garbage from the ring depending on the input sample's length.
	RawSample []byte

	// The number of samples which could not be output, since
	// the ring buffer was full.
	LostSamples uint64

	// The minimum number of bytes remaining in the per-CPU buffer after this Record has been read.
	// Negative for overwritable buffers.
	Remaining int
}

Record contains either a sample or a counter of the number of lost samples.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL