Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1585357 > unrolled thread

[PATCH v7 0/8] perf: add support for analyzing events for containers

Started byHari Bathini <hbathini@linux.vnet.ibm.com>
First post2017-02-21 15:10 +0100
Last post2017-02-22 15:00 +0100
Articles 10 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v7 0/8] perf: add support for analyzing events for containers Hari Bathini <hbathini@linux.vnet.ibm.com> - 2017-02-21 15:10 +0100
    [PATCH v7 8/8] perf tool: add cgroup identifier entry in perf report Hari Bathini <hbathini@linux.vnet.ibm.com> - 2017-02-21 15:10 +0100
      Re: [PATCH v7 8/8] perf tool: add cgroup identifier entry in perf  report Jiri Olsa <jolsa@redhat.com> - 2017-02-22 17:50 +0100
    [PATCH v7 5/8] perf tool: add print support for namespace events Hari Bathini <hbathini@linux.vnet.ibm.com> - 2017-02-21 15:10 +0100
    [PATCH v7 3/8] perf tool: update about the new option to record  namespace events Hari Bathini <hbathini@linux.vnet.ibm.com> - 2017-02-21 15:10 +0100
    [PATCH v7 6/8] perf tool: add script print support for namespace  events Hari Bathini <hbathini@linux.vnet.ibm.com> - 2017-02-21 15:10 +0100
    [PATCH v7 4/8] perf tool: synthesize namespace events for current  processes Hari Bathini <hbathini@linux.vnet.ibm.com> - 2017-02-21 15:10 +0100
    Re: [PATCH v7 0/8] perf: add support for analyzing events for  containers Jiri Olsa <jolsa@redhat.com> - 2017-02-22 12:20 +0100
      Re: [PATCH v7 0/8] perf: add support for analyzing events for  containers Hari Bathini <hbathini@linux.vnet.ibm.com> - 2017-02-22 13:50 +0100
        Re: [PATCH v7 0/8] perf: add support for analyzing events for  containers Jiri Olsa <jolsa@redhat.com> - 2017-02-22 15:00 +0100

#1585357 — [PATCH v7 0/8] perf: add support for analyzing events for containers

FromHari Bathini <hbathini@linux.vnet.ibm.com>
Date2017-02-21 15:10 +0100
Subject[PATCH v7 0/8] perf: add support for analyzing events for containers
Message-ID<tdjiF-3At-7@gated-at.bofh.it>
Currently, there is no trivial mechanism to analyze events based on
containers. perf -G can be used, but it will not filter events for the                  
containers created after perf is invoked, making it difficult to assess/
analyze performance issues of multiple containers at once.

This patch-set is aimed at addressing this limitation by introducing a
new PERF_RECORD_NAMESPACES event that records namespaces related info.
As containers are created with namespaces, the new data can be used to
in assessment/analysis of multiple containers.

The first patch introduces PERF_RECORD_NAMESPACES in kernel while the
second patch makes the corresponding changes in perf tool to read this
PERF_RECORD_NAMESPACES events. The third patch demonstrates analysis
of containers with this data by adding a cgroup identifier column in
perf report, which contains the cgroup namespace's device and inode
numbers. This is based on the assumption that each container is created
with it's own cgroup namespace. The third patch has scope for improvement
based on the conventions a container is attributed with, going forward.

Changes from v6:
* Updated changelog of patch 1
* Split patch 2 into smaller patches
* Updated record and script documenatation
* Dropped name field from ns_link_info struct

Changes from v5:
* Updated changelogs of patches 1 & 3
* Rebased the patches on perf/core in tip

---

