linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Hari Bathini <hbathini@linux.vnet.ibm.com>
Cc: ast@fb.com, peterz@infradead.org,
	lkml <linux-kernel@vger.kernel.org>,
	alexander.shishkin@linux.intel.com, mingo@redhat.com,
	daniel@iogearbox.net, rostedt@goodmis.org,
	Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>,
	ebiederm@xmission.com, sargun@sargun.me,
	Aravinda Prasad <aravinda@linux.vnet.ibm.com>,
	brendan.d.gregg@gmail.com, jolsa@redhat.com
Subject: Re: [PATCH v7 4/8] perf tool: synthesize namespace events for current processes
Date: Wed, 1 Mar 2017 18:05:58 -0300	[thread overview]
Message-ID: <20170301210558.GK15145@kernel.org> (raw)
In-Reply-To: <148768570431.30285.4321000215785619369.stgit@hbathini.in.ibm.com>

Em Tue, Feb 21, 2017 at 07:31:44PM +0530, Hari Bathini escreveu:
> Synthesize PERF_RECORD_NAMESPACES events for processes that were
> running prior to invocation of perf record, the data for which is
> taken from /proc/$PID/ns. These changes make way for analyzing
> events with regard to namespaces.
> 
> Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
> ---
>  tools/perf/builtin-record.c |   27 +++++++++--
>  tools/perf/util/event.c     |  107 +++++++++++++++++++++++++++++++++++++++++--
>  tools/perf/util/event.h     |    6 ++
>  3 files changed, 130 insertions(+), 10 deletions(-)
> 
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index a8b9a78..f4bf6a6 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,28 @@ 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) + 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..c8c112a 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,56 @@ 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) + machine->id_hdr_size);
> +
> +	event->namespaces.pid = tgid;
> +	event->namespaces.tid = pid;
> +
> +	event->namespaces.nr_namespaces = NR_NAMESPACES;

Huh? Don't you have to first figure out how many namespaces a process is
in to then set this field? 

> +	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) +
> +					 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 +502,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 +524,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 +562,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 +595,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 +610,15 @@ 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) +
> +				  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 +644,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 +653,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 +674,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 +692,16 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
>  	if (fork_event == NULL)
>  		goto out_free_mmap;
>  
> +	namespaces_event = malloc(sizeof(namespaces_event->namespaces) +
> +				  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 +713,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 4e90b09..c73ad47 100644
> --- a/tools/perf/util/event.h
> +++ b/tools/perf/util/event.h
> @@ -650,6 +650,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,

  reply	other threads:[~2017-03-01 21:17 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-21 14:01 [PATCH v7 0/8] perf: add support for analyzing events for containers Hari Bathini
2017-02-21 14:01 ` [PATCH v7 1/8] perf: add PERF_RECORD_NAMESPACES to include namespaces related info Hari Bathini
2017-02-24 12:14   ` Peter Zijlstra
2017-03-01 20:45     ` Arnaldo Carvalho de Melo
2017-02-21 14:01 ` [PATCH v7 2/8] perf tool: " Hari Bathini
2017-03-01 21:02   ` Arnaldo Carvalho de Melo
2017-03-03  8:54     ` Hari Bathini
2017-02-21 14:01 ` [PATCH v7 3/8] perf tool: update about the new option to record namespace events Hari Bathini
2017-03-01 21:03   ` Arnaldo Carvalho de Melo
2017-02-21 14:01 ` [PATCH v7 4/8] perf tool: synthesize namespace events for current processes Hari Bathini
2017-03-01 21:05   ` Arnaldo Carvalho de Melo [this message]
2017-03-03  8:57     ` Hari Bathini
2017-02-21 14:01 ` [PATCH v7 5/8] perf tool: add print support for namespace events Hari Bathini
2017-03-01 21:06   ` Arnaldo Carvalho de Melo
2017-02-21 14:02 ` [PATCH v7 6/8] perf tool: add script " Hari Bathini
2017-03-01 21:08   ` Arnaldo Carvalho de Melo
2017-02-21 14:02 ` [PATCH v7 7/8] perf tool: update about the new option to show " Hari Bathini
2017-02-21 14:03 ` [PATCH v7 8/8] perf tool: add cgroup identifier entry in perf report Hari Bathini
2017-02-22 16:48   ` Jiri Olsa
2017-03-01 21:16   ` Arnaldo Carvalho de Melo
2017-03-03  8:59     ` Hari Bathini
2017-02-22 11:11 ` [PATCH v7 0/8] perf: add support for analyzing events for containers Jiri Olsa
2017-02-22 12:40   ` Hari Bathini
2017-02-22 13:52     ` Jiri Olsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170301210558.GK15145@kernel.org \
    --to=acme@kernel.org \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=ananth@linux.vnet.ibm.com \
    --cc=aravinda@linux.vnet.ibm.com \
    --cc=ast@fb.com \
    --cc=brendan.d.gregg@gmail.com \
    --cc=daniel@iogearbox.net \
    --cc=ebiederm@xmission.com \
    --cc=hbathini@linux.vnet.ibm.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=sargun@sargun.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).