perf event: No need to create a thread when handling PERF_RECORD_EXIT
authorArnaldo Carvalho de Melo <acme@redhat.com>
Sat, 6 Oct 2012 18:44:59 +0000 (15:44 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Sat, 6 Oct 2012 19:33:45 +0000 (16:33 -0300)
When we were processing a PERF_RECORD_EXIT event we first used
machine__findnew_thread for both the thread exiting and for its parent,
only to use just the thread struct associated with the one exiting, and
to just delete it.

If it existed, i.e. not created at this very moment in
machine__findnew_thread, it will be moved to the machine->dead_threads
linked list, because we may have hist_entries pointing to it, but if it
was created just do be deleted, it will just sit there with no
references at all.

Use the new machine__find_thread() method so that if it is not there, we
don't create it.

As a bonus the parent thread will also not be created at this point.

Create process_fork() and process_exit() helpers to use this and make
the builtins use it instead of the generic process_task(), ditched by
this patch.

Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-z7n2y98ebjyrvmytaope4vdl@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-annotate.c
tools/perf/builtin-diff.c
tools/perf/builtin-inject.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-script.c
tools/perf/util/build-id.c
tools/perf/util/event.c
tools/perf/util/event.h

index 9ea38540b873b5ca02567aeb9114313f96fa6764..cca2fb5c436f889219c7415963f0791b3f4c3464 100644 (file)
@@ -246,7 +246,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
                        .sample = process_sample_event,
                        .mmap   = perf_event__process_mmap,
                        .comm   = perf_event__process_comm,
-                       .fork   = perf_event__process_task,
+                       .fork   = perf_event__process_fork,
                        .ordered_samples = true,
                        .ordering_requires_timestamps = true,
                },
