From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752731AbdCNNgo (ORCPT ); Tue, 14 Mar 2017 09:36:44 -0400 Received: from mail.kernel.org ([198.145.29.136]:59286 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751071AbdCNNeb (ORCPT ); Tue, 14 Mar 2017 09:34:31 -0400 Date: Tue, 14 Mar 2017 10:34:24 -0300 From: Arnaldo Carvalho de Melo To: Hari Bathini Cc: ast@fb.com, peterz@infradead.org, lkml , alexander.shishkin@linux.intel.com, mingo@redhat.com, daniel@iogearbox.net, rostedt@goodmis.org, Ananth N Mavinakayanahalli , ebiederm@xmission.com, sargun@sargun.me, Aravinda Prasad , brendan.d.gregg@gmail.com, jolsa@redhat.com Subject: Re: [PATCH v8 3/6] perf record: Synthesize namespace events for current processes Message-ID: <20170314133424.GF3089@kernel.org> References: <148891921533.25309.8328657213311313206.stgit@hbathini.in.ibm.com> <148891931111.25309.11073854609798681633.stgit@hbathini.in.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <148891931111.25309.11073854609798681633.stgit@hbathini.in.ibm.com> X-Url: http://acmel.wordpress.com User-Agent: Mutt/1.7.1 (2016-10-04) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Em Wed, Mar 08, 2017 at 02:11:51AM +0530, Hari Bathini escreveu: > Synthesize PERF_RECORD_NAMESPACES events for processes that were > running prior to invocation of perf record. The data for this is > taken from /proc/$PID/ns. These changes make way for analyzing > events with regard to namespaces. Will investigate... [root@jouet ~]# perf test Lookup 26: Lookup mmap thread : FAILED! [root@jouet ~]# perf test -v Lookup 26: Lookup mmap thread : --- start --- test child forked, pid 3413 tid = 3413, map = 0x7fd99225d000 tid = 3414, map = 0x7fd99225c000 tid = 3415, map = 0x7fd99225b000 tid = 3416, map = 0x7fd99225a000 perf: Segmentation fault Obtained 16 stack frames. perf(dump_stack+0x2d) [0x53dee6] perf(sighandler_dump_stack+0x2d) [0x53dfc6] /lib64/libc.so.6(+0x3598f) [0x7fd98f48898f] perf(perf_event__synthesize_namespaces+0x32) [0x4c808b] perf() [0x4c8de1] perf(perf_event__synthesize_threads+0x20c) [0x4c935d] perf() [0x4aa6e8] perf() [0x4aa7fe] perf(test__mmap_thread_lookup+0x23) [0x4aa9e9] perf() [0x48daf8] perf() [0x48dc2e] perf() [0x48deb5] perf(cmd_test+0x233) [0x48e340] perf() [0x4b90fa] perf() [0x4b9367] perf() [0x4b94ac] test child interrupted ---- end ---- Lookup mmap thread: FAILED! [root@jouet ~]# > Acked-by: Jiri Olsa > Signed-off-by: Hari Bathini > --- > tools/perf/builtin-record.c | 29 ++++++++++- > tools/perf/util/event.c | 111 +++++++++++++++++++++++++++++++++++++++++-- > tools/perf/util/event.h | 6 ++ > 3 files changed, 136 insertions(+), 10 deletions(-) > > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c > index 99562c7..04faef7 100644 > --- a/tools/perf/builtin-record.c > +++ b/tools/perf/builtin-record.c > @@ -986,6 +986,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) > */ > if (forks) { > union perf_event *event; > + pid_t tgid; > > event = malloc(sizeof(event->comm) + machine->id_hdr_size); > if (event == NULL) { > @@ -999,10 +1000,30 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) > * 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); > + tgid = perf_event__synthesize_comm(tool, event, > + rec->evlist->workload.pid, > + process_synthesized_event, > + machine); > + free(event); > + > + if (tgid == -1) > + goto out_child; > + > + event = malloc(sizeof(event->namespaces) + > + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + > + machine->id_hdr_size); > + if (event == NULL) { > + err = -ENOMEM; > + goto out_child; > + } > + > + /* > + * Synthesize NAMESPACES event for the command specified. > + */ > + perf_event__synthesize_namespaces(tool, event, > + rec->evlist->workload.pid, > + tgid, process_synthesized_event, > + machine); > free(event); > > perf_evlist__start_workload(rec->evlist); > diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c > index f118eac..5a99af8 100644 > --- a/tools/perf/util/event.c > +++ b/tools/perf/util/event.c > @@ -50,6 +50,16 @@ static const char *perf_event__names[] = { > [PERF_RECORD_TIME_CONV] = "TIME_CONV", > }; > > +static const char *perf_ns__names[] = { > + [NET_NS_INDEX] = "net", > + [UTS_NS_INDEX] = "uts", > + [IPC_NS_INDEX] = "ipc", > + [PID_NS_INDEX] = "pid", > + [USER_NS_INDEX] = "user", > + [MNT_NS_INDEX] = "mnt", > + [CGROUP_NS_INDEX] = "cgroup", > +}; > + > const char *perf_event__name(unsigned int id) > { > if (id >= ARRAY_SIZE(perf_event__names)) > @@ -59,6 +69,13 @@ const char *perf_event__name(unsigned int id) > return perf_event__names[id]; > } > > +static const char *perf_ns__name(unsigned int id) > +{ > + if (id >= ARRAY_SIZE(perf_ns__names)) > + return "UNKNOWN"; > + return perf_ns__names[id]; > +} > + > static int perf_tool__process_synth_event(struct perf_tool *tool, > union perf_event *event, > struct machine *machine, > @@ -204,6 +221,58 @@ pid_t perf_event__synthesize_comm(struct perf_tool *tool, > return tgid; > } > > +static void perf_event__get_ns_link_info(pid_t pid, const char *ns, > + struct perf_ns_link_info *ns_link_info) > +{ > + struct stat64 st; > + char proc_ns[128]; > + > + sprintf(proc_ns, "/proc/%u/ns/%s", pid, ns); > + if (stat64(proc_ns, &st) == 0) { > + ns_link_info->dev = st.st_dev; > + ns_link_info->ino = st.st_ino; > + } > +} > + > +int perf_event__synthesize_namespaces(struct perf_tool *tool, > + union perf_event *event, > + pid_t pid, pid_t tgid, > + perf_event__handler_t process, > + struct machine *machine) > +{ > + u32 idx; > + struct perf_ns_link_info *ns_link_info; > + > + if (!tool->namespace_events) > + return 0; > + > + memset(&event->namespaces, 0, (sizeof(event->namespaces) + > + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + > + machine->id_hdr_size)); > + > + event->namespaces.pid = tgid; > + event->namespaces.tid = pid; > + > + event->namespaces.nr_namespaces = NR_NAMESPACES; > + > + ns_link_info = event->namespaces.link_info; > + > + for (idx = 0; idx < event->namespaces.nr_namespaces; idx++) > + perf_event__get_ns_link_info(pid, perf_ns__name(idx), > + &ns_link_info[idx]); > + > + event->namespaces.header.type = PERF_RECORD_NAMESPACES; > + > + event->namespaces.header.size = (sizeof(event->namespaces) + > + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + > + machine->id_hdr_size); > + > + if (perf_tool__process_synth_event(tool, event, machine, process) != 0) > + return -1; > + > + return 0; > +} > + > static int perf_event__synthesize_fork(struct perf_tool *tool, > union perf_event *event, > pid_t pid, pid_t tgid, pid_t ppid, > @@ -435,8 +504,9 @@ int perf_event__synthesize_modules(struct perf_tool *tool, > static int __event__synthesize_thread(union perf_event *comm_event, > union perf_event *mmap_event, > union perf_event *fork_event, > + union perf_event *namespaces_event, > pid_t pid, int full, > - perf_event__handler_t process, > + perf_event__handler_t process, > struct perf_tool *tool, > struct machine *machine, > bool mmap_data, > @@ -456,6 +526,11 @@ static int __event__synthesize_thread(union perf_event *comm_event, > if (tgid == -1) > return -1; > > + if (perf_event__synthesize_namespaces(tool, namespaces_event, pid, > + tgid, process, machine) < 0) > + return -1; > + > + > return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, > process, machine, mmap_data, > proc_map_timeout); > @@ -489,6 +564,11 @@ static int __event__synthesize_thread(union perf_event *comm_event, > if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, > ppid, process, machine) < 0) > break; > + > + if (perf_event__synthesize_namespaces(tool, namespaces_event, _pid, > + tgid, process, machine) < 0) > + break; > + > /* > * Send the prepared comm event > */ > @@ -517,6 +597,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, > unsigned int proc_map_timeout) > { > union perf_event *comm_event, *mmap_event, *fork_event; > + union perf_event *namespaces_event; > int err = -1, thread, j; > > comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); > @@ -531,10 +612,16 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, > if (fork_event == NULL) > goto out_free_mmap; > > + namespaces_event = malloc(sizeof(namespaces_event->namespaces) + > + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + > + machine->id_hdr_size); > + if (namespaces_event == NULL) > + goto out_free_fork; > + > err = 0; > for (thread = 0; thread < threads->nr; ++thread) { > if (__event__synthesize_thread(comm_event, mmap_event, > - fork_event, > + fork_event, namespaces_event, > thread_map__pid(threads, thread), 0, > process, tool, machine, > mmap_data, proc_map_timeout)) { > @@ -560,7 +647,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, > /* if not, generate events for it */ > if (need_leader && > __event__synthesize_thread(comm_event, mmap_event, > - fork_event, > + fork_event, namespaces_event, > comm_event->comm.pid, 0, > process, tool, machine, > mmap_data, proc_map_timeout)) { > @@ -569,6 +656,8 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, > } > } > } > + free(namespaces_event); > +out_free_fork: > free(fork_event); > out_free_mmap: > free(mmap_event); > @@ -588,6 +677,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, > char proc_path[PATH_MAX]; > struct dirent *dirent; > union perf_event *comm_event, *mmap_event, *fork_event; > + union perf_event *namespaces_event; > int err = -1; > > if (machine__is_default_guest(machine)) > @@ -605,11 +695,17 @@ int perf_event__synthesize_threads(struct perf_tool *tool, > if (fork_event == NULL) > goto out_free_mmap; > > + namespaces_event = malloc(sizeof(namespaces_event->namespaces) + > + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + > + machine->id_hdr_size); > + if (namespaces_event == NULL) > + goto out_free_fork; > + > snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); > proc = opendir(proc_path); > > if (proc == NULL) > - goto out_free_fork; > + goto out_free_namespaces; > > while ((dirent = readdir(proc)) != NULL) { > char *end; > @@ -621,13 +717,16 @@ int perf_event__synthesize_threads(struct perf_tool *tool, > * We may race with exiting thread, so don't stop just because > * one thread couldn't be synthesized. > */ > - __event__synthesize_thread(comm_event, mmap_event, fork_event, pid, > - 1, process, tool, machine, mmap_data, > + __event__synthesize_thread(comm_event, mmap_event, fork_event, > + namespaces_event, pid, 1, process, > + tool, machine, mmap_data, > proc_map_timeout); > } > > err = 0; > closedir(proc); > +out_free_namespaces: > + free(namespaces_event); > out_free_fork: > free(fork_event); > out_free_mmap: > diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h > index 26efc77..a46a1b4 100644 > --- a/tools/perf/util/event.h > +++ b/tools/perf/util/event.h > @@ -648,6 +648,12 @@ pid_t perf_event__synthesize_comm(struct perf_tool *tool, > perf_event__handler_t process, > struct machine *machine); > > +int perf_event__synthesize_namespaces(struct perf_tool *tool, > + union perf_event *event, > + pid_t pid, pid_t tgid, > + 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,