summaryrefslogtreecommitdiff
path: root/tools/perf/util/machine.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-08-20 09:47:14 (GMT)
committerIngo Molnar <mingo@kernel.org>2015-08-20 09:47:14 (GMT)
commit196676497f2507966f99abef63bede6a8550f8b3 (patch)
treebe58cfeca954483721fa4864db952fc0b032fb63 /tools/perf/util/machine.c
parent1b647a166f07dcf08709c8606470f4b17a4aa11d (diff)
parent09f4d78ab0af0973e1a49c10eb7bf977c68cc3aa (diff)
downloadlinux-196676497f2507966f99abef63bede6a8550f8b3.tar.xz
Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/urgent fixes from Arnaldo Carvalho de Melo: - Fix buildid processing done at the end of a 'perf record' session, a problem that happened in workloads involving lots of small short-lived processes. That code was not asking the perf_session layer to order the events. Make the code more robust to handle some of the problems with such out-of-order events and fix 'perf record' to ask for ordered events on systems where we have perf_event_attr.sample_id_all. (Adrian Hunter) - Show backtrace when handling a SIGSEGV in 'perf top --stdio' (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r--tools/perf/util/machine.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 7ff6827..f1a4c83 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1387,6 +1387,24 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
event->fork.ptid);
int err = 0;
+ if (dump_trace)
+ perf_event__fprintf_task(event, stdout);
+
+ /*
+ * There may be an existing thread that is not actually the parent,
+ * either because we are processing events out of order, or because the
+ * (fork) event that would have removed the thread was lost. Assume the
+ * latter case and continue on as best we can.
+ */
+ if (parent->pid_ != (pid_t)event->fork.ppid) {
+ dump_printf("removing erroneous parent thread %d/%d\n",
+ parent->pid_, parent->tid);
+ machine__remove_thread(machine, parent);
+ thread__put(parent);
+ parent = machine__findnew_thread(machine, event->fork.ppid,
+ event->fork.ptid);
+ }
+
/* if a thread currently exists for the thread id remove it */
if (thread != NULL) {
machine__remove_thread(machine, thread);
@@ -1395,8 +1413,6 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
thread = machine__findnew_thread(machine, event->fork.pid,
event->fork.tid);
- if (dump_trace)
- perf_event__fprintf_task(event, stdout);
if (thread == NULL || parent == NULL ||
thread__fork(thread, parent, sample->time) < 0) {