Skip to content

Commit 3fd7c36

Browse files
benjaminpacmel
authored andcommitted
perf trace: Do not lose last events in a race
If a perf trace event selector specifies a maximum number of events to output (i.e., "/nr=N/" syntax), the event printing handler, trace__event_handler, disables the event selector after the maximum number events are printed. Furthermore, trace__event_handler checked if the event selector was disabled before doing any work. This avoided exceeding the maximum number of events to print if more events were in the buffer before the selector was disabled. However, the event selector can be disabled for reasons other than exceeding the maximum number of events. In particular, when the traced subprocess exits, the main loop disables all event selectors. This meant the last events of a traced subprocess might be lost to the printing handler's short-circuiting logic. This nondeterministic problem could be seen by running the following many times: $ perf trace -e syscalls:sys_enter_exit_group true trace__event_handler should simply check for exceeding the maximum number of events to print rather than the state of the event selector. Fixes: a9c5e6c ("perf trace: Introduce per-event maximum number of events property") Signed-off-by: Benjamin Peterson <[email protected]> Tested-by: Howard Chu <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 080e47b commit 3fd7c36

File tree

1 file changed

+2
-7
lines changed

1 file changed

+2
-7
lines changed

tools/perf/builtin-trace.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3096,13 +3096,8 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
30963096
{
30973097
struct thread *thread;
30983098
int callchain_ret = 0;
3099-
/*
3100-
* Check if we called perf_evsel__disable(evsel) due to, for instance,
3101-
* this event's max_events having been hit and this is an entry coming
3102-
* from the ring buffer that we should discard, since the max events
3103-
* have already been considered/printed.
3104-
*/
3105-
if (evsel->disabled)
3099+
3100+
if (evsel->nr_events_printed >= evsel->max_events)
31063101
return 0;
31073102

31083103
thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);

0 commit comments

Comments
 (0)