index b4db513751997398816d53a3c691c4ff9c2bf311..380683de1df38c3f097b3184d6cc62024c3a7170 100644 (file)
@@ -285,8 +285,8 @@ static struct perf_tool tool = {
        .sample = diff__process_sample_event,
        .mmap   = perf_event__process_mmap,
        .comm   = perf_event__process_comm,
-       .exit   = perf_event__process_task,
-       .fork   = perf_event__process_task,
+       .exit   = perf_event__process_exit,
+       .fork   = perf_event__process_fork,
        .lost   = perf_event__process_lost,
        .ordered_samples = true,
        .ordering_requires_timestamps = true,
index 4688bea95c12e4d3dedfb1d12180848aaa8fd725..386a5c0013ffcace497e44c745f23b663c6fed0d 100644 (file)
@@ -102,14 +102,14 @@ static int perf_event__repipe_mmap(struct perf_tool *tool,
        return err;
 }
 
-static int perf_event__repipe_task(struct perf_tool *tool,
+static int perf_event__repipe_fork(struct perf_tool *tool,
                                   union perf_event *event,
                                   struct perf_sample *sample,
                                   struct machine *machine)
 {
        int err;
 
-       err = perf_event__process_task(tool, event, sample, machine);
+       err = perf_event__process_fork(tool, event, sample, machine);
        perf_event__repipe(tool, event, sample, machine);
 
        return err;
@@ -227,7 +227,7 @@ static int __cmd_inject(struct perf_inject *inject)
        if (inject->build_ids) {
                inject->tool.sample       = perf_event__inject_buildid;
                inject->tool.mmap         = perf_event__repipe_mmap;
-               inject->tool.fork         = perf_event__repipe_task;
+               inject->tool.fork         = perf_event__repipe_fork;
                inject->tool.tracing_data = perf_event__repipe_tracing_data;
        }
 
index a61725d89d3ee4188dbe7c4b542c6e1f3685d506..5104a40af5634fb62f0089a81d85e2c73bc2219f 100644 (file)
@@ -556,8 +556,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
                        .sample          = process_sample_event,
                        .mmap            = perf_event__process_mmap,
                        .comm            = perf_event__process_comm,
-                       .exit            = perf_event__process_task,
-                       .fork            = perf_event__process_task,
+                       .exit            = perf_event__process_exit,
+                       .fork            = perf_event__process_fork,
                        .lost            = perf_event__process_lost,
                        .read            = process_read_event,
                        .attr            = perf_event__process_attr,
index 3488ead3b60ce80707493e93f821945bad8a6455..3a25cd83b56e7c4322c0711e2375f59dd3965a56 100644 (file)
@@ -1672,7 +1672,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
                        .sample          = perf_sched__process_tracepoint_sample,
                        .comm            = perf_event__process_comm,
                        .lost            = perf_event__process_lost,
-                       .fork            = perf_event__process_task,
+                       .fork            = perf_event__process_fork,
                        .ordered_samples = true,
                },
                .cmp_pid              = LIST_HEAD_INIT(sched.cmp_pid),
index fb9625083a2ed6d9d4bd25b94bc306895f18d6fc..04ceb0779d399037567cc80b0f97a7e8e131ebc3 100644 (file)
@@ -520,8 +520,8 @@ static struct perf_tool perf_script = {
        .sample          = process_sample_event,
        .mmap            = perf_event__process_mmap,
        .comm            = perf_event__process_comm,
-       .exit            = perf_event__process_task,
-       .fork            = perf_event__process_task,
+       .exit            = perf_event__process_exit,
+       .fork            = perf_event__process_fork,
        .attr            = perf_event__process_attr,
        .event_type      = perf_event__process_event_type,
        .tracing_data    = perf_event__process_tracing_data,
index 8e3a740ddbd4eed2059aa08d8d7592fea4075833..6a6399955ef2ddee6b163e0a8e1f2c18dfda250b 100644 (file)
@@ -64,7 +64,7 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused,
 struct perf_tool build_id__mark_dso_hit_ops = {
        .sample = build_id__mark_dso_hit,
        .mmap   = perf_event__process_mmap,
-       .fork   = perf_event__process_task,
+       .fork   = perf_event__process_fork,
        .exit   = perf_event__exit_del_thread,
        .attr            = perf_event__process_attr,
        .build_id        = perf_event__process_build_id,
index 6715b19387258cd184bba45d88a00e76eaebbeba..eaaee22628ea63864d9d79abe2c322088304f7ac 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/types.h>
 #include "event.h"
 #include "debug.h"
+#include "machine.h"
 #include "sort.h"
 #include "string.h"
 #include "strlist.h"
@@ -702,10 +703,10 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
                       event->fork.ppid, event->fork.ptid);
 }
 
-int perf_event__process_task(struct perf_tool *tool __maybe_unused,
+int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
                             union perf_event *event,
                             struct perf_sample *sample __maybe_unused,
-                             struct machine *machine)
+                            struct machine *machine)
 {
        struct thread *thread = machine__findnew_thread(machine, event->fork.tid);
        struct thread *parent = machine__findnew_thread(machine, event->fork.ptid);
@@ -713,11 +714,6 @@ int perf_event__process_task(struct perf_tool *tool __maybe_unused,
        if (dump_trace)
                perf_event__fprintf_task(event, stdout);
 
-       if (event->header.type == PERF_RECORD_EXIT) {
-               machine__remove_thread(machine, thread);
-               return 0;
-       }
-
        if (thread == NULL || parent == NULL ||
            thread__fork(thread, parent) < 0) {
                dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
@@ -727,6 +723,22 @@ int perf_event__process_task(struct perf_tool *tool __maybe_unused,
        return 0;
 }
 
+int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
+                            union perf_event *event,
+                            struct perf_sample *sample __maybe_unused,
+                            struct machine *machine)
+{
+       struct thread *thread = machine__find_thread(machine, event->fork.tid);
+
+       if (dump_trace)
+               perf_event__fprintf_task(event, stdout);
+
+       if (thread != NULL)
+               machine__remove_thread(machine, thread);
+
+       return 0;
+}
+
 size_t perf_event__fprintf(union perf_event *event, FILE *fp)
 {
        size_t ret = fprintf(fp, "PERF_RECORD_%s",
@@ -761,8 +773,10 @@ int perf_event__process(struct perf_tool *tool, union perf_event *event,
                perf_event__process_mmap(tool, event, sample, machine);
                break;
        case PERF_RECORD_FORK:
+               perf_event__process_fork(tool, event, sample, machine);
+               break;
        case PERF_RECORD_EXIT:
-               perf_event__process_task(tool, event, sample, machine);
+               perf_event__process_exit(tool, event, sample, machine);
                break;
        case PERF_RECORD_LOST:
                perf_event__process_lost(tool, event, sample, machine);
index 21b99e741a87c016ab383d683492dfd2aa2017b9..da97aff5bd7592222a7656825f96538eec911361 100644 (file)
@@ -191,7 +191,11 @@ int perf_event__process_mmap(struct perf_tool *tool,
                             union perf_event *event,
                             struct perf_sample *sample,
                             struct machine *machine);
-int perf_event__process_task(struct perf_tool *tool,
+int perf_event__process_fork(struct perf_tool *tool,
+                            union perf_event *event,
+                            struct perf_sample *sample,
+                            struct machine *machine);
+int perf_event__process_exit(struct perf_tool *tool,
                             union perf_event *event,
                             struct perf_sample *sample,
                             struct machine *machine);