Skip to content

Commit

Permalink
perf: fix TestPerfReaderWakeupEvents
Browse files Browse the repository at this point in the history
The WakeupEvents limit is per ring, one per CPU. And when we execute
BPF_PROG_RUN multiple times, we sometimes execute on different CPUs.
This means that samples don't all go into a single ring.

Fix this by forcing the producer to run on a single CPU.

Fixes #1419

Co-developed-by: Dylan Reimerink <dylan@isovalent.com>
Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
  • Loading branch information
lmb committed Apr 10, 2024
1 parent e678d6e commit bbb2c07
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
32 changes: 32 additions & 0 deletions internal/testutils/cpu.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package testutils

import (
"runtime"
"testing"

"github.com/cilium/ebpf/internal/unix"

"github.com/go-quicktest/qt"
)

// LockOSThreadToSingleCPU force the current goroutine to run on a single CPU.
func LockOSThreadToSingleCPU(tb testing.TB) {
tb.Helper()

runtime.LockOSThread()
tb.Cleanup(runtime.UnlockOSThread)

var old unix.CPUSet
err := unix.SchedGetaffinity(0, &old)
qt.Assert(tb, qt.IsNil(err))

// Schedule test to run on only CPU 0
var first unix.CPUSet
first.Set(0)
err = unix.SchedSetaffinity(0, &first)
qt.Assert(tb, qt.IsNil(err))

tb.Cleanup(func() {
_ = unix.SchedSetaffinity(0, &old)
})
}
9 changes: 9 additions & 0 deletions internal/unix/types_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type PerfEventMmapPage = linux.PerfEventMmapPage
type EpollEvent = linux.EpollEvent
type PerfEventAttr = linux.PerfEventAttr
type Utsname = linux.Utsname
type CPUSet = linux.CPUSet

func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return linux.Syscall(trap, a1, a2, a3)
Expand Down Expand Up @@ -204,3 +205,11 @@ func Fstat(fd int, stat *Stat_t) error {
func SetsockoptInt(fd, level, opt, value int) error {
return linux.SetsockoptInt(fd, level, opt, value)
}

func SchedSetaffinity(pid int, set *CPUSet) error {
return linux.SchedSetaffinity(pid, set)
}

func SchedGetaffinity(pid int, set *CPUSet) error {
return linux.SchedGetaffinity(pid, set)
}
12 changes: 12 additions & 0 deletions internal/unix/types_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,15 @@ func Fstat(fd int, stat *Stat_t) error {
func SetsockoptInt(fd, level, opt, value int) error {
return errNonLinux
}

type CPUSet struct{}

func (*CPUSet) Set(int) {}

func SchedSetaffinity(pid int, set *CPUSet) error {
return errNonLinux
}

func SchedGetaffinity(pid int, set *CPUSet) error {
return errNonLinux
}
2 changes: 2 additions & 0 deletions perf/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ func TestPause(t *testing.T) {
}

func TestPerfReaderWakeupEvents(t *testing.T) {
testutils.LockOSThreadToSingleCPU(t)

events := perfEventArray(t)

numEvents := 2
Expand Down

0 comments on commit bbb2c07

Please sign in to comment.