From 37ce7eaf6859ca68fc7c0d1c91403c20f6a47292 Mon Sep 17 00:00:00 2001 From: "cilium-renovate[bot]" <134692979+cilium-renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:07:37 +0000 Subject: [PATCH] fix(deps): update github.com/cilium/ebpf digest to 654f02d Signed-off-by: cilium-renovate[bot] <134692979+cilium-renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- vendor/github.com/cilium/ebpf/Makefile | 12 +- .../github.com/cilium/ebpf/features/misc.go | 24 ++- .../cilium/ebpf/internal/sysenc/buffer.go | 5 + vendor/github.com/cilium/ebpf/link/link.go | 10 +- .../github.com/cilium/ebpf/link/syscalls.go | 35 ++++ vendor/github.com/cilium/ebpf/link/tcx.go | 3 + vendor/github.com/cilium/ebpf/map.go | 151 ++++++++++++------ vendor/github.com/cilium/ebpf/marshalers.go | 113 +++++++++++-- vendor/github.com/cilium/ebpf/perf/reader.go | 3 +- vendor/github.com/cilium/ebpf/run-tests.sh | 22 +-- vendor/modules.txt | 2 +- 13 files changed, 286 insertions(+), 100 deletions(-) diff --git a/go.mod b/go.mod index 89915864053..4f9a851051e 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ go 1.21.0 require ( github.com/bombsimon/logrusr/v4 v4.1.0 github.com/cilium/cilium v1.15.0-rc.0 - github.com/cilium/ebpf v0.12.4-0.20231215112452-00c0cb05d35c + github.com/cilium/ebpf v0.12.4-0.20240111120710-654f02de301e github.com/cilium/little-vm-helper v0.0.13 github.com/cilium/lumberjack/v2 v2.3.0 github.com/cilium/tetragon/api v0.0.0-00010101000000-000000000000 diff --git a/go.sum b/go.sum index 5e076f55183..07f0b1f8cf8 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,8 @@ github.com/cilium/controller-tools v0.8.0-1 h1:D5xhwSUZZceaKAacHOyfcpUMgLbs2TGeJ github.com/cilium/controller-tools v0.8.0-1/go.mod h1:qE2DXhVOiEq5ijmINcFbqi9GZrrUjzB1TuJU0xa6eoY= github.com/cilium/dns v1.1.51-0.20230303133941-d3bcb3008ed2 h1:aUhT8ib6cKposeTys3ncn4AVOxEdAo2tXpWuCed/Nfk= github.com/cilium/dns v1.1.51-0.20230303133941-d3bcb3008ed2/go.mod h1:AyKxZ17L5Q7fk2doxT3yjMYGlrJdq5/jvR2xN5KMbxA= -github.com/cilium/ebpf v0.12.4-0.20231215112452-00c0cb05d35c h1:A4GKNW2FJKFAwvkJvFVnxyVn+9LGaUPz5LY6r8wZAh0= -github.com/cilium/ebpf v0.12.4-0.20231215112452-00c0cb05d35c/go.mod h1:9BszLnmZR7oucpa/kBbVVf1ts3BoUSpltcnNp1hQkVw= +github.com/cilium/ebpf v0.12.4-0.20240111120710-654f02de301e h1:X+fnTEDdxW2/XTjIk90B7lWIDESn/LLSwtQnwc9ncHA= +github.com/cilium/ebpf v0.12.4-0.20240111120710-654f02de301e/go.mod h1:9BszLnmZR7oucpa/kBbVVf1ts3BoUSpltcnNp1hQkVw= github.com/cilium/little-vm-helper v0.0.13 h1:pRyaz3Rg+S6u23z7EDOrTtBRRleZ1md2D/BTMbz3d30= github.com/cilium/little-vm-helper v0.0.13/go.mod h1:mtoEi6aNRMWCkyyP6y+K7+/KUUgQWtWZ4a7L69Fg3WU= github.com/cilium/lumberjack/v2 v2.3.0 h1:IhVJMvPpqDYmQzC0KDhAoy7KlaRsyOsZnT97Nsa3u0o= diff --git a/vendor/github.com/cilium/ebpf/Makefile b/vendor/github.com/cilium/ebpf/Makefile index 0a1201076d7..96517b75066 100644 --- a/vendor/github.com/cilium/ebpf/Makefile +++ b/vendor/github.com/cilium/ebpf/Makefile @@ -103,14 +103,6 @@ testdata/loader-%-eb.elf: testdata/loader.c $(STRIP) -g $@ .PHONY: update-kernel-deps -update-kernel-deps: KERNEL_VERSION?=6.6 +update-kernel-deps: export KERNEL_VERSION?=6.6 update-kernel-deps: - $(eval TMP := $(shell mktemp -d)) - curl -fL https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/plain/tools/lib/bpf/libbpf.c?h=v$(KERNEL_VERSION) -o "$(TMP)/libbpf.c" - "$(CURDIR)/internal/cmd/gensections.awk" "$(TMP)/libbpf.c" | gofmt > "$(CURDIR)/elf_sections.go" - curl -fL "$(CI_KERNEL_URL)/linux-$(KERNEL_VERSION)-amd64.tgz" -o "$(TMP)/linux.tgz" - tar xvf "$(TMP)/linux.tgz" -C "$(TMP)" --strip-components=2 ./boot/vmlinuz ./lib/modules - /lib/modules/$(shell uname -r)/build/scripts/extract-vmlinux "$(TMP)/vmlinuz" > "$(TMP)/vmlinux" - $(OBJCOPY) --dump-section .BTF=/dev/stdout "$(TMP)/vmlinux" /dev/null | gzip > "btf/testdata/vmlinux.btf.gz" - find "$(TMP)/modules" -type f -name bpf_testmod.ko -exec $(OBJCOPY) --dump-section .BTF="btf/testdata/btf_testmod.btf" {} /dev/null \; - $(RM) -r "$(TMP)" + ./testdata/sh/update-kernel-deps.sh diff --git a/vendor/github.com/cilium/ebpf/features/misc.go b/vendor/github.com/cilium/ebpf/features/misc.go index de07d3801b7..6bd8df9332d 100644 --- a/vendor/github.com/cilium/ebpf/features/misc.go +++ b/vendor/github.com/cilium/ebpf/features/misc.go @@ -12,7 +12,11 @@ import ( // Upstream commit c04c0d2b968a ("bpf: increase complexity limit and maximum program size"). // // See the package documentation for the meaning of the error return value. -var HaveLargeInstructions = internal.NewFeatureTest(">4096 instructions", "5.2", func() error { +func HaveLargeInstructions() error { + return haveLargeInstructions() +} + +var haveLargeInstructions = internal.NewFeatureTest(">4096 instructions", "5.2", func() error { const maxInsns = 4096 insns := make(asm.Instructions, maxInsns, maxInsns+1) @@ -32,7 +36,11 @@ var HaveLargeInstructions = internal.NewFeatureTest(">4096 instructions", "5.2", // Upstream commit 2589726d12a1 ("bpf: introduce bounded loops"). // // See the package documentation for the meaning of the error return value. -var HaveBoundedLoops = internal.NewFeatureTest("bounded loops", "5.3", func() error { +func HaveBoundedLoops() error { + return haveBoundedLoops() +} + +var haveBoundedLoops = internal.NewFeatureTest("bounded loops", "5.3", func() error { return probeProgram(&ebpf.ProgramSpec{ Type: ebpf.SocketFilter, Instructions: asm.Instructions{ @@ -49,7 +57,11 @@ var HaveBoundedLoops = internal.NewFeatureTest("bounded loops", "5.3", func() er // Upstream commit 92b31a9af73b ("bpf: add BPF_J{LT,LE,SLT,SLE} instructions"). // // See the package documentation for the meaning of the error return value. -var HaveV2ISA = internal.NewFeatureTest("v2 ISA", "4.14", func() error { +func HaveV2ISA() error { + return haveV2ISA() +} + +var haveV2ISA = internal.NewFeatureTest("v2 ISA", "4.14", func() error { return probeProgram(&ebpf.ProgramSpec{ Type: ebpf.SocketFilter, Instructions: asm.Instructions{ @@ -66,7 +78,11 @@ var HaveV2ISA = internal.NewFeatureTest("v2 ISA", "4.14", func() error { // Upstream commit 092ed0968bb6 ("bpf: verifier support JMP32"). // // See the package documentation for the meaning of the error return value. -var HaveV3ISA = internal.NewFeatureTest("v3 ISA", "5.1", func() error { +func HaveV3ISA() error { + return haveV3ISA() +} + +var haveV3ISA = internal.NewFeatureTest("v3 ISA", "5.1", func() error { return probeProgram(&ebpf.ProgramSpec{ Type: ebpf.SocketFilter, Instructions: asm.Instructions{ diff --git a/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go b/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go index 97ac473c889..d184ea196ae 100644 --- a/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go +++ b/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go @@ -54,6 +54,11 @@ func (b Buffer) CopyTo(dst []byte) int { return copy(dst, b.unsafeBytes()) } +// AppendTo appends the buffer onto dst. +func (b Buffer) AppendTo(dst []byte) []byte { + return append(dst, b.unsafeBytes()...) +} + // Pointer returns the location where a syscall should write. func (b Buffer) Pointer() sys.Pointer { // NB: This deliberately ignores b.length to support zero-copy diff --git a/vendor/github.com/cilium/ebpf/link/link.go b/vendor/github.com/cilium/ebpf/link/link.go index 590ea3aec3d..2025b7d4349 100644 --- a/vendor/github.com/cilium/ebpf/link/link.go +++ b/vendor/github.com/cilium/ebpf/link/link.go @@ -160,7 +160,7 @@ func (r Info) NetNs() *NetNsInfo { return e } -// ExtraNetNs returns XDP type-specific link info. +// XDP returns XDP type-specific link info. // // Returns nil if the type-specific link info isn't available. func (r Info) XDP() *XDPInfo { @@ -168,6 +168,14 @@ func (r Info) XDP() *XDPInfo { return e } +// TCX returns TCX type-specific link info. +// +// Returns nil if the type-specific link info isn't available. +func (r Info) TCX() *TCXInfo { + e, _ := r.extra.(*TCXInfo) + return e +} + // RawLink is the low-level API to bpf_link. // // You should consider using the higher level interfaces in this diff --git a/vendor/github.com/cilium/ebpf/link/syscalls.go b/vendor/github.com/cilium/ebpf/link/syscalls.go index 96d6c7b1a03..02460d9fbd6 100644 --- a/vendor/github.com/cilium/ebpf/link/syscalls.go +++ b/vendor/github.com/cilium/ebpf/link/syscalls.go @@ -125,3 +125,38 @@ var haveProgQuery = internal.NewFeatureTest("BPF_PROG_QUERY", "4.15", func() err } return errors.New("syscall succeeded unexpectedly") }) + +var haveTCX = internal.NewFeatureTest("tcx", "6.6", func() error { + prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ + Type: ebpf.SchedCLS, + License: "MIT", + Instructions: asm.Instructions{ + asm.Mov.Imm(asm.R0, 0), + asm.Return(), + }, + }) + + if err != nil { + return internal.ErrNotSupported + } + + defer prog.Close() + attr := sys.LinkCreateTcxAttr{ + // We rely on this being checked during the syscall. + // With an otherwise correct payload we expect ENODEV here + // as an indication that the feature is present. + TargetIfindex: ^uint32(0), + ProgFd: uint32(prog.FD()), + AttachType: sys.AttachType(ebpf.AttachTCXIngress), + } + + _, err = sys.LinkCreateTcx(&attr) + + if errors.Is(err, unix.ENODEV) { + return nil + } + if err != nil { + return ErrNotSupported + } + return errors.New("syscall succeeded unexpectedly") +}) diff --git a/vendor/github.com/cilium/ebpf/link/tcx.go b/vendor/github.com/cilium/ebpf/link/tcx.go index 6989af8c9e7..88f2237d290 100644 --- a/vendor/github.com/cilium/ebpf/link/tcx.go +++ b/vendor/github.com/cilium/ebpf/link/tcx.go @@ -55,6 +55,9 @@ func AttachTCX(opts TCXOptions) (Link, error) { runtime.KeepAlive(opts.Program) runtime.KeepAlive(opts.Anchor) if err != nil { + if haveFeatErr := haveTCX(); haveFeatErr != nil { + return nil, haveFeatErr + } return nil, fmt.Errorf("attach tcx link: %w", err) } diff --git a/vendor/github.com/cilium/ebpf/map.go b/vendor/github.com/cilium/ebpf/map.go index 5e71ccfc2a1..f350d8b11a4 100644 --- a/vendor/github.com/cilium/ebpf/map.go +++ b/vendor/github.com/cilium/ebpf/map.go @@ -1005,6 +1005,53 @@ type BatchCursor struct { } func (m *Map) batchLookup(cmd sys.Cmd, cursor *BatchCursor, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { + if m.typ.hasPerCPUValue() { + return m.batchLookupPerCPU(cmd, cursor, keysOut, valuesOut, opts) + } + + count, err := batchCount(keysOut, valuesOut) + if err != nil { + return 0, err + } + + valueBuf := sysenc.SyscallOutput(valuesOut, count*int(m.fullValueSize)) + + n, err := m.batchLookupCmd(cmd, cursor, count, keysOut, valueBuf.Pointer(), opts) + if err != nil { + return n, err + } + + err = valueBuf.Unmarshal(valuesOut) + if err != nil { + return 0, err + } + + return n, nil +} + +func (m *Map) batchLookupPerCPU(cmd sys.Cmd, cursor *BatchCursor, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { + count, err := sliceLen(keysOut) + if err != nil { + return 0, fmt.Errorf("keys: %w", err) + } + + valueBuf := make([]byte, count*int(m.fullValueSize)) + valuePtr := sys.NewSlicePointer(valueBuf) + + n, sysErr := m.batchLookupCmd(cmd, cursor, count, keysOut, valuePtr, opts) + if sysErr != nil && !errors.Is(sysErr, unix.ENOENT) { + return 0, err + } + + err = unmarshalBatchPerCPUValue(valuesOut, count, int(m.valueSize), valueBuf) + if err != nil { + return 0, err + } + + return n, sysErr +} + +func (m *Map) batchLookupCmd(cmd sys.Cmd, cursor *BatchCursor, count int, keysOut any, valuePtr sys.Pointer, opts *BatchOptions) (int, error) { cursorLen := int(m.keySize) if cursorLen < 4 { // * generic_map_lookup_batch requires that batch_out is key_size bytes. @@ -1033,29 +1080,13 @@ func (m *Map) batchLookup(cmd sys.Cmd, cursor *BatchCursor, keysOut, valuesOut i if err := haveBatchAPI(); err != nil { return 0, err } - if m.typ.hasPerCPUValue() { - return 0, ErrNotSupported - } - keysValue := reflect.ValueOf(keysOut) - if keysValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("keys must be a slice") - } - valuesValue := reflect.ValueOf(valuesOut) - if valuesValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("valuesOut must be a slice") - } - count := keysValue.Len() - if count != valuesValue.Len() { - return 0, fmt.Errorf("keysOut and valuesOut must be the same length") - } keyBuf := sysenc.SyscallOutput(keysOut, count*int(m.keySize)) - valueBuf := sysenc.SyscallOutput(valuesOut, count*int(m.fullValueSize)) attr := sys.MapLookupBatchAttr{ MapFd: m.fd.Uint(), Keys: keyBuf.Pointer(), - Values: valueBuf.Pointer(), + Values: valuePtr, Count: uint32(count), InBatch: sys.NewSlicePointer(inBatch), OutBatch: sys.NewSlicePointer(cursor.opaque), @@ -1075,9 +1106,6 @@ func (m *Map) batchLookup(cmd sys.Cmd, cursor *BatchCursor, keysOut, valuesOut i if err := keyBuf.Unmarshal(keysOut); err != nil { return 0, err } - if err := valueBuf.Unmarshal(valuesOut); err != nil { - return 0, err - } return int(attr.Count), sysErr } @@ -1088,29 +1116,24 @@ func (m *Map) batchLookup(cmd sys.Cmd, cursor *BatchCursor, keysOut, valuesOut i // to a slice or buffer will not work. func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, error) { if m.typ.hasPerCPUValue() { - return 0, ErrNotSupported + return m.batchUpdatePerCPU(keys, values, opts) } - keysValue := reflect.ValueOf(keys) - if keysValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("keys must be a slice") - } - valuesValue := reflect.ValueOf(values) - if valuesValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("values must be a slice") - } - var ( - count = keysValue.Len() - valuePtr sys.Pointer - err error - ) - if count != valuesValue.Len() { - return 0, fmt.Errorf("keys and values must be the same length") + + count, err := batchCount(keys, values) + if err != nil { + return 0, err } - keyPtr, err := marshalMapSyscallInput(keys, count*int(m.keySize)) + + valuePtr, err := marshalMapSyscallInput(values, count*int(m.valueSize)) if err != nil { return 0, err } - valuePtr, err = marshalMapSyscallInput(values, count*int(m.valueSize)) + + return m.batchUpdate(count, keys, valuePtr, opts) +} + +func (m *Map) batchUpdate(count int, keys any, valuePtr sys.Pointer, opts *BatchOptions) (int, error) { + keyPtr, err := marshalMapSyscallInput(keys, count*int(m.keySize)) if err != nil { return 0, err } @@ -1137,17 +1160,28 @@ func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, er return int(attr.Count), nil } +func (m *Map) batchUpdatePerCPU(keys, values any, opts *BatchOptions) (int, error) { + count, err := sliceLen(keys) + if err != nil { + return 0, fmt.Errorf("keys: %w", err) + } + + valueBuf, err := marshalBatchPerCPUValue(values, count, int(m.valueSize)) + if err != nil { + return 0, err + } + + return m.batchUpdate(count, keys, sys.NewSlicePointer(valueBuf), opts) +} + // BatchDelete batch deletes entries in the map by keys. // "keys" must be of type slice, a pointer to a slice or buffer will not work. func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error) { - if m.typ.hasPerCPUValue() { - return 0, ErrNotSupported - } - keysValue := reflect.ValueOf(keys) - if keysValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("keys must be a slice") + count, err := sliceLen(keys) + if err != nil { + return 0, fmt.Errorf("keys: %w", err) } - count := keysValue.Len() + keyPtr, err := marshalMapSyscallInput(keys, count*int(m.keySize)) if err != nil { return 0, fmt.Errorf("cannot marshal keys: %v", err) @@ -1174,6 +1208,24 @@ func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error) { return int(attr.Count), nil } +func batchCount(keys, values any) (int, error) { + keysLen, err := sliceLen(keys) + if err != nil { + return 0, fmt.Errorf("keys: %w", err) + } + + valuesLen, err := sliceLen(values) + if err != nil { + return 0, fmt.Errorf("values: %w", err) + } + + if keysLen != valuesLen { + return 0, fmt.Errorf("keys and values must have the same length") + } + + return keysLen, nil +} + // Iterate traverses a map. // // It's safe to create multiple iterators at the same time. @@ -1552,3 +1604,12 @@ func NewMapFromID(id MapID) (*Map, error) { return newMapFromFD(fd) } + +// sliceLen returns the length if the value is a slice or an error otherwise. +func sliceLen(slice any) (int, error) { + sliceValue := reflect.ValueOf(slice) + if sliceValue.Kind() != reflect.Slice { + return 0, fmt.Errorf("%T is not a slice", slice) + } + return sliceValue.Len(), nil +} diff --git a/vendor/github.com/cilium/ebpf/marshalers.go b/vendor/github.com/cilium/ebpf/marshalers.go index d77a5fb81f7..1efa5d425df 100644 --- a/vendor/github.com/cilium/ebpf/marshalers.go +++ b/vendor/github.com/cilium/ebpf/marshalers.go @@ -10,6 +10,8 @@ import ( "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/sysenc" + + "golang.org/x/exp/slices" ) // marshalMapSyscallInput converts an arbitrary value into a pointer suitable @@ -43,44 +45,90 @@ func makeMapSyscallOutput(dst any, length int) sysenc.Buffer { return sysenc.SyscallOutput(dst, length) } -// marshalPerCPUValue encodes a slice containing one value per +// appendPerCPUSlice encodes a slice containing one value per // possible CPU into a buffer of bytes. // // Values are initialized to zero if the slice has less elements than CPUs. -func marshalPerCPUValue(slice any, elemLength int) (sys.Pointer, error) { +func appendPerCPUSlice(buf []byte, slice any, possibleCPUs, elemLength, alignedElemLength int) ([]byte, error) { sliceType := reflect.TypeOf(slice) if sliceType.Kind() != reflect.Slice { - return sys.Pointer{}, errors.New("per-CPU value requires slice") - } - - possibleCPUs, err := PossibleCPU() - if err != nil { - return sys.Pointer{}, err + return nil, errors.New("per-CPU value requires slice") } sliceValue := reflect.ValueOf(slice) sliceLen := sliceValue.Len() if sliceLen > possibleCPUs { - return sys.Pointer{}, fmt.Errorf("per-CPU value exceeds number of CPUs") + return nil, fmt.Errorf("per-CPU value greater than number of CPUs") } - alignedElemLength := internal.Align(elemLength, 8) - buf := make([]byte, alignedElemLength*possibleCPUs) - + // Grow increases the slice's capacity, _if_necessary_ + buf = slices.Grow(buf, alignedElemLength*possibleCPUs) for i := 0; i < sliceLen; i++ { elem := sliceValue.Index(i).Interface() elemBytes, err := sysenc.Marshal(elem, elemLength) if err != nil { - return sys.Pointer{}, err + return nil, err } - offset := i * alignedElemLength - elemBytes.CopyTo(buf[offset : offset+elemLength]) + buf = elemBytes.AppendTo(buf) + buf = append(buf, make([]byte, alignedElemLength-elemLength)...) + } + + // Ensure buf is zero-padded full size. + buf = append(buf, make([]byte, (possibleCPUs-sliceLen)*alignedElemLength)...) + + return buf, nil +} + +// marshalPerCPUValue encodes a slice containing one value per +// possible CPU into a buffer of bytes. +// +// Values are initialized to zero if the slice has less elements than CPUs. +func marshalPerCPUValue(slice any, elemLength int) (sys.Pointer, error) { + possibleCPUs, err := PossibleCPU() + if err != nil { + return sys.Pointer{}, err + } + + alignedElemLength := internal.Align(elemLength, 8) + buf := make([]byte, 0, alignedElemLength*possibleCPUs) + buf, err = appendPerCPUSlice(buf, slice, possibleCPUs, elemLength, alignedElemLength) + if err != nil { + return sys.Pointer{}, err } return sys.NewSlicePointer(buf), nil } +// marshalBatchPerCPUValue encodes a batch-sized slice of slices containing +// one value per possible CPU into a buffer of bytes. +func marshalBatchPerCPUValue(slice any, batchLen, elemLength int) ([]byte, error) { + sliceType := reflect.TypeOf(slice) + if sliceType.Kind() != reflect.Slice { + return nil, fmt.Errorf("batch value requires a slice") + } + sliceValue := reflect.ValueOf(slice) + + possibleCPUs, err := PossibleCPU() + if err != nil { + return nil, err + } + if sliceValue.Len() != batchLen*possibleCPUs { + return nil, fmt.Errorf("per-CPU slice has incorrect length, expected %d, got %d", + batchLen*possibleCPUs, sliceValue.Len()) + } + alignedElemLength := internal.Align(elemLength, 8) + buf := make([]byte, 0, batchLen*alignedElemLength*possibleCPUs) + for i := 0; i < batchLen; i++ { + batch := sliceValue.Slice(i*possibleCPUs, (i+1)*possibleCPUs).Interface() + buf, err = appendPerCPUSlice(buf, batch, possibleCPUs, elemLength, alignedElemLength) + if err != nil { + return nil, fmt.Errorf("batch %d: %w", i, err) + } + } + return buf, nil +} + // unmarshalPerCPUValue decodes a buffer into a slice containing one value per // possible CPU. // @@ -123,6 +171,41 @@ func unmarshalPerCPUValue(slice any, elemLength int, buf []byte) error { buf = buf[stride:] } + return nil +} +// unmarshalBatchPerCPUValue decodes a buffer into a batch-sized slice +// containing one value per possible CPU. +// +// slice must have length batchLen * PossibleCPUs(). +func unmarshalBatchPerCPUValue(slice any, batchLen, elemLength int, buf []byte) error { + sliceType := reflect.TypeOf(slice) + if sliceType.Kind() != reflect.Slice { + return fmt.Errorf("batch requires a slice") + } + + sliceValue := reflect.ValueOf(slice) + possibleCPUs, err := PossibleCPU() + if err != nil { + return err + } + if sliceValue.Len() != batchLen*possibleCPUs { + return fmt.Errorf("per-CPU slice has incorrect length, expected %d, got %d", + sliceValue.Len(), batchLen*possibleCPUs) + } + + fullValueSize := possibleCPUs * internal.Align(elemLength, 8) + if len(buf) != batchLen*fullValueSize { + return fmt.Errorf("input buffer has incorrect length, expected %d, got %d", + len(buf), batchLen*fullValueSize) + } + + for i := 0; i < batchLen; i++ { + elem := sliceValue.Slice(i*possibleCPUs, (i+1)*possibleCPUs).Interface() + if err := unmarshalPerCPUValue(elem, elemLength, buf[:fullValueSize]); err != nil { + return fmt.Errorf("batch %d: %w", i, err) + } + buf = buf[fullValueSize:] + } return nil } diff --git a/vendor/github.com/cilium/ebpf/perf/reader.go b/vendor/github.com/cilium/ebpf/perf/reader.go index 1aec79d50b2..3c820708c72 100644 --- a/vendor/github.com/cilium/ebpf/perf/reader.go +++ b/vendor/github.com/cilium/ebpf/perf/reader.go @@ -231,11 +231,12 @@ func NewReaderWithOptions(array *ebpf.Map, perCPUBuffer int, opts ReaderOptions) pauseFds = append(pauseFds, -1) continue } - bufferSize = ring.size() if err != nil { return nil, fmt.Errorf("failed to create perf ring for CPU %d: %v", i, err) } + + bufferSize = ring.size() rings = append(rings, ring) pauseFds = append(pauseFds, ring.fd) diff --git a/vendor/github.com/cilium/ebpf/run-tests.sh b/vendor/github.com/cilium/ebpf/run-tests.sh index d48e97adc93..9f435613903 100644 --- a/vendor/github.com/cilium/ebpf/run-tests.sh +++ b/vendor/github.com/cilium/ebpf/run-tests.sh @@ -14,6 +14,8 @@ set -euo pipefail script="$(realpath "$0")" readonly script +source "$(dirname "$script")/testdata/sh/lib.sh" + quote_env() { for var in "$@"; do if [ -v "$var" ]; then @@ -120,26 +122,6 @@ fi input="$(mktemp -d)" readonly input -readonly docker="${CONTAINER_ENGINE:-docker}" - -extract_oci_image() { - local image_name=$1 - local target_directory=$2 - - echo -n "Fetching $image_name... " - - # We abuse the --output flag of docker buildx to obtain a copy of the image. - # This is simpler than creating a temporary container and using docker cp. - # It also automatically fetches the image for us if necessary. - if ! echo "FROM $image_name" | "$docker" buildx build --quiet --pull --output="$target_directory" - &> /dev/null; then - echo "failed" - return 1 - fi - - echo "ok" - return 0 -} - if [[ -f "${1}" ]]; then # First argument is a local file. readonly kernel="${1}" diff --git a/vendor/modules.txt b/vendor/modules.txt index c86883d03c5..0031b24f69e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -196,7 +196,7 @@ github.com/cilium/cilium/pkg/wireguard/types # github.com/cilium/dns v1.1.51-0.20230303133941-d3bcb3008ed2 ## explicit; go 1.14 github.com/cilium/dns -# github.com/cilium/ebpf v0.12.4-0.20231215112452-00c0cb05d35c +# github.com/cilium/ebpf v0.12.4-0.20240111120710-654f02de301e ## explicit; go 1.20 github.com/cilium/ebpf github.com/cilium/ebpf/asm