Commit ba78c1c5 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

perf tools: Basic support for CGROUP event



Implement basic functionality to support cgroup tracking.  Each cgroup
can be identified by inode number which can be read from userspace too.
The actual cgroup processing will come in the later patch.

Reported-by: default avatarkernel test robot <rong.a.chen@intel.com>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
[ fix perf test failure on sampling parsing ]
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20200325124536.2800725-4-namhyung@kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 49f550ea
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -105,6 +105,12 @@ struct perf_record_bpf_event {
	__u8			 tag[BPF_TAG_SIZE];  // prog tag
	__u8			 tag[BPF_TAG_SIZE];  // prog tag
};
};


struct perf_record_cgroup {
	struct perf_event_header header;
	__u64			 id;
	char			 path[PATH_MAX];
};

struct perf_record_sample {
struct perf_record_sample {
	struct perf_event_header header;
	struct perf_event_header header;
	__u64			 array[];
	__u64			 array[];
@@ -352,6 +358,7 @@ union perf_event {
	struct perf_record_mmap2		mmap2;
	struct perf_record_mmap2		mmap2;
	struct perf_record_comm			comm;
	struct perf_record_comm			comm;
	struct perf_record_namespaces		namespaces;
	struct perf_record_namespaces		namespaces;
	struct perf_record_cgroup		cgroup;
	struct perf_record_fork			fork;
	struct perf_record_fork			fork;
	struct perf_record_lost			lost;
	struct perf_record_lost			lost;
	struct perf_record_lost_samples		lost_samples;
	struct perf_record_lost_samples		lost_samples;
+1 −0
Original line number Original line Diff line number Diff line
@@ -455,6 +455,7 @@ static struct perf_diff pdiff = {
		.fork	= perf_event__process_fork,
		.fork	= perf_event__process_fork,
		.lost	= perf_event__process_lost,
		.lost	= perf_event__process_lost,
		.namespaces = perf_event__process_namespaces,
		.namespaces = perf_event__process_namespaces,
		.cgroup = perf_event__process_cgroup,
		.ordered_events = true,
		.ordered_events = true,
		.ordering_requires_timestamps = true,
		.ordering_requires_timestamps = true,
	},
	},
+1 −0
Original line number Original line Diff line number Diff line
@@ -1105,6 +1105,7 @@ int cmd_report(int argc, const char **argv)
			.mmap2		 = perf_event__process_mmap2,
			.mmap2		 = perf_event__process_mmap2,
			.comm		 = perf_event__process_comm,
			.comm		 = perf_event__process_comm,
			.namespaces	 = perf_event__process_namespaces,
			.namespaces	 = perf_event__process_namespaces,
			.cgroup		 = perf_event__process_cgroup,
			.exit		 = perf_event__process_exit,
			.exit		 = perf_event__process_exit,
			.fork		 = perf_event__process_fork,
			.fork		 = perf_event__process_fork,
			.lost		 = perf_event__process_lost,
			.lost		 = perf_event__process_lost,
+5 −1
Original line number Original line Diff line number Diff line
@@ -151,6 +151,9 @@ static bool samples_same(const struct perf_sample *s1,
	if (type & PERF_SAMPLE_PHYS_ADDR)
	if (type & PERF_SAMPLE_PHYS_ADDR)
		COMP(phys_addr);
		COMP(phys_addr);


	if (type & PERF_SAMPLE_CGROUP)
		COMP(cgroup);

	if (type & PERF_SAMPLE_AUX) {
	if (type & PERF_SAMPLE_AUX) {
		COMP(aux_sample.size);
		COMP(aux_sample.size);
		if (memcmp(s1->aux_sample.data, s2->aux_sample.data,
		if (memcmp(s1->aux_sample.data, s2->aux_sample.data,
@@ -230,6 +233,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
			.regs	= regs,
			.regs	= regs,
		},
		},
		.phys_addr	= 113,
		.phys_addr	= 113,
		.cgroup		= 114,
		.aux_sample	= {
		.aux_sample	= {
			.size	= sizeof(aux_data),
			.size	= sizeof(aux_data),
			.data	= (void *)aux_data,
			.data	= (void *)aux_data,
@@ -336,7 +340,7 @@ int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_u
	 * were added.  Please actually update the test rather than just change
	 * were added.  Please actually update the test rather than just change
	 * the condition below.
	 * the condition below.
	 */
	 */
	if (PERF_SAMPLE_MAX > PERF_SAMPLE_AUX << 1) {
	if (PERF_SAMPLE_MAX > PERF_SAMPLE_CGROUP << 1) {
		pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
		pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
		return -1;
		return -1;
	}
	}
+18 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,7 @@ static const char *perf_event__names[] = {
	[PERF_RECORD_NAMESPACES]		= "NAMESPACES",
	[PERF_RECORD_NAMESPACES]		= "NAMESPACES",
	[PERF_RECORD_KSYMBOL]			= "KSYMBOL",
	[PERF_RECORD_KSYMBOL]			= "KSYMBOL",
	[PERF_RECORD_BPF_EVENT]			= "BPF_EVENT",
	[PERF_RECORD_BPF_EVENT]			= "BPF_EVENT",
	[PERF_RECORD_CGROUP]			= "CGROUP",
	[PERF_RECORD_HEADER_ATTR]		= "ATTR",
	[PERF_RECORD_HEADER_ATTR]		= "ATTR",
	[PERF_RECORD_HEADER_EVENT_TYPE]		= "EVENT_TYPE",
	[PERF_RECORD_HEADER_EVENT_TYPE]		= "EVENT_TYPE",
	[PERF_RECORD_HEADER_TRACING_DATA]	= "TRACING_DATA",
	[PERF_RECORD_HEADER_TRACING_DATA]	= "TRACING_DATA",
@@ -180,6 +181,12 @@ size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp)
	return ret;
	return ret;
}
}


size_t perf_event__fprintf_cgroup(union perf_event *event, FILE *fp)
{
	return fprintf(fp, " cgroup: %" PRI_lu64 " %s\n",
		       event->cgroup.id, event->cgroup.path);
}

int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
			     union perf_event *event,
			     struct perf_sample *sample,
			     struct perf_sample *sample,
@@ -196,6 +203,14 @@ int perf_event__process_namespaces(struct perf_tool *tool __maybe_unused,
	return machine__process_namespaces_event(machine, event, sample);
	return machine__process_namespaces_event(machine, event, sample);
}
}


int perf_event__process_cgroup(struct perf_tool *tool __maybe_unused,
			       union perf_event *event,
			       struct perf_sample *sample,
			       struct machine *machine)
{
	return machine__process_cgroup_event(machine, event, sample);
}

int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
			     union perf_event *event,
			     struct perf_sample *sample,
			     struct perf_sample *sample,
@@ -417,6 +432,9 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)
	case PERF_RECORD_NAMESPACES:
	case PERF_RECORD_NAMESPACES:
		ret += perf_event__fprintf_namespaces(event, fp);
		ret += perf_event__fprintf_namespaces(event, fp);
		break;
		break;
	case PERF_RECORD_CGROUP:
		ret += perf_event__fprintf_cgroup(event, fp);
		break;
	case PERF_RECORD_MMAP2:
	case PERF_RECORD_MMAP2:
		ret += perf_event__fprintf_mmap2(event, fp);
		ret += perf_event__fprintf_mmap2(event, fp);
		break;
		break;
Loading