Hari Bathini (8):
      perf: add PERF_RECORD_NAMESPACES to include namespaces related info
      perf tool: add PERF_RECORD_NAMESPACES to include namespaces related info
      perf tool: update about the new option to record namespace events
      perf tool: synthesize namespace events for current processes
      perf tool: add print support for namespace events
      perf tool: add script print support for namespace events
      perf tool: update about the new option to show namespace events
      perf tool: add cgroup identifier entry in perf report


 include/linux/perf_event.h               |    2 
 include/uapi/linux/perf_event.h          |   32 ++++++-
 kernel/events/core.c                     |  139 +++++++++++++++++++++++++++++
 kernel/fork.c                            |    2 
 kernel/nsproxy.c                         |    3 +
 tools/include/uapi/linux/perf_event.h    |   32 ++++++-
 tools/perf/Documentation/perf-record.txt |    3 +
 tools/perf/Documentation/perf-script.txt |    3 +
 tools/perf/builtin-annotate.c            |    1 
 tools/perf/builtin-diff.c                |    1 
 tools/perf/builtin-inject.c              |   14 +++
 tools/perf/builtin-kmem.c                |    1 
 tools/perf/builtin-kvm.c                 |    2 
 tools/perf/builtin-lock.c                |    1 
 tools/perf/builtin-mem.c                 |    1 
 tools/perf/builtin-record.c              |   33 ++++++-
 tools/perf/builtin-report.c              |    1 
 tools/perf/builtin-sched.c               |    1 
 tools/perf/builtin-script.c              |   41 ++++++++
 tools/perf/builtin-trace.c               |    3 -
 tools/perf/perf.h                        |    1 
 tools/perf/util/Build                    |    1 
 tools/perf/util/data-convert-bt.c        |    1 
 tools/perf/util/event.c                  |  146 +++++++++++++++++++++++++++++-
 tools/perf/util/event.h                  |   21 ++++
 tools/perf/util/evsel.c                  |    3 +
 tools/perf/util/hist.c                   |    7 +
 tools/perf/util/hist.h                   |    1 
 tools/perf/util/machine.c                |   34 +++++++
 tools/perf/util/machine.h                |    3 +
 tools/perf/util/namespaces.c             |   35 +++++++
 tools/perf/util/namespaces.h             |   26 +++++
 tools/perf/util/session.c                |    7 +
 tools/perf/util/sort.c                   |   41 ++++++++
 tools/perf/util/sort.h                   |    7 +
 tools/perf/util/thread.c                 |   44 +++++++++
 tools/perf/util/thread.h                 |    6 +
 tools/perf/util/tool.h                   |    2 
 38 files changed, 687 insertions(+), 15 deletions(-)
 create mode 100644 tools/perf/util/namespaces.c
 create mode 100644 tools/perf/util/namespaces.h

[toc] | [next] | [standalone]


#1585358 — [PATCH v7 8/8] perf tool: add cgroup identifier entry in perf report

FromHari Bathini <hbathini@linux.vnet.ibm.com>
Date2017-02-21 15:10 +0100
Subject[PATCH v7 8/8] perf tool: add cgroup identifier entry in perf report
Message-ID<tdjiF-3At-19@gated-at.bofh.it>
In reply to#1585357
This patch introduces a cgroup identifier entry field in perf report to
identify or distinguish data of different cgroups. It uses the device
number and inode number of cgroup namespace, included in perf data with
the new PERF_RECORD_NAMESPACES event, as cgroup identifier. With the
assumption that each container is created with it's own cgroup namespace,
this allows assessment/analysis of multiple containers at once.

Shown below is the output of perf report, sorted based on cgroup id, on
a system that was running three containers at the time of perf record
and clearly showing one of the containers' considerable use of kernel
memory in comparison with others:


	$ perf report -s cgroup_id,sample --stdio
	#
	# Total Lost Samples: 0
	#
	# Samples: 16K of event 'kmem:kmalloc'
	# Event count (approx.): 16043
	#
	# Overhead  cgroup id (dev/inode)       Samples
	# ........  .....................  ............
	#
	    96.33%  3/0xf00000d0                  15454
	     3.02%  3/0xeffffffb                    485
	     0.31%  3/0xf00000ce                     49
	     0.29%  3/0xf00000cf                     47
	     0.05%  0/0x0                             8

While this is a start, there is further scope of improving this. For
example, instead of cgroup namespace's device and inode numbers, dev
and inode numbers of some or all namespaces may be used to distinguish
which processes are running in a given container context. Also, scripts
to map device and inode info to containers sounds plausible for better
tracing of containers.

Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
---
 tools/perf/util/hist.c |    7 +++++++
 tools/perf/util/hist.h |    1 +
 tools/perf/util/sort.c |   41 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/sort.h |    7 +++++++
 4 files changed, 56 insertions(+)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 32c6a93..559ea27 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -3,6 +3,7 @@
 #include "hist.h"
 #include "map.h"
 #include "session.h"
