[tip:perf/core] perf record: Synthesize COMM event for a command line workload

From: tip-bot for Namhyung Kim
Date: Wed Sep 23 2015 - 04:46:39 EST


Commit-ID: e803cf97a4f90d31bcc2c9a1ea20fe9cdc12b2f9
Gitweb: http://git.kernel.org/tip/e803cf97a4f90d31bcc2c9a1ea20fe9cdc12b2f9
Author: Namhyung Kim <namhyung@xxxxxxxxxx>
AuthorDate: Tue, 22 Sep 2015 09:24:55 +0900
Committer: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
CommitDate: Tue, 22 Sep 2015 22:43:12 -0300

perf record: Synthesize COMM event for a command line workload

When perf creates a new child to profile, the events are enabled on
exec(). And in this case, it doesn't synthesize any event for the
child since they'll be generated during exec(). But there's an window
between the enabling and the event generation.

It used to be overcome since samples are only in kernel (so we always
have the map) and the comm is overridden by a later COMM event.
However it won't work if events are processed and displayed before the
COMM event overrides like in 'perf script'. This leads to those early
samples (like native_write_msr_safe) not having a comm but pid (like
':15328').

So it needs to synthesize COMM event for the child explicitly before
enabling so that it can have a correct comm. But at this time, the
comm will be "perf" since it's not exec-ed yet.

Committer note:

Before this patch:

# perf record usleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.017 MB perf.data (7 samples) ]
# perf script --show-task-events
:4429 4429 27909.079372: 1 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
:4429 4429 27909.079375: 1 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
:4429 4429 27909.079376: 10 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
:4429 4429 27909.079377: 223 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
:4429 4429 27909.079378: 6571 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
usleep 4429 27909.079380: PERF_RECORD_COMM exec: usleep:4429/4429
usleep 4429 27909.079381: 185403 cycles: ffffffff810a72d3 flush_signal_handlers (/lib/modules/4.
usleep 4429 27909.079444: 2241110 cycles: 7fc575355be3 _dl_start (/usr/lib64/ld-2.20.so)
usleep 4429 27909.079875: PERF_RECORD_EXIT(4429:4429):(4429:4429)

After:

# perf record usleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.017 MB perf.data (7 samples) ]
# perf script --show-task
perf 0 0.000000: PERF_RECORD_COMM: perf:8446/8446
perf 8446 30154.038944: 1 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
perf 8446 30154.038948: 1 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
perf 8446 30154.038949: 9 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
perf 8446 30154.038950: 230 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
perf 8446 30154.038951: 6772 cycles: ffffffff8105f45a native_write_msr_safe (/lib/modules/4.
usleep 8446 30154.038952: PERF_RECORD_COMM exec: usleep:8446/8446
usleep 8446 30154.038954: 196923 cycles: ffffffff81766440 _raw_spin_lock (/lib/modules/4.3.0-rc1
usleep 8446 30154.039021: 2292130 cycles: 7f609a173dc4 memcpy (/usr/lib64/ld-2.20.so)
usleep 8446 30154.039349: PERF_RECORD_EXIT(8446:8446):(8446:8446)
#

Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
Tested-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Cc: David Ahern <dsahern@xxxxxxxxx>
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Link: http://lkml.kernel.org/r/1442881495-2928-1-git-send-email-namhyung@xxxxxxxxxx
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/builtin-record.c | 15 ++++++++++++++-
tools/perf/util/event.c | 2 +-
tools/perf/util/event.h | 5 +++++
3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 142eeb3..a01c8ae 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -636,8 +636,21 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
/*
* Let the child rip
*/
- if (forks)
+ if (forks) {
+ union perf_event event;
+ /*
+ * Some H/W events are generated before COMM event
+ * which is emitted during exec(), so perf script
+ * cannot see a correct process name for those events.
+ * Synthesize COMM event to prevent it.
+ */
+ perf_event__synthesize_comm(tool, &event,
+ rec->evlist->workload.pid,
+ process_synthesized_event,
+ machine);
+
perf_evlist__start_workload(rec->evlist);
+ }

if (opts->initial_delay) {
usleep(opts->initial_delay * 1000);
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 497157a..6214ad4 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -167,7 +167,7 @@ static int perf_event__prepare_comm(union perf_event *event, pid_t pid,
return 0;
}

-static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
+pid_t perf_event__synthesize_comm(struct perf_tool *tool,
union perf_event *event, pid_t pid,
perf_event__handler_t process,
struct machine *machine)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index f729df5..be5cbc7 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -478,6 +478,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
const struct perf_sample *sample,
bool swapped);

+pid_t perf_event__synthesize_comm(struct perf_tool *tool,
+ union perf_event *event, pid_t pid,
+ perf_event__handler_t process,
+ struct machine *machine);
+
int perf_event__synthesize_mmap_events(struct perf_tool *tool,
union perf_event *event,
pid_t pid, pid_t tgid,
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/