nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: cilium/ebpf
Pull request #329 (2021-06-17 21:48:20)

Add feature test for BPF_F_MMAPABLE maps
Introduced in
https://github.com/torvalds/linux/commit/fc9702273e2edb90400a34b3be76f7b08fa3344b.

Signed-off-by: Chris Tarazi <chris@isovalent.com>


christarazi: Ah thanks @aditighag. I instinctively updated the library thinking that the `BPF_F_MMAPABLE` constant wasn't available, but didn't notice that the `darwin` builds were failing. Should be good now.

Patch:
diff --git a/internal/unix/types_linux.go b/internal/unix/types_linux.go
index 39debb5..928756c 100644
--- a/internal/unix/types_linux.go
+++ b/internal/unix/types_linux.go
@@ -31,6 +31,7 @@ const (
 	BPF_F_RDONLY_PROG        = linux.BPF_F_RDONLY_PROG
 	BPF_F_WRONLY_PROG        = linux.BPF_F_WRONLY_PROG
 	BPF_F_SLEEPABLE          = linux.BPF_F_SLEEPABLE
+	BPF_F_MMAPABLE           = linux.BPF_F_MMAPABLE
 	BPF_OBJ_NAME_LEN         = linux.BPF_OBJ_NAME_LEN
 	BPF_TAG_SIZE             = linux.BPF_TAG_SIZE
 	SYS_BPF                  = linux.SYS_BPF
diff --git a/internal/unix/types_other.go b/internal/unix/types_other.go
index deedccc..42a13fa 100644
--- a/internal/unix/types_other.go
+++ b/internal/unix/types_other.go
@@ -31,6 +31,7 @@ const (
 	BPF_F_RDONLY_PROG        = 0
 	BPF_F_WRONLY_PROG        = 0
 	BPF_F_SLEEPABLE          = 0
+	BPF_F_MMAPABLE           = 0
 	BPF_OBJ_NAME_LEN         = 0x10
 	BPF_TAG_SIZE             = 0x8
 	SYS_BPF                  = 321
diff --git a/map.go b/map.go
index 304219e..575ed35 100644
--- a/map.go
+++ b/map.go
@@ -316,6 +316,11 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, handles *hand
 			return nil, fmt.Errorf("map create: %w", err)
 		}
 	}
+	if spec.Flags&unix.BPF_F_MMAPABLE > 0 {
+		if err := haveMmapableMaps(); err != nil {
+			return nil, fmt.Errorf("map create: %w", err)
+		}
+	}
 
 	attr := internal.BPFMapCreateAttr{
 		MapType:    uint32(spec.Type),
diff --git a/syscalls.go b/syscalls.go
index cf37dc8..c026126 100644
--- a/syscalls.go
+++ b/syscalls.go
@@ -214,6 +214,22 @@ var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps
 	return nil
 })
 
