]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf trace: Fix potential u64 underflow in duration calculation
authorMichael Petlan <mpetlan@redhat.com>
Thu, 2 Apr 2026 14:51:18 +0000 (16:51 +0200)
committerNamhyung Kim <namhyung@kernel.org>
Fri, 3 Apr 2026 01:43:35 +0000 (18:43 -0700)
Although it happens very rarely, in case of out-of-order events (i.e.
due to CPU migration when a syscall is executed), the calculation of
event duration might underflow and thus a bogus value is printed:

    2.804 ( 0.001 ms): :49553/49553 rt_sigaction(sig: QUIT, act: 0x7fff403ed6e0, oact: 0x7fff403ed780, sigsetsize: 8) = 0
    2.807 ( 0.001 ms): :49553/49553 rt_sigaction(sig: CHLD, act: 0x7fff403ed6e0, oact: 0x7fff403ed780, sigsetsize: 8) = 0
    2.815 (18446744073709.438 ms): :49553/49553 execve(filename: 0xbb173a30, argv: 0x55aabb171930, envp: 0x55aabb171120) = 0
    2.815 ( 0.534 ms): pwd/49553  ... [continued]: execve())                                           = 0

Check for possible underflow first and in case of a bogus value, do
not print it.

    2.804 ( 0.001 ms): :49553/49553 rt_sigaction(sig: QUIT, act: 0x7fff403ed6e0, oact: 0x7fff403ed780, sigsetsize: 8) = 0
    2.807 ( 0.001 ms): :49553/49553 rt_sigaction(sig: CHLD, act: 0x7fff403ed6e0, oact: 0x7fff403ed780, sigsetsize: 8) = 0
    2.815 (         ): :49553/49553 execve(filename: 0xbb173a30, argv: 0x55aabb171930, envp: 0x55aabb171120) = 0
    2.815 ( 0.534 ms): pwd/49553  ... [continued]: execve())                                           = 0

Signed-off-by: Michael Petlan <mpetlan@redhat.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/builtin-trace.c

index d121640ace6e14561d50fc71c69c9adb6d7cb34d..873d144807e2d16a3dde5b1ec9255bb5d9d9272d 100644 (file)
@@ -2960,7 +2960,7 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
                ++trace->stats.vfs_getname;
        }
 
-       if (ttrace->entry_time) {
+       if (ttrace->entry_time && sample->time >= ttrace->entry_time) {
                duration = sample->time - ttrace->entry_time;
                if (trace__filter_duration(trace, duration))
                        goto out;