summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-21 17:58:01 +0300
committerPaul Buetow <paul@buetow.org>2026-05-21 17:58:01 +0300
commit3e00ee8e994147c2dce70bc785fb6fb70f3ecd41 (patch)
tree722485bcdb9227b15fc662fdecd580dfbb8c99c0
parent47091d7d25da2bb80ce8ad2209575e098f726075 (diff)
j7 add futex kind and aggregate-only defaults
-rw-r--r--internal/c/generated_tracepoints.c10
-rw-r--r--internal/c/generated_tracepoints_result.txt10
-rw-r--r--internal/flags/flags.go2
-rw-r--r--internal/flags/sampling.go24
-rw-r--r--internal/flags/sampling_test.go26
-rw-r--r--internal/generate/classify.go13
-rw-r--r--internal/generate/classify_test.go25
-rw-r--r--internal/generate/codegen_test.go4
-rw-r--r--internal/generate/kindregistry.go1
-rw-r--r--internal/tracepoints/dimension_selector_test.go15
-rw-r--r--internal/tracepoints/generated_tracepoints.go10
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",