+var haveMmapableMaps = internal.FeatureTest("mmapable maps", "5.5", func() error {
+	// This checks BPF_F_MMAPABLE, which appeared in 5.5 for array maps.
+	m, err := internal.BPFMapCreate(&internal.BPFMapCreateAttr{
+		MapType:    uint32(Array),
+		KeySize:    4,
+		ValueSize:  4,
+		MaxEntries: 1,
+		Flags:      unix.BPF_F_MMAPABLE,
+	})
+	if err != nil {
+		return internal.ErrNotSupported
+	}
+	_ = m.Close()
+	return nil
+})
+
 func bpfMapLookupElem(m *internal.FD, key, valueOut internal.Pointer) error {
 	fd, err := m.Value()
 	if err != nil {


Test patch:
diff --git a/syscalls_test.go b/syscalls_test.go
index b1f6878..80b3b29 100644
--- a/syscalls_test.go
+++ b/syscalls_test.go
@@ -42,3 +42,7 @@ func TestHaveNestedMaps(t *testing.T) {
 func TestHaveMapMutabilityModifiers(t *testing.T) {
 	testutils.CheckFeatureTest(t, haveMapMutabilityModifiers)
 }
+
+func TestHaveMmapableMaps(t *testing.T) {
+	testutils.CheckFeatureTest(t, haveMmapableMaps)
+}
Repository: cilium/ebpf
Pull request #330 (2021-06-21 23:53:38)

Add feature test for BPF_F_INNER_MAP maps
Introduced in
https://github.com/torvalds/linux/commit/4a8f87e60f6db40e640f1db555d063b2c4dea5f1.

In Cilium, following the merge of https://github.com/cilium/cilium/pull/15546, we need to add this feature test as Maglev mode uses inner maps (map-in-map).

Signed-off-by: Chris Tarazi <chris@isovalent.com>



Patch:
diff --git a/internal/unix/types_linux.go b/internal/unix/types_linux.go
index 928756c..0a18eaf 100644
--- a/internal/unix/types_linux.go
+++ b/internal/unix/types_linux.go
@@ -32,6 +32,7 @@ const (
 	BPF_F_WRONLY_PROG        = linux.BPF_F_WRONLY_PROG
 	BPF_F_SLEEPABLE          = linux.BPF_F_SLEEPABLE
 	BPF_F_MMAPABLE           = linux.BPF_F_MMAPABLE
+	BPF_F_INNER_MAP          = linux.BPF_F_INNER_MAP
 	BPF_OBJ_NAME_LEN         = linux.BPF_OBJ_NAME_LEN
 	BPF_TAG_SIZE             = linux.BPF_TAG_SIZE
 	SYS_BPF                  = linux.SYS_BPF
diff --git a/internal/unix/types_other.go b/internal/unix/types_other.go
index 42a13fa..1b06def 100644
--- a/internal/unix/types_other.go
+++ b/internal/unix/types_other.go
@@ -32,6 +32,7 @@ const (
 	BPF_F_WRONLY_PROG        = 0
 	BPF_F_SLEEPABLE          = 0
 	BPF_F_MMAPABLE           = 0
+	BPF_F_INNER_MAP          = 0
 	BPF_OBJ_NAME_LEN         = 0x10
 	BPF_TAG_SIZE             = 0x8
 	SYS_BPF                  = 321
diff --git a/map.go b/map.go
index 575ed35..f257d88 100644
--- a/map.go
+++ b/map.go
@@ -321,6 +321,11 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, handles *hand
 			return nil, fmt.Errorf("map create: %w", err)
 		}
 	}
+	if spec.Flags&unix.BPF_F_INNER_MAP > 0 {
+		if err := haveInnerMaps(); err != nil {
+			return nil, fmt.Errorf("map create: %w", err)
+		}
+	}
 
 	attr := internal.BPFMapCreateAttr{
 		MapType:    uint32(spec.Type),
diff --git a/syscalls.go b/syscalls.go
index c026126..c3cc523 100644
--- a/syscalls.go
+++ b/syscalls.go
@@ -230,6 +230,22 @@ var haveMmapableMaps = internal.FeatureTest("mmapable maps", "5.5", func() error
 	return nil
 })
 
+var haveInnerMaps = internal.FeatureTest("inner maps", "5.10", func() error {
+	// This checks BPF_F_INNER_MAP, which appeared in 5.10.
+	m, err := internal.BPFMapCreate(&internal.BPFMapCreateAttr{
+		MapType:    uint32(Array),
+		KeySize:    4,
+		ValueSize:  4,
+		MaxEntries: 1,
+		Flags:      unix.BPF_F_INNER_MAP,
+	})
+	if err != nil {
+		return internal.ErrNotSupported
+	}
+	_ = m.Close()
+	return nil
+})
+
 func bpfMapLookupElem(m *internal.FD, key, valueOut internal.Pointer) error {
 	fd, err := m.Value()
 	if err != nil {


Test patch:
diff --git a/syscalls_test.go b/syscalls_test.go
index 80b3b29..45c5421 100644
--- a/syscalls_test.go
+++ b/syscalls_test.go
@@ -46,3 +46,7 @@ func TestHaveMapMutabilityModifiers(t *testing.T) {
 func TestHaveMmapableMaps(t *testing.T) {
 	testutils.CheckFeatureTest(t, haveMmapableMaps)
 }
+
+func TestHaveInnerMaps(t *testing.T) {
+	testutils.CheckFeatureTest(t, haveInnerMaps)
+}
Repository: cilium/ebpf
Pull request #361 (2021-08-02 16:11:06)

Export `CollectionSpec.ByteOrder`
This is necessary to be able to access it from package `link`.


Patch:
diff --git a/collection.go b/collection.go
index 1ea77f7..b70a879 100644
--- a/collection.go
+++ b/collection.go
@@ -27,7 +27,9 @@ type CollectionSpec struct {
 	Maps     map[string]*MapSpec
 	Programs map[string]*ProgramSpec
 
-	byteOrder binary.ByteOrder
+	// ByteOrder specifies whether the ELF was compiled for
+	// big-endian or little-endian architectures.
+	ByteOrder binary.ByteOrder
 }
 
 // Copy returns a recursive copy of the spec.
@@ -39,7 +41,7 @@ func (cs *CollectionSpec) Copy() *CollectionSpec {
 	cpy := CollectionSpec{
 		Maps:      make(map[string]*MapSpec, len(cs.Maps)),
 		Programs:  make(map[string]*ProgramSpec, len(cs.Programs)),
-		byteOrder: cs.byteOrder,
+		ByteOrder: cs.ByteOrder,
 	}
 
 	for name, spec := range cs.Maps {
diff --git a/link/freplace.go b/link/freplace.go
index 571e8cd..9fafb70 100644
--- a/link/freplace.go
+++ b/link/freplace.go
@@ -12,7 +12,7 @@ type FreplaceLink struct {
 }
 
 // AttachFreplace attaches the given eBPF program to the function it replaces.
-
+//
 // The program and name can either be provided at link time, or can be provided
 // at program load time. If they were provided at load time, they should be nil
 // and empty respectively here, as they will be ignored by the kernel.


Test patch:
diff --git a/elf_reader_test.go b/elf_reader_test.go
index 9a7d906..6a634ab 100644
--- a/elf_reader_test.go
+++ b/elf_reader_test.go
@@ -118,7 +118,7 @@ func TestLoadCollectionSpec(t *testing.T) {
 
 	defaultOpts := cmp.Options{
 		cmpopts.IgnoreTypes(new(btf.Map), new(btf.Program)),
-		cmpopts.IgnoreFields(CollectionSpec{}, "byteOrder"),
+		cmpopts.IgnoreFields(CollectionSpec{}, "ByteOrder"),
 		cmpopts.IgnoreFields(ProgramSpec{}, "Instructions", "ByteOrder"),
 		cmpopts.IgnoreMapEntries(func(key string, _ *MapSpec) bool {
 			switch key {
@@ -166,7 +166,7 @@ func TestLoadCollectionSpec(t *testing.T) {
 			t.Errorf("MapSpec mismatch (-want +got):\n%s", diff)
 		}
 
-		if have.byteOrder != internal.NativeEndian {
+		if have.ByteOrder != internal.NativeEndian {
 			return
 		}
 
@@ -333,7 +333,7 @@ func TestLoadRawTracepoint(t *testing.T) {
 			t.Fatal("Can't parse ELF:", err)
 		}
 
-		if spec.byteOrder != internal.NativeEndian {
+		if spec.ByteOrder != internal.NativeEndian {
 			return
 		}
 
diff --git a/link/freplace_test.go b/link/freplace_test.go
index 1d9e5a1..98de30d 100644
--- a/link/freplace_test.go
+++ b/link/freplace_test.go
@@ -17,7 +17,7 @@ func TestFreplace(t *testing.T) {
 			t.Fatal("Can't parse ELF:", err)
 		}
 
-		if spec.Programs["sched_process_exec"].ByteOrder != internal.NativeEndian {
+		if spec.ByteOrder != internal.NativeEndian {
 			return
 		}
Repository: cilium/ebpf
Pull request #397 (2021-09-01 16:46:27)

perf: deprecate IsClosed
Encourage the use of errors.Is instead.


Patch:
diff --git a/perf/reader.go b/perf/reader.go
index d4f68b8..8cc4401 100644
--- a/perf/reader.go
+++ b/perf/reader.go
@@ -15,7 +15,7 @@ import (
 )
 
 var (
-	errClosed = errors.New("perf reader was closed")
+	ErrClosed = errors.New("perf reader was closed")
 	errEOR    = errors.New("end of ring")
 )
 
@@ -322,7 +322,7 @@ func (pr *Reader) Read() (Record, error) {
 	defer pr.mu.Unlock()
 
 	if pr.epollFd == -1 {
-		return Record{}, errClosed
+		return Record{}, fmt.Errorf("%w", ErrClosed)
 	}
 
 	for {
@@ -339,7 +339,7 @@ func (pr *Reader) Read() (Record, error) {
 
 			for _, event := range pr.epollEvents[:nEvents] {
 				if int(event.Fd) == pr.closeFd {
-					return Record{}, errClosed
+					return Record{}, fmt.Errorf("%w", ErrClosed)
 				}
 
 				ring := pr.rings[cpuForEvent(&event)]
@@ -378,7 +378,7 @@ func (pr *Reader) Pause() error {
 	defer pr.pauseMu.Unlock()
 
 	if pr.pauseFds == nil {
-		return errClosed
+		return fmt.Errorf("%w", ErrClosed)
 	}
 
 	for i := range pr.pauseFds {
@@ -398,7 +398,7 @@ func (pr *Reader) Resume() error {
 	defer pr.pauseMu.Unlock()
 
 	if pr.pauseFds == nil {
-		return errClosed
+		return fmt.Errorf("%w", ErrClosed)
 	}
 
 	for i, fd := range pr.pauseFds {
@@ -420,8 +420,10 @@ type temporaryError interface {
 
 // IsClosed returns true if the error occurred because
 // a Reader was closed.
+//
+// Deprecated: use errors.Is(err, ErrClosed) instead.
 func IsClosed(err error) bool {
-	return errors.Is(err, errClosed)
+	return errors.Is(err, ErrClosed)
 }
 
 type unknownEventError struct {


Test patch:
diff --git a/perf/reader_test.go b/perf/reader_test.go
index bb3d60b..efe836f 100644
--- a/perf/reader_test.go
+++ b/perf/reader_test.go
@@ -3,6 +3,7 @@ package perf
 import (
 	"bytes"
 	"encoding/binary"
+	"errors"
 	"fmt"
 	"os"
 	"syscall"
@@ -14,6 +15,8 @@ import (
 	"github.com/cilium/ebpf/internal"
 	"github.com/cilium/ebpf/internal/testutils"
 	"github.com/cilium/ebpf/internal/unix"
+
+	qt "github.com/frankban/quicktest"
 )
 
 var (
@@ -371,12 +374,13 @@ func TestPause(t *testing.T) {
 	}
 
 	// Pause/Resume after close should be no-op.
-	if err = rd.Pause(); err != errClosed {
-		t.Fatalf("Unexpected error: %s", err)
-	}
-	if err = rd.Resume(); err != errClosed {
-		t.Fatalf("Unexpected error: %s", err)
-	}
+	err = rd.Pause()
+	qt.Assert(t, err, qt.Not(qt.Equals), ErrClosed, qt.Commentf("returns unwrapped ErrClosed"))
+	qt.Assert(t, errors.Is(err, ErrClosed), qt.IsTrue, qt.Commentf("doesn't wrap ErrClosed"))
+
+	err = rd.Resume()
+	qt.Assert(t, err, qt.Not(qt.Equals), ErrClosed, qt.Commentf("returns unwrapped ErrClosed"))
+	qt.Assert(t, errors.Is(err, ErrClosed), qt.IsTrue, qt.Commentf("doesn't wrap ErrClosed"))
 }
 
 func BenchmarkReader(b *testing.B) {
Repository: cilium/ebpf
Pull request #403 (2021-09-06 10:13:51)

btf: handle float relocation for CO-RE
Handle floats according to upstream libbpf logic: https://github.com/libbpf/libbpf/commit/6b14cfa56eb87724d7c9d489ade6990dc2bc269a


Patch:
diff --git a/internal/btf/core.go b/internal/btf/core.go
index 749799c..c6bc179 100644
--- a/internal/btf/core.go
+++ b/internal/btf/core.go
@@ -813,6 +813,7 @@ func coreAreTypesCompatible(localType Type, targetType Type) error {
  *     least one of enums should be anonymous;
  *   - for ENUMs, check sizes, names are ignored;
  *   - for INT, size and signedness are ignored;
+ *   - any two FLOATs are always compatible;
  *   - for ARRAY, dimensionality is ignored, element types are checked for
  *     compatibility recursively;
  *     [ NB: coreAreMembersCompatible doesn't recurse, this check is done
@@ -848,7 +849,7 @@ func coreAreMembersCompatible(localType Type, targetType Type) error {
 	}
 
 	switch lv := localType.(type) {
-	case *Array, *Pointer:
+	case *Array, *Pointer, *Float:
 		return nil
 
 	case *Enum:


Test patch:
diff --git a/internal/btf/core_test.go b/internal/btf/core_test.go
index c5cea5d..db49528 100644
--- a/internal/btf/core_test.go
+++ b/internal/btf/core_test.go
@@ -102,6 +102,7 @@ func TestCoreAreMembersCompatible(t *testing.T) {
 		{&Pointer{Target: &Void{}}, &Pointer{Target: &Void{}}, true},
 		{&Pointer{Target: &Void{}}, &Void{}, false},
 		{&Array{Type: &Int{Size: 1}}, &Array{Type: &Int{Encoding: Signed}}, true},
+		{&Float{Size: 2}, &Float{Size: 4}, true},
 	}
 
 	for _, test := range tests {
Repository: cilium/ebpf
Pull request #426 (2021-09-18 11:26:49)

link/uprobe: skip integration test when binaries are stripped
Context: https://cilium.slack.com/archives/C027KBX679U/p1631808389034700

The Go binary on Debian seems to be stripped:

```
SYMBOL TABLE:
no symbols
```

```
$ file /usr/lib/go-1.17/bin/go
/usr/lib/go-1.17/bin/go: ELF 64-bit LSB executable, ..., stripped
```

This PR is for skipping the test in such cases (assuming bash's `main` and Go's `main.main` always exists, it should be safe to do so)

cc @rockdaboot 

rockdaboot: :+1: Works for me (test is skipped)

Patch:
diff --git a/link/uprobe.go b/link/uprobe.go
index 50299c8..59170ce 100644
--- a/link/uprobe.go
+++ b/link/uprobe.go
@@ -25,6 +25,10 @@ var (
 		value uint64
 		err   error
 	}{}
+
+	// ErrNoSymbol indicates that the given symbol was not found
+	// in the ELF symbols table.
+	ErrNoSymbol = errors.New("not found")
 )
 
 // Executable defines an executable program on the filesystem.
@@ -144,7 +148,7 @@ func (ex *Executable) offset(symbol string) (uint64, error) {
 		}
 		return off, nil
 	}
-	return 0, fmt.Errorf("symbol %s not found", symbol)
+	return 0, fmt.Errorf("symbol %s: %w", symbol, ErrNoSymbol)
 }
 
 // Uprobe attaches the given eBPF program to a perf event that fires when the


Test patch:
diff --git a/link/uprobe_test.go b/link/uprobe_test.go
index 8159bc3..cf0ea07 100644
--- a/link/uprobe_test.go
+++ b/link/uprobe_test.go
@@ -349,6 +349,12 @@ func TestUprobeProgramCall(t *testing.T) {
 			// Open Uprobe on the executable for the given symbol
 			// and attach it to the ebpf program created above.
 			u, err := ex.Uprobe(tt.sym, p, nil)
+			if errors.Is(err, ErrNoSymbol) {
+				// Assume bash::main and go::main.main always exists
+				// and skip the test if the symbol can't be found as
+				// certain OS (eg. Debian) strip binaries.
+				t.Skipf("executable %s appear to be stripped, skipping", tt.elf)
+			}
 			if err != nil {
 				t.Fatal(err)
 			}