From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755602AbbIUA4I (ORCPT ); Sun, 20 Sep 2015 20:56:08 -0400 Received: from LGEAMRELO12.lge.com ([156.147.23.52]:35884 "EHLO lgeamrelo12.lge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753481AbbIUA4G (ORCPT ); Sun, 20 Sep 2015 20:56:06 -0400 X-Greylist: delayed 898 seconds by postgrey-1.27 at vger.kernel.org; Sun, 20 Sep 2015 20:56:06 EDT X-Original-SENDERIP: 156.147.1.125 X-Original-MAILFROM: namhyung@kernel.org X-Original-SENDERIP: 10.177.222.170 X-Original-MAILFROM: namhyung@kernel.org From: Namhyung Kim To: Arnaldo Carvalho de Melo Cc: Ingo Molnar , Peter Zijlstra , Jiri Olsa , LKML , David Ahern Subject: [PATCH 2/2] perf record: Synthesize COMM event for a command line workload Date: Mon, 21 Sep 2015 09:26:49 +0900 Message-Id: <1442795209-6875-2-git-send-email-namhyung@kernel.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1442795209-6875-1-git-send-email-namhyung@kernel.org> References: <1442795209-6875-1-git-send-email-namhyung@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/perf/builtin-record.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 142eeb341b29..b83373adb9f8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -469,6 +469,43 @@ static void workload_exec_failed_signal(int signo __maybe_unused, child_finished = 1; } +static int synthesize_workload_comm_event(struct perf_evlist *evlist, void *arg) +{ + union perf_event *event; + struct record *rec = arg; + struct machine *machine = &rec->session->machines.host; + int pid = evlist->workload.pid; + const char *comm_str = program_invocation_short_name; + size_t comm_size, total_size; + int ret; + + comm_size = PERF_ALIGN(strlen(comm_str) + 1, sizeof(u64)); + total_size = sizeof(event->comm) + machine->id_hdr_size; + /* + * (aligned) comm size might be smaller than expected size + * (i.e. size of event->comm.comm[]), in that case it needs + * to shrink the total size. + */ + if (comm_size < sizeof(event->comm.comm)) + total_size -= sizeof(event->comm.comm) - comm_size; + + event = zalloc(total_size); + if (event == NULL) + return -ENOMEM; + + event->comm.header.type = PERF_RECORD_COMM; + event->comm.header.size = total_size; + + event->comm.pid = pid; + event->comm.tid = pid; + strncpy(event->comm.comm, comm_str, comm_size); + + ret = record__write(rec, event, total_size); + + free(event); + return ret; +} + static void snapshot_sig_handler(int sig); static int __cmd_record(struct record *rec, int argc, const char **argv) @@ -637,7 +674,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) * Let the child rip */ if (forks) - perf_evlist__start_workload(rec->evlist); + perf_evlist__start_workload_ex(rec->evlist, + synthesize_workload_comm_event, + rec); if (opts->initial_delay) { usleep(opts->initial_delay * 1000); -- 2.5.0