Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Fix use of wrong event when processing exit events

In a couple of cases the 'comm' member of 'union event' has been used
instead of the correct member ('fork') when processing exit events.

In the cases where it has been used incorrectly, only the 'pid' and
'tid' are affected. The 'pid' value would be correct anyway because it
is in the same position in 'comm' and 'fork' events, but the 'tid' would
have been incorrectly assigned from 'ppid'.

However, for exit events, the kernel puts the current task in the 'ppid'
and 'ttid' which is the same as the exiting task. That is 'ppid' ==
'pid' and if the task is not multi-threaded, 'pid' == 'tid' i.e. the
data goes wrong only when tracing multi-threaded programs.

It is hard to find an example of how this would produce an error in
practice. There are 3 occurences of the fix:

1. perf script is only affected if !sample_id_all which only happens on
old kernels.

2. intel_pt is only affected when decoding without timestamps
and would probably still decode correctly - the exit event is
only used to flush out data which anyway gets flushed at the
end of the session

3. intel_bts also uses the exit event to flush data which
would probably not cause errors as it would get flushed at
the end of the session instead

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1439888825-27708-1-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
53ff6bc3 5ad4da43

+4 -4
+2 -2
tools/perf/builtin-script.c
··· 768 768 if (!evsel->attr.sample_id_all) { 769 769 sample->cpu = 0; 770 770 sample->time = 0; 771 - sample->tid = event->comm.tid; 772 - sample->pid = event->comm.pid; 771 + sample->tid = event->fork.tid; 772 + sample->pid = event->fork.pid; 773 773 } 774 774 print_sample_start(sample, thread, evsel); 775 775 perf_event__fprintf(event, stdout);
+1 -1
tools/perf/util/intel-bts.c
··· 623 623 if (err) 624 624 return err; 625 625 if (event->header.type == PERF_RECORD_EXIT) { 626 - err = intel_bts_process_tid_exit(bts, event->comm.tid); 626 + err = intel_bts_process_tid_exit(bts, event->fork.tid); 627 627 if (err) 628 628 return err; 629 629 }
+1 -1
tools/perf/util/intel-pt.c
··· 1494 1494 if (pt->timeless_decoding) { 1495 1495 if (event->header.type == PERF_RECORD_EXIT) { 1496 1496 err = intel_pt_process_timeless_queues(pt, 1497 - event->comm.tid, 1497 + event->fork.tid, 1498 1498 sample->time); 1499 1499 } 1500 1500 } else if (timestamp) {