summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/machine.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-08-20 11:48:56 +0200
committerIngo Molnar <mingo@kernel.org>2015-08-20 11:48:56 +0200
commit40a2ea1bd988e3bbdb07a0708681fdb05cd7d267 (patch)
tree05806aaa27a4b0516a14a8ccf703c1501500e588 /tools/perf/util/machine.c
parentMerge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/... (diff)
parentMerge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kerne... (diff)
downloadlinux-40a2ea1bd988e3bbdb07a0708681fdb05cd7d267.tar.xz
linux-40a2ea1bd988e3bbdb07a0708681fdb05cd7d267.zip
Merge branch 'perf/urgent' into perf/core, to pick up fixes before adding more changes
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 be3e00891d22..6309f7ceb08f 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1395,6 +1395,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);
@@ -1403,8 +1421,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) {