From 3e00ee8e994147c2dce70bc785fb6fb70f3ecd41 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 21 May 2026 17:58:01 +0300 Subject: j7 add futex kind and aggregate-only defaults --- internal/c/generated_tracepoints.c | 10 +++++----- internal/c/generated_tracepoints_result.txt | 10 +++++----- internal/flags/flags.go | 2 +- internal/flags/sampling.go | 24 +++++++++++++++++++++++ internal/flags/sampling_test.go | 26 +++++++++++++++++++++++++ internal/generate/classify.go | 13 +++++++++++++ internal/generate/classify_test.go | 25 ++++++++++++++++++++++++ internal/generate/codegen_test.go | 4 +++- internal/generate/kindregistry.go | 1 + internal/tracepoints/dimension_selector_test.go | 15 ++++++++++++++ internal/tracepoints/generated_tracepoints.go | 10 +++++----- 11 files changed, 123 insertions(+), 17 deletions(-) diff --git a/internal/c/generated_tracepoints.c b/internal/c/generated_tracepoints.c index 8dbacc2..e2035db 100644 --- a/internal/c/generated_tracepoints.c +++ b/internal/c/generated_tracepoints.c @@ -13658,7 +13658,7 @@ int handle_sys_exit_get_robust_list(struct syscall_trace_exit *ctx) { return 0; } -/// sys_enter_futex is a struct null_event (kind=null) +/// sys_enter_futex is a struct null_event (kind=futex) SEC("tracepoint/syscalls/sys_enter_futex") int handle_sys_enter_futex(struct syscall_trace_enter *ctx) { __u32 pid, tid; @@ -13708,7 +13708,7 @@ int handle_sys_exit_futex(struct syscall_trace_exit *ctx) { return 0; } -/// sys_enter_futex_waitv is a struct null_event (kind=null) +/// sys_enter_futex_waitv is a struct null_event (kind=futex) SEC("tracepoint/syscalls/sys_enter_futex_waitv") int handle_sys_enter_futex_waitv(struct syscall_trace_enter *ctx) { __u32 pid, tid; @@ -13758,7 +13758,7 @@ int handle_sys_exit_futex_waitv(struct syscall_trace_exit *ctx) { return 0; } -/// sys_enter_futex_wake is a struct null_event (kind=null) +/// sys_enter_futex_wake is a struct null_event (kind=futex) SEC("tracepoint/syscalls/sys_enter_futex_wake") int handle_sys_enter_futex_wake(struct syscall_trace_enter *ctx) { __u32 pid, tid; @@ -13808,7 +13808,7 @@ int handle_sys_exit_futex_wake(struct syscall_trace_exit *ctx) { return 0; } -/// sys_enter_futex_wait is a struct null_event (kind=null) +/// sys_enter_futex_wait is a struct null_event (kind=futex) SEC("tracepoint/syscalls/sys_enter_futex_wait") int handle_sys_enter_futex_wait(struct syscall_trace_enter *ctx) { __u32 pid, tid; @@ -13858,7 +13858,7 @@ int handle_sys_exit_futex_wait(struct syscall_trace_exit *ctx) { return 0; } -/// sys_enter_futex_requeue is a struct null_event (kind=null) +/// sys_enter_futex_requeue is a struct null_event (kind=futex) SEC("tracepoint/syscalls/sys_enter_futex_requeue") int handle_sys_enter_futex_requeue(struct syscall_trace_enter *ctx) { __u32 pid, tid; diff --git a/internal/c/generated_tracepoints_result.txt b/internal/c/generated_tracepoints_result.txt index 2da645d..ff6598c 100644 --- a/internal/c/generated_tracepoints_result.txt +++ b/internal/c/generated_tracepoints_result.txt @@ -74,11 +74,11 @@ sys_enter_fspick is a struct path_event (kind=pathname) sys_enter_fstatfs is a struct fd_event (kind=fd) sys_enter_fsync is a struct fd_event (kind=fd) sys_enter_ftruncate is a struct fd_event (kind=fd) -sys_enter_futex is a struct null_event (kind=null) -sys_enter_futex_requeue is a struct null_event (kind=null) -sys_enter_futex_wait is a struct null_event (kind=null) -sys_enter_futex_waitv is a struct null_event (kind=null) -sys_enter_futex_wake is a struct null_event (kind=null) +sys_enter_futex is a struct null_event (kind=futex) +sys_enter_futex_requeue is a struct null_event (kind=futex) +sys_enter_futex_wait is a struct null_event (kind=futex) +sys_enter_futex_waitv is a struct null_event (kind=futex) +sys_enter_futex_wake is a struct null_event (kind=futex) sys_enter_futimesat is a struct path_event (kind=pathname) sys_enter_get_mempolicy is a struct null_event (kind=null) sys_enter_get_robust_list is a struct null_event (kind=null) diff --git a/internal/flags/flags.go b/internal/flags/flags.go index 547ba8e..cc39638 100644 --- a/internal/flags/flags.go +++ b/internal/flags/flags.go @@ -265,7 +265,7 @@ func resolveSamplingRates(cfg *Config, familySampling, syscallSampling *string) return err } cfg.SyscallFamilySamplingRates = familyRates - cfg.SyscallSamplingRates = syscallRates + cfg.SyscallSamplingRates = mergeSyscallSamplingRates(syscallRates) return nil } diff --git a/internal/flags/sampling.go b/internal/flags/sampling.go index 19b4f9d..2f63ada 100644 --- a/internal/flags/sampling.go +++ b/internal/flags/sampling.go @@ -8,6 +8,14 @@ import ( "ior/internal/types" ) +var defaultAggregateOnlySyscalls = []string{ + "futex", + "futex_wait", + "futex_wake", + "futex_requeue", + "futex_waitv", +} + func cloneFamilySamplingRates(in map[types.SyscallFamily]uint32) map[types.SyscallFamily]uint32 { out := make(map[types.SyscallFamily]uint32, len(in)) for family, rate := range in { @@ -24,6 +32,22 @@ func cloneSyscallSamplingRates(in map[string]uint32) map[string]uint32 { return out } +func defaultSyscallSamplingRates() map[string]uint32 { + out := make(map[string]uint32, len(defaultAggregateOnlySyscalls)) + for _, syscall := range defaultAggregateOnlySyscalls { + out[syscall] = 0 + } + return out +} + +func mergeSyscallSamplingRates(overrides map[string]uint32) map[string]uint32 { + out := defaultSyscallSamplingRates() + for syscall, rate := range overrides { + out[syscall] = rate + } + return out +} + func parseFamilySamplingRates(raw string) (map[types.SyscallFamily]uint32, error) { entries, err := parseSamplingEntries(raw) if err != nil { diff --git a/internal/flags/sampling_test.go b/internal/flags/sampling_test.go index 0966c0f..82a43ec 100644 --- a/internal/flags/sampling_test.go +++ b/internal/flags/sampling_test.go @@ -76,3 +76,29 @@ func TestCloneDeepCopiesSamplingMaps(t *testing.T) { t.Fatalf("original syscall rate mutated: got %d, want 9", got) } } + +func TestDefaultSamplingRatesIncludeFutexAggregateOnly(t *testing.T) { + cfg, err := parseForTest(t) + if err != nil { + t.Fatalf("parse returned error: %v", err) + } + for _, syscall := range []string{"futex", "futex_wait", "futex_wake", "futex_requeue", "futex_waitv"} { + rate, ok := cfg.SyscallSamplingRates[syscall] + if !ok { + t.Fatalf("expected default sampling entry for %s", syscall) + } + if rate != 0 { + t.Fatalf("%s default rate = %d, want 0 (aggregate-only)", syscall, rate) + } + } +} + +func TestParseSamplingRatesOverrideDefaultFutexRate(t *testing.T) { + cfg, err := parseForTest(t, "-syscall-sampling-syscalls", "futex=7") + if err != nil { + t.Fatalf("parse returned error: %v", err) + } + if got := cfg.SyscallSamplingRates["futex"]; got != 7 { + t.Fatalf("futex rate = %d, want 7", got) + } +} diff --git a/internal/generate/classify.go b/internal/generate/classify.go index 3fa8d23..ffac1b3 100644 --- a/internal/generate/classify.go +++ b/internal/generate/classify.go @@ -37,6 +37,7 @@ const ( KindSysVOp KindProc KindBpf + KindFutex ) func (k TracepointKind) MetadataName() string { @@ -103,6 +104,8 @@ func (k TracepointKind) MetadataName() string { return "proc" case KindBpf: return "bpf" + case KindFutex: + return "futex" default: return "none" } @@ -410,6 +413,16 @@ func classifyNameOnly(name string) (ClassificationResult, bool) { return ClassificationResult{Kind: KindProc}, true case "sys_enter_bpf": return ClassificationResult{Kind: KindBpf}, true + case "sys_enter_futex": + return ClassificationResult{Kind: KindFutex}, true + case "sys_enter_futex_wait": + return ClassificationResult{Kind: KindFutex}, true + case "sys_enter_futex_wake": + return ClassificationResult{Kind: KindFutex}, true + case "sys_enter_futex_requeue": + return ClassificationResult{Kind: KindFutex}, true + case "sys_enter_futex_waitv": + return ClassificationResult{Kind: KindFutex}, true case "sys_enter_pidfd_send_signal": return ClassificationResult{Kind: KindFd}, true case "sys_enter_kexec_file_load": diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go index 07445ec..c3c7676 100644 --- a/internal/generate/classify_test.go +++ b/internal/generate/classify_test.go @@ -780,6 +780,31 @@ func TestClassifyL7NameOnlyKinds(t *testing.T) { } } +func TestClassifyJ7NameOnlyKinds(t *testing.T) { + tests := []string{ + "sys_enter_futex", + "sys_enter_futex_wait", + "sys_enter_futex_wake", + "sys_enter_futex_requeue", + "sys_enter_futex_waitv", + } + + for _, name := range tests { + t.Run(name, func(t *testing.T) { + r := ClassifyFormat(&Format{ + Name: name, + ExternalFields: []Field{ + {Type: "long", Name: "__syscall_nr"}, + {Type: "long", Name: "arg0"}, + }, + }) + if r.Kind != KindFutex { + t.Fatalf("%s: got kind %d, want KindFutex", name, r.Kind) + } + }) + } +} + func TestClassify67NameOnlyKinds(t *testing.T) { tests := []struct { name string diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go index 220d77e..cf75324 100644 --- a/internal/generate/codegen_test.go +++ b/internal/generate/codegen_test.go @@ -634,6 +634,7 @@ func TestGenerateAllEventTypes(t *testing.T) { {KindSysVOp, "ENTER_NULL_EVENT", "EXIT_NULL_EVENT"}, {KindProc, "ENTER_NULL_EVENT", "EXIT_NULL_EVENT"}, {KindBpf, "ENTER_NULL_EVENT", "EXIT_NULL_EVENT"}, + {KindFutex, "ENTER_NULL_EVENT", "EXIT_NULL_EVENT"}, } for _, tt := range tests { @@ -682,6 +683,7 @@ func TestEventStructNames(t *testing.T) { {KindSysVOp, "null_event"}, {KindProc, "null_event"}, {KindBpf, "null_event"}, + {KindFutex, "null_event"}, } for _, tt := range tests { @@ -700,7 +702,7 @@ func TestEnterReject(t *testing.T) { t.Error("KindNone should be enter-rejected") } - accepted := []TracepointKind{KindFd, KindOpen, KindMqOpen, KindExec, KindPathname, KindName, KindFcntl, KindNull, KindDup3, KindOpenByHandleAt, KindSocket, KindSocketpair, KindAccept, KindPipe, KindEventfd, KindPidfd, KindEpollCtl, KindTwoFd, KindPoll, KindMem, KindSleep, KindKeyctl, KindPtrace, KindPerfOpen, KindSeccomp, KindModule, KindSysVId, KindSysVOp, KindProc, KindBpf} + accepted := []TracepointKind{KindFd, KindOpen, KindMqOpen, KindExec, KindPathname, KindName, KindFcntl, KindNull, KindDup3, KindOpenByHandleAt, KindSocket, KindSocketpair, KindAccept, KindPipe, KindEventfd, KindPidfd, KindEpollCtl, KindTwoFd, KindPoll, KindMem, KindSleep, KindKeyctl, KindPtrace, KindPerfOpen, KindSeccomp, KindModule, KindSysVId, KindSysVOp, KindProc, KindBpf, KindFutex} for _, k := range accepted { if isEnterRejected(k) { t.Errorf("kind %d should NOT be enter-rejected", k) diff --git a/internal/generate/kindregistry.go b/internal/generate/kindregistry.go index f78bf6f..03977a4 100644 --- a/internal/generate/kindregistry.go +++ b/internal/generate/kindregistry.go @@ -47,6 +47,7 @@ var kindRegistry = map[TracepointKind]kindMeta{ KindSysVOp: {structName: "null_event", enterAccepted: true}, KindProc: {structName: "null_event", enterAccepted: true}, KindBpf: {structName: "null_event", enterAccepted: true}, + KindFutex: {structName: "null_event", enterAccepted: true}, // KindNone is intentionally absent: it represents "unclassified" and is // never enter-accepted. lookupKind returns the zero kindMeta (enterAccepted=false) // for any unregistered kind, so KindNone is implicitly rejected. diff --git a/internal/tracepoints/dimension_selector_test.go b/internal/tracepoints/dimension_selector_test.go index eab18dc..2391ba3 100644 --- a/internal/tracepoints/dimension_selector_test.go +++ b/internal/tracepoints/dimension_selector_test.go @@ -171,6 +171,21 @@ func TestParseSelectorWithDimensionsBpfKindOnly(t *testing.T) { } } +func TestParseSelectorWithDimensionsFutexKindOnly(t *testing.T) { + sel, err := ParseSelectorWithDimensions("", "", DimensionSelectorConfig{ + TraceKinds: "futex", + }) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !sel.ShouldAttach("sys_enter_futex_waitv") { + t.Fatal("expected futex_waitv to be attached for futex kind") + } + if sel.ShouldAttach("sys_enter_openat") { + t.Fatal("expected openat to be excluded when only futex kind is enabled") + } +} + func TestParseSelectorWithDimensionsSyscallOnly(t *testing.T) { sel, err := ParseSelectorWithDimensions("", "", DimensionSelectorConfig{ TraceSyscalls: "openat", diff --git a/internal/tracepoints/generated_tracepoints.go b/internal/tracepoints/generated_tracepoints.go index f27d185..dca04ea 100644 --- a/internal/tracepoints/generated_tracepoints.go +++ b/internal/tracepoints/generated_tracepoints.go @@ -1185,11 +1185,11 @@ var syscallKinds = map[string]string{ "fstatfs": "fd", "fsync": "fd", "ftruncate": "fd", - "futex": "null", - "futex_requeue": "null", - "futex_wait": "null", - "futex_waitv": "null", - "futex_wake": "null", + "futex": "futex", + "futex_requeue": "futex", + "futex_wait": "futex", + "futex_waitv": "futex", + "futex_wake": "futex", "futimesat": "pathname", "get_mempolicy": "null", "get_robust_list": "null", -- cgit v1.2.3