+#include "namespaces.h"
 #include "sort.h"
 #include "evlist.h"
 #include "evsel.h"
@@ -169,6 +170,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
 		hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
 	}
 
+	hists__new_col_len(hists, HISTC_CGROUP_ID, 20);
 	hists__new_col_len(hists, HISTC_CPU, 3);
 	hists__new_col_len(hists, HISTC_SOCKET, 6);
 	hists__new_col_len(hists, HISTC_MEM_LOCKED, 6);
@@ -574,9 +576,14 @@ __hists__add_entry(struct hists *hists,
 		   bool sample_self,
 		   struct hist_entry_ops *ops)
 {
+	struct namespaces *ns = thread__namespaces(al->thread);
 	struct hist_entry entry = {
 		.thread	= al->thread,
 		.comm = thread__comm(al->thread),
+		.cgroup_id = {
+			.dev = ns ? ns->link_info[CGROUP_NS_INDEX].dev : 0,
+			.ino = ns ? ns->link_info[CGROUP_NS_INDEX].ino : 0,
+		},
 		.ms = {
 			.map	= al->map,
 			.sym	= al->sym,
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 28c216e..4c1da48 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -30,6 +30,7 @@ enum hist_column {
 	HISTC_DSO,
 	HISTC_THREAD,
 	HISTC_COMM,
+	HISTC_CGROUP_ID,
 	HISTC_PARENT,
 	HISTC_CPU,
 	HISTC_SOCKET,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index df622f4..9f5f404 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -536,6 +536,46 @@ struct sort_entry sort_cpu = {
 	.se_width_idx	= HISTC_CPU,
 };
 
+/* --sort cgroup_id */
+
+static int64_t _sort__cgroup_dev_cmp(u64 left_dev, u64 right_dev)
+{
+	return (int64_t)(right_dev - left_dev);
+}
+
+static int64_t _sort__cgroup_inode_cmp(u64 left_ino, u64 right_ino)
+{
+	return (int64_t)(right_ino - left_ino);
+}
+
+static int64_t
+sort__cgroup_id_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	int64_t ret;
+
+	ret = _sort__cgroup_dev_cmp(right->cgroup_id.dev, left->cgroup_id.dev);
+	if (ret != 0)
+		return ret;
+
+	return _sort__cgroup_inode_cmp(right->cgroup_id.ino,
+				       left->cgroup_id.ino);
+}
+
+static int hist_entry__cgroup_id_snprintf(struct hist_entry *he,
+					  char *bf, size_t size,
+					  unsigned int width __maybe_unused)
+{
+	return repsep_snprintf(bf, size, "%lu/0x%lx", he->cgroup_id.dev,
+			       he->cgroup_id.ino);
+}
+
+struct sort_entry sort_cgroup_id = {
+	.se_header      = "cgroup id (dev/inode)",
+	.se_cmp	        = sort__cgroup_id_cmp,
+	.se_snprintf    = hist_entry__cgroup_id_snprintf,
+	.se_width_idx	= HISTC_CGROUP_ID,
+};
+
 /* --sort socket */
 
 static int64_t
@@ -1418,6 +1458,7 @@ static struct sort_dimension common_sort_dimensions[] = {
 	DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
 	DIM(SORT_TRANSACTION, "transaction", sort_transaction),
 	DIM(SORT_TRACE, "trace", sort_trace),
+	DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id),
 };
 
 #undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 7aff317..68a5abb 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -54,6 +54,11 @@ struct he_stat {
 	u32			nr_events;
 };
 
+struct namespace_id {
+	u64			dev;
+	u64			ino;
+};
+
 struct hist_entry_diff {
 	bool	computed;
 	union {
@@ -91,6 +96,7 @@ struct hist_entry {
 	struct map_symbol	ms;
 	struct thread		*thread;
 	struct comm		*comm;
+	struct namespace_id	cgroup_id;
 	u64			ip;
 	u64			transaction;
 	s32			socket;
@@ -211,6 +217,7 @@ enum sort_type {
 	SORT_GLOBAL_WEIGHT,
 	SORT_TRANSACTION,
 	SORT_TRACE,
+	SORT_CGROUP_ID,
 
 	/* branch stack specific sort keys */
 	__SORT_BRANCH_STACK,

[toc] | [prev] | [next] | [standalone]


#1586308 — Re: [PATCH v7 8/8] perf tool: add cgroup identifier entry in perf report

FromJiri Olsa <jolsa@redhat.com>
Date2017-02-22 17:50 +0100
SubjectRe: [PATCH v7 8/8] perf tool: add cgroup identifier entry in perf report
Message-ID<tdIh4-4BG-13@gated-at.bofh.it>
In reply to#1585358
On Tue, Feb 21, 2017 at 07:33:13PM +0530, Hari Bathini wrote:
> This patch introduces a cgroup identifier entry field in perf report to
> identify or distinguish data of different cgroups. It uses the device
> number and inode number of cgroup namespace, included in perf data with
> the new PERF_RECORD_NAMESPACES event, as cgroup identifier. With the
> assumption that each container is created with it's own cgroup namespace,
> this allows assessment/analysis of multiple containers at once.
> 
> Shown below is the output of perf report, sorted based on cgroup id, on
> a system that was running three containers at the time of perf record
> and clearly showing one of the containers' considerable use of kernel
> memory in comparison with others:
> 
> 
> 	$ perf report -s cgroup_id,sample --stdio
> 	#
> 	# Total Lost Samples: 0
> 	#
> 	# Samples: 16K of event 'kmem:kmalloc'
> 	# Event count (approx.): 16043
> 	#
> 	# Overhead  cgroup id (dev/inode)       Samples
> 	# ........  .....................  ............
> 	#
> 	    96.33%  3/0xf00000d0                  15454
> 	     3.02%  3/0xeffffffb                    485
> 	     0.31%  3/0xf00000ce                     49
> 	     0.29%  3/0xf00000cf                     47
> 	     0.05%  0/0x0                             8
> 
> While this is a start, there is further scope of improving this. For
> example, instead of cgroup namespace's device and inode numbers, dev
> and inode numbers of some or all namespaces may be used to distinguish
> which processes are running in a given container context. Also, scripts
> to map device and inode info to containers sounds plausible for better
> tracing of containers.
> 
> Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
> ---
>  tools/perf/util/hist.c |    7 +++++++
>  tools/perf/util/hist.h |    1 +
>  tools/perf/util/sort.c |   41 +++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/sort.h |    7 +++++++
>  4 files changed, 56 insertions(+)

missing documentation update with new sorting field...

other than that the rest looks ok to me, for the patchset:

Acked-by: Jiri Olsa <jolsa@kernel.org>

thanks,
jirka

[toc] | [prev] | [next] | [standalone]


#1585360 — [PATCH v7 5/8] perf tool: add print support for namespace events

FromHari Bathini <hbathini@linux.vnet.ibm.com>
Date2017-02-21 15:10 +0100
Subject[PATCH v7 5/8] perf tool: add print support for namespace events
Message-ID<tdjiF-3At-21@gated-at.bofh.it>
In reply to#1585357
Add print support for events of type PERF_RECORD_NAMESPACES.

Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
---
 tools/perf/util/event.c   |   30 ++++++++++++++++++++++++++++++
 tools/perf/util/event.h   |    1 +
 tools/perf/util/machine.c |    3 +++
 3 files changed, 34 insertions(+)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index c8c112a..43b6a8f 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1104,6 +1104,33 @@ size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 	return fprintf(fp, "%s: %s:%d/%d\n", s, event->comm.comm, event->comm.pid, event->comm.tid);
 }
 
+size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp)
+{
+	size_t ret = 0;
+	struct perf_ns_link_info *ns_link_info;
+	u32 nr_namespaces, idx;
+
+	ns_link_info = event->namespaces.link_info;
+	nr_namespaces = event->namespaces.nr_namespaces;
+
+	ret += fprintf(fp, " %d/%d - nr_namespaces: %u\n\t[",
+		       event->namespaces.pid,
+		       event->namespaces.tid,
+		       nr_namespaces);
+
+	for (idx = 0; idx < nr_namespaces; idx++) {
+		if (idx && (idx % 4 == 0))
+			ret += fprintf(fp, "\n\t ");
+
+		ret  += fprintf(fp, "%u/%s: %lu/0x%lx%s", idx,
+				perf_ns__name(idx), (u64)ns_link_info[idx].dev,
+				(u64)ns_link_info[idx].ino,
+				((idx + 1) != nr_namespaces) ? ", " : "]\n\n");
+	}
+
+	return ret;
+}
+
 int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
 			     union perf_event *event,
 			     struct perf_sample *sample,
@@ -1300,6 +1327,9 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)
 	case PERF_RECORD_MMAP:
 		ret += perf_event__fprintf_mmap(event, fp);
 		break;
+	case PERF_RECORD_NAMESPACES:
+		ret += perf_event__fprintf_namespaces(event, fp);
+		break;
 	case PERF_RECORD_MMAP2:
 		ret += perf_event__fprintf_mmap2(event, fp);
 		break;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index c73ad47..8eb470b 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -673,6 +673,7 @@ size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp);
+size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf(union perf_event *event, FILE *fp);
 
 u64 kallsyms__get_function_start(const char *kallsyms_filename,
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 060fabb..5f46ad0 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -519,6 +519,9 @@ int machine__process_namespaces_event(struct machine *machine __maybe_unused,
 		  "\nWARNING: perf tool seems to support more namespaces than"
 		  " the kernel.\nTry updating the kernel..\n\n");
 
+	if (dump_trace)
+		perf_event__fprintf_namespaces(event, stdout);
+
 	if (thread == NULL ||
 	    thread__set_namespaces(thread, sample->time, &event->namespaces)) {
 		dump_printf("problem processing PERF_RECORD_NAMESPACES, skipping event.\n");

[toc] | [prev] | [next] | [standalone]


#1585362 — [PATCH v7 3/8] perf tool: update about the new option to record namespace events

FromHari Bathini <hbathini@linux.vnet.ibm.com>
Date2017-02-21 15:10 +0100
Subject[PATCH v7 3/8] perf tool: update about the new option to record namespace events
Message-ID<tdjiG-3At-31@gated-at.bofh.it>
In reply to#1585357
Now that we have a new option to record namespace events, update
the perf-record documentation accordingly.

Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
---
 tools/perf/Documentation/perf-record.txt |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 27256bc..9c85a65 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -347,6 +347,9 @@ Enable weightened sampling. An additional weight is recorded per sample and can
 displayed with the weight and local_weight sort keys.  This currently works for TSX
 abort events and some memory events in precise mode on modern Intel CPUs.
 
+--namespaces::
+Record events of type PERF_RECORD_NAMESPACES.
+
 --transaction::
 Record transaction flags for transaction related events.
 

[toc] | [prev] | [next] | [standalone]


#1585363 — [PATCH v7 6/8] perf tool: add script print support for namespace events

FromHari Bathini <hbathini@linux.vnet.ibm.com>
Date2017-02-21 15:10 +0100
Subject[PATCH v7 6/8] perf tool: add script print support for namespace events
Message-ID<tdjiG-3At-33@gated-at.bofh.it>
In reply to#1585357
Add script print support for events of type PERF_RECORD_NAMESPACES.

Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
---
 tools/perf/builtin-script.c |   40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index f1ce806..66d62c9 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -830,6 +830,7 @@ struct perf_script {
 	bool			show_task_events;
 	bool			show_mmap_events;
 	bool			show_switch_events;
+	bool			show_namespace_events;
 	bool			allocated;
 	struct cpu_map		*cpus;
 	struct thread_map	*threads;
@@ -1118,6 +1119,41 @@ static int process_comm_event(struct perf_tool *tool,
 	return ret;
 }
 
+static int process_namespaces_event(struct perf_tool *tool,
+				    union perf_event *event,
+				    struct perf_sample *sample,
+				    struct machine *machine)
+{
+	struct thread *thread;
+	struct perf_script *script = container_of(tool, struct perf_script, tool);
+	struct perf_session *session = script->session;
+	struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+	int ret = -1;
+
+	thread = machine__findnew_thread(machine, event->namespaces.pid,
+					 event->namespaces.tid);
+	if (thread == NULL) {
+		pr_debug("problem processing NAMESPACES event, skipping it.\n");
+		return -1;
+	}
+
+	if (perf_event__process_namespaces(tool, event, sample, machine) < 0)
+		goto out;
+
+	if (!evsel->attr.sample_id_all) {
+		sample->cpu = 0;
+		sample->time = 0;
+		sample->tid = event->namespaces.tid;
+		sample->pid = event->namespaces.pid;
+	}
+	print_sample_start(sample, thread, evsel);
+	perf_event__fprintf(event, stdout);
+	ret = 0;
+out:
+	thread__put(thread);
+	return ret;
+}
+
 static int process_fork_event(struct perf_tool *tool,
 			      union perf_event *event,
 			      struct perf_sample *sample,
@@ -1293,6 +1329,8 @@ static int __cmd_script(struct perf_script *script)
 	}
 	if (script->show_switch_events)
 		script->tool.context_switch = process_switch_event;
+	if (script->show_namespace_events)
+		script->tool.namespaces = process_namespaces_event;
 
 	ret = perf_session__process_events(script->session);
 
@@ -2181,6 +2219,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 		    "Show the mmap events"),
 	OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
 		    "Show context switch events (if recorded)"),
+	OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events,
+		    "Show namespace events (if recorded)"),
 	OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
 	OPT_BOOLEAN(0, "ns", &nanosecs,
 		    "Use 9 decimal places when displaying time"),

[toc] | [prev] | [next] | [standalone]


#1585364 — [PATCH v7 4/8] perf tool: synthesize namespace events for current processes

FromHari Bathini <hbathini@linux.vnet.ibm.com>
Date2017-02-21 15:10 +0100
Subject[PATCH v7 4/8] perf tool: synthesize namespace events for current processes
Message-ID<tdjiG-3At-35@gated-at.bofh.it>
In reply to#1585357
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;
+
+	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,

[toc] | [prev] | [next] | [standalone]


#1586067 — Re: [PATCH v7 0/8] perf: add support for analyzing events for containers

FromJiri Olsa <jolsa@redhat.com>
Date2017-02-22 12:20 +0100
SubjectRe: [PATCH v7 0/8] perf: add support for analyzing events for containers
Message-ID<tdD7I-R8-5@gated-at.bofh.it>
In reply to#1585357
On Tue, Feb 21, 2017 at 07:31:11PM +0530, Hari Bathini wrote:
> Currently, there is no trivial mechanism to analyze events based on
> containers. perf -G can be used, but it will not filter events for the                  
> containers created after perf is invoked, making it difficult to assess/
> analyze performance issues of multiple containers at once.
> 
> This patch-set is aimed at addressing this limitation by introducing a
> new PERF_RECORD_NAMESPACES event that records namespaces related info.
> As containers are created with namespaces, the new data can be used to
> in assessment/analysis of multiple containers.
> 
> The first patch introduces PERF_RECORD_NAMESPACES in kernel while the
> second patch makes the corresponding changes in perf tool to read this
> PERF_RECORD_NAMESPACES events. The third patch demonstrates analysis
> of containers with this data by adding a cgroup identifier column in
> perf report, which contains the cgroup namespace's device and inode
> numbers. This is based on the assumption that each container is created
> with it's own cgroup namespace. The third patch has scope for improvement
> based on the conventions a container is attributed with, going forward.
> 
> Changes from v6:
> * Updated changelog of patch 1
> * Split patch 2 into smaller patches
> * Updated record and script documenatation
> * Dropped name field from ns_link_info struct

what's this version based on? I can't cleanly apply it neither
on tip's perf/core or master or Arnaldo's perf/core

thanks,
jirka

[toc] | [prev] | [next] | [standalone]


#1586124 — Re: [PATCH v7 0/8] perf: add support for analyzing events for containers

FromHari Bathini <hbathini@linux.vnet.ibm.com>
Date2017-02-22 13:50 +0100
SubjectRe: [PATCH v7 0/8] perf: add support for analyzing events for containers
Message-ID<tdEwO-1Jr-17@gated-at.bofh.it>
In reply to#1586067
Hi Jirka,


On Wednesday 22 February 2017 04:41 PM, Jiri Olsa wrote:
> On Tue, Feb 21, 2017 at 07:31:11PM +0530, Hari Bathini wrote:
>> Currently, there is no trivial mechanism to analyze events based on
>> containers. perf -G can be used, but it will not filter events for the
>> containers created after perf is invoked, making it difficult to assess/
>> analyze performance issues of multiple containers at once.
>>
>> This patch-set is aimed at addressing this limitation by introducing a
>> new PERF_RECORD_NAMESPACES event that records namespaces related info.
>> As containers are created with namespaces, the new data can be used to
>> in assessment/analysis of multiple containers.
>>
>> The first patch introduces PERF_RECORD_NAMESPACES in kernel while the
>> second patch makes the corresponding changes in perf tool to read this
>> PERF_RECORD_NAMESPACES events. The third patch demonstrates analysis
>> of containers with this data by adding a cgroup identifier column in
>> perf report, which contains the cgroup namespace's device and inode
>> numbers. This is based on the assumption that each container is created
>> with it's own cgroup namespace. The third patch has scope for improvement
>> based on the conventions a container is attributed with, going forward.
>>
>> Changes from v6:
>> * Updated changelog of patch 1
>> * Split patch 2 into smaller patches
>> * Updated record and script documenatation
>> * Dropped name field from ns_link_info struct
> what's this version based on? I can't cleanly apply it neither
> on tip's perf/core or master or Arnaldo's perf/core

That's odd. I based my patches against tip's perf/core
To be precise, the patches apply cleanly on top of commit
0c8967c9df230d2c4dde6649f410b62e01806c22.

Thanks
Hari

[toc] | [prev] | [next] | [standalone]


#1586164 — Re: [PATCH v7 0/8] perf: add support for analyzing events for containers

FromJiri Olsa <jolsa@redhat.com>
Date2017-02-22 15:00 +0100
SubjectRe: [PATCH v7 0/8] perf: add support for analyzing events for containers
Message-ID<tdFCy-2v3-9@gated-at.bofh.it>
In reply to#1586124
On Wed, Feb 22, 2017 at 06:10:28PM +0530, Hari Bathini wrote:
> Hi Jirka,
> 
> 
> On Wednesday 22 February 2017 04:41 PM, Jiri Olsa wrote:
> > On Tue, Feb 21, 2017 at 07:31:11PM +0530, Hari Bathini wrote:
> > > Currently, there is no trivial mechanism to analyze events based on
> > > containers. perf -G can be used, but it will not filter events for the
> > > containers created after perf is invoked, making it difficult to assess/
> > > analyze performance issues of multiple containers at once.
> > > 
> > > This patch-set is aimed at addressing this limitation by introducing a
> > > new PERF_RECORD_NAMESPACES event that records namespaces related info.
> > > As containers are created with namespaces, the new data can be used to
> > > in assessment/analysis of multiple containers.
> > > 
> > > The first patch introduces PERF_RECORD_NAMESPACES in kernel while the
> > > second patch makes the corresponding changes in perf tool to read this
> > > PERF_RECORD_NAMESPACES events. The third patch demonstrates analysis
> > > of containers with this data by adding a cgroup identifier column in
> > > perf report, which contains the cgroup namespace's device and inode
> > > numbers. This is based on the assumption that each container is created
> > > with it's own cgroup namespace. The third patch has scope for improvement
> > > based on the conventions a container is attributed with, going forward.
> > > 
> > > Changes from v6:
> > > * Updated changelog of patch 1
> > > * Split patch 2 into smaller patches
> > > * Updated record and script documenatation
> > > * Dropped name field from ns_link_info struct
> > what's this version based on? I can't cleanly apply it neither
> > on tip's perf/core or master or Arnaldo's perf/core
> 
> That's odd. I based my patches against tip's perf/core
> To be precise, the patches apply cleanly on top of commit
> 0c8967c9df230d2c4dde6649f410b62e01806c22.

got it now, thanks

jirka

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web