diff options
| -rw-r--r-- | docs/syscall-tracing-plan.md | 2 | ||||
| -rw-r--r-- | integrationtests/ipc_test.go | 5 | ||||
| -rw-r--r-- | internal/c/generated_tracepoints.c | 4 | ||||
| -rw-r--r-- | internal/c/generated_tracepoints_result.txt | 2 | ||||
| -rw-r--r-- | internal/generate/classify.go | 8 | ||||
| -rw-r--r-- | internal/generate/classify_test.go | 4 |
6 files changed, 18 insertions, 7 deletions
diff --git a/docs/syscall-tracing-plan.md b/docs/syscall-tracing-plan.md index 2225d48..9bb94e1 100644 --- a/docs/syscall-tracing-plan.md +++ b/docs/syscall-tracing-plan.md @@ -94,7 +94,7 @@ Payload bytes classified by return value: - ReadClassified: `fgetxattr`, `flistxattr`, `getdents`, `getdents64`, `getrandom`, `getxattr`, `getxattrat`, `lgetxattr`, `listxattr`, `listxattrat`, `llistxattr`, `mq_timedreceive`, `msgrcv`, `pread64`, `preadv`, `preadv2`, `process_vm_readv`, `read`, `readlink`, `readlinkat`, `readv`, `recvfrom`, `recvmsg`, `syslog` - TransferClassified: `copy_file_range`, `sendfile64`, `splice`, `tee`, `vmsplice` -- WriteClassified: `mq_timedsend`, `process_vm_writev`, `pwrite64`, `pwritev`, `pwritev2`, `sendmsg`, `sendto`, `write`, `writev` +- WriteClassified: `process_vm_writev`, `pwrite64`, `pwritev`, `pwritev2`, `sendmsg`, `sendto`, `write`, `writev` All other traced syscalls are treated as non-bytes for throughput accounting. Memory extent is tracked separately via address-space metrics. diff --git a/integrationtests/ipc_test.go b/integrationtests/ipc_test.go index 5672bbe..9c1efcc 100644 --- a/integrationtests/ipc_test.go +++ b/integrationtests/ipc_test.go @@ -113,7 +113,10 @@ func TestPosixMqBasic(t *testing.T) { sendExp := ExpectedEvent{Tracepoint: "enter_mq_timedsend", Comm: "ioworkload", PathContains: "/ior-mq-"} recvExp := ExpectedEvent{Tracepoint: "enter_mq_timedreceive", Comm: "ioworkload", PathContains: "/ior-mq-"} - assertEventBytesAtLeast(t, result, sendExp, mqPayloadLen) + // mq_timedsend returns 0 on success (a status, not a byte count), so it is + // UNCLASSIFIED and must NOT be attributed any write bytes. Only + // mq_timedreceive returns a real received byte count (ReadClassified). + assertEventBytesEqual(t, result, sendExp, 0) assertEventBytesAtLeast(t, result, recvExp, mqPayloadLen) assertEventDurationPositive(t, result, sendExp) assertEventDurationPositive(t, result, recvExp) diff --git a/internal/c/generated_tracepoints.c b/internal/c/generated_tracepoints.c index 8e3f996..4ec7b86 100644 --- a/internal/c/generated_tracepoints.c +++ b/internal/c/generated_tracepoints.c @@ -2593,7 +2593,7 @@ int handle_sys_enter_mq_timedsend(struct syscall_trace_enter *ctx) { return 0; } -/// sys_exit_mq_timedsend is a struct ret_event (WRITE_CLASSIFIED) (kind=ret) +/// sys_exit_mq_timedsend is a struct ret_event (UNCLASSIFIED) (kind=ret) SEC("tracepoint/syscalls/sys_exit_mq_timedsend") int handle_sys_exit_mq_timedsend(struct syscall_trace_exit *ctx) { __u32 pid, tid; @@ -2613,7 +2613,7 @@ int handle_sys_exit_mq_timedsend(struct syscall_trace_exit *ctx) { ev->tid = tid; ev->time = bpf_ktime_get_boot_ns(); ev->ret = ctx->ret; - ev->ret_type = WRITE_CLASSIFIED; + ev->ret_type = UNCLASSIFIED; bpf_ringbuf_submit(ev, 0); return 0; diff --git a/internal/c/generated_tracepoints_result.txt b/internal/c/generated_tracepoints_result.txt index 0a88f30..3804441 100644 --- a/internal/c/generated_tracepoints_result.txt +++ b/internal/c/generated_tracepoints_result.txt @@ -544,7 +544,7 @@ sys_exit_mq_getsetattr is a struct ret_event (UNCLASSIFIED) (kind=ret) sys_exit_mq_notify is a struct ret_event (UNCLASSIFIED) (kind=ret) sys_exit_mq_open is a struct ret_event (UNCLASSIFIED) (kind=ret) sys_exit_mq_timedreceive is a struct ret_event (READ_CLASSIFIED) (kind=ret) -sys_exit_mq_timedsend is a struct ret_event (WRITE_CLASSIFIED) (kind=ret) +sys_exit_mq_timedsend is a struct ret_event (UNCLASSIFIED) (kind=ret) sys_exit_mq_unlink is a struct ret_event (UNCLASSIFIED) (kind=ret) sys_exit_mremap is a struct ret_event (UNCLASSIFIED) (kind=ret) sys_exit_mseal is a struct ret_event (UNCLASSIFIED) (kind=ret) diff --git a/internal/generate/classify.go b/internal/generate/classify.go index c1125e5..3ba0c00 100644 --- a/internal/generate/classify.go +++ b/internal/generate/classify.go @@ -632,5 +632,11 @@ var retClassifications = map[string]RetClassification{ // UNCLASSIFIED so the stats engine never treats the return as bytes written. "write": WriteClassified, "writev": WriteClassified, - "mq_timedsend": WriteClassified, + // mq_timedsend is deliberately NOT listed here: mq_timedsend(2)/mq_send(3) + // return 0 on success or -1 on error — NOT a byte count (msg_len is an + // INPUT arg, never the return). Listing it as WriteClassified made + // bytesFromRet attribute its 0 return as "bytes written". Like its POSIX mq + // sibling mq_timedreceive (which genuinely returns the received byte count + // and stays ReadClassified), mq_timedsend's int status must stay + // UNCLASSIFIED. This mirrors the SysV IPC msgsnd vs msgrcv asymmetry. } diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go index bd03af4..4993293 100644 --- a/internal/generate/classify_test.go +++ b/internal/generate/classify_test.go @@ -350,7 +350,9 @@ func TestClassifyMqSyscallPairsAcceptedAndClassified(t *testing.T) { }{ {"mq_open", "struct open_event", "UNCLASSIFIED"}, {"mq_unlink", "struct path_event", "UNCLASSIFIED"}, - {"mq_timedsend", "struct fd_event", "WRITE_CLASSIFIED"}, + // mq_timedsend returns 0/-1 (a status), not a byte count, so its ret is + // UNCLASSIFIED. Only mq_timedreceive returns a real received byte count. + {"mq_timedsend", "struct fd_event", "UNCLASSIFIED"}, {"mq_timedreceive", "struct fd_event", "READ_CLASSIFIED"}, {"mq_notify", "struct fd_event", "UNCLASSIFIED"}, {"mq_getsetattr", "struct fd_event", "UNCLASSIFIED"}, |
