Skip to content

Commit

Permalink
perf tools: Basic support for CGROUP event
Browse files Browse the repository at this point in the history
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: kernel test robot <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
Cc: Adrian Hunter <[email protected]>
[ fix perf test failure on sampling parsing ]
Cc: Alexander Shishkin <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lore.kernel.org/lkml/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
namhyung authored and acmel committed Apr 3, 2020
1 parent 49f550e commit ba78c1c
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 1 deletion.
7 changes: 7 additions & 0 deletions tools/lib/perf/include/perf/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ struct perf_record_bpf_event {
__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_event_header header;
__u64 array[];
Expand Down Expand Up @@ -352,6 +358,7 @@ union perf_event {
struct perf_record_mmap2 mmap2;
struct perf_record_comm comm;
struct perf_record_namespaces namespaces;
struct perf_record_cgroup cgroup;
struct perf_record_fork fork;
struct perf_record_lost lost;
struct perf_record_lost_samples lost_samples;
Expand Down
1 change: 1 addition & 0 deletions tools/perf/builtin-diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ static struct perf_diff pdiff = {
.fork = perf_event__process_fork,
.lost = perf_event__process_lost,
.namespaces = perf_event__process_namespaces,
.cgroup = perf_event__process_cgroup,
.ordered_events = true,
.ordering_requires_timestamps = true,
},
Expand Down
1 change: 1 addition & 0 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,7 @@ int cmd_report(int argc, const char **argv)
.mmap2 = perf_event__process_mmap2,
.comm = perf_event__process_comm,
.namespaces = perf_event__process_namespaces,
.cgroup = perf_event__process_cgroup,
.exit = perf_event__process_exit,
.fork = perf_event__process_fork,
.lost = perf_event__process_lost,
Expand Down
6 changes: 5 additions & 1 deletion tools/perf/tests/sample-parsing.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ static bool samples_same(const struct perf_sample *s1,
if (type & PERF_SAMPLE_PHYS_ADDR)
COMP(phys_addr);

if (type & PERF_SAMPLE_CGROUP)
COMP(cgroup);

if (type & PERF_SAMPLE_AUX) {
COMP(aux_sample.size);
if (memcmp(s1->aux_sample.data, s2->aux_sample.data,
Expand Down Expand Up @@ -230,6 +233,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
.regs = regs,
},
.phys_addr = 113,
.cgroup = 114,
.aux_sample = {
.size = sizeof(aux_data),
.data = (void *)aux_data,
Expand Down Expand Up @@ -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
* 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");
return -1;
}
Expand Down
18 changes: 18 additions & 0 deletions tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static const char *perf_event__names[] = {
[PERF_RECORD_NAMESPACES] = "NAMESPACES",
[PERF_RECORD_KSYMBOL] = "KSYMBOL",
[PERF_RECORD_BPF_EVENT] = "BPF_EVENT",
[PERF_RECORD_CGROUP] = "CGROUP",
[PERF_RECORD_HEADER_ATTR] = "ATTR",
[PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE",
[PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA",
Expand Down Expand Up @@ -180,6 +181,12 @@ size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp)
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,
union perf_event *event,
struct perf_sample *sample,
Expand All @@ -196,6 +203,14 @@ int perf_event__process_namespaces(struct perf_tool *tool __maybe_unused,
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,
union perf_event *event,
struct perf_sample *sample,
Expand Down Expand Up @@ -417,6 +432,9 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)
case PERF_RECORD_NAMESPACES:
ret += perf_event__fprintf_namespaces(event, fp);
break;
case PERF_RECORD_CGROUP:
ret += perf_event__fprintf_cgroup(event, fp);
break;
case PERF_RECORD_MMAP2:
ret += perf_event__fprintf_mmap2(event, fp);
break;
Expand Down
6 changes: 6 additions & 0 deletions tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ struct perf_sample {
u32 raw_size;
u64 data_src;
u64 phys_addr;
u64 cgroup;
u32 flags;
u16 insn_len;
u8 cpumode;
Expand Down Expand Up @@ -322,6 +323,10 @@ int perf_event__process_namespaces(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct machine *machine);
int perf_event__process_cgroup(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct machine *machine);
int perf_event__process_mmap(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
Expand Down Expand Up @@ -377,6 +382,7 @@ 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_cgroup(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp);
size_t perf_event__fprintf(union perf_event *event, FILE *fp);
Expand Down
6 changes: 6 additions & 0 deletions tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2267,6 +2267,12 @@ int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event,
array++;
}

data->cgroup = 0;
if (type & PERF_SAMPLE_CGROUP) {
data->cgroup = *array;
array++;
}

if (type & PERF_SAMPLE_AUX) {
OVERFLOW_CHECK_u64(array);
sz = *array++;
Expand Down
12 changes: 12 additions & 0 deletions tools/perf/util/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,16 @@ int machine__process_namespaces_event(struct machine *machine __maybe_unused,
return err;
}

int machine__process_cgroup_event(struct machine *machine __maybe_unused,
union perf_event *event,
struct perf_sample *sample __maybe_unused)
{
if (dump_trace)
perf_event__fprintf_cgroup(event, stdout);

return 0;
}

int machine__process_lost_event(struct machine *machine __maybe_unused,
union perf_event *event, struct perf_sample *sample __maybe_unused)
{
Expand Down Expand Up @@ -1878,6 +1888,8 @@ int machine__process_event(struct machine *machine, union perf_event *event,
ret = machine__process_mmap_event(machine, event, sample); break;
case PERF_RECORD_NAMESPACES:
ret = machine__process_namespaces_event(machine, event, sample); break;
case PERF_RECORD_CGROUP:
ret = machine__process_cgroup_event(machine, event, sample); break;
case PERF_RECORD_MMAP2:
ret = machine__process_mmap2_event(machine, event, sample); break;
case PERF_RECORD_FORK:
Expand Down
3 changes: 3 additions & 0 deletions tools/perf/util/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ int machine__process_switch_event(struct machine *machine,
int machine__process_namespaces_event(struct machine *machine,
union perf_event *event,
struct perf_sample *sample);
int machine__process_cgroup_event(struct machine *machine,
union perf_event *event,
struct perf_sample *sample);
int machine__process_mmap_event(struct machine *machine, union perf_event *event,
struct perf_sample *sample);
int machine__process_mmap2_event(struct machine *machine, union perf_event *event,
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/util/perf_event_attr_fprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static void __p_sample_type(char *buf, size_t size, u64 value)
bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER),
bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC),
bit_name(WEIGHT), bit_name(PHYS_ADDR), bit_name(AUX),
bit_name(CGROUP),
{ .name = NULL, }
};
#undef bit_name
Expand Down Expand Up @@ -132,6 +133,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
PRINT_ATTRf(ksymbol, p_unsigned);
PRINT_ATTRf(bpf_event, p_unsigned);
PRINT_ATTRf(aux_output, p_unsigned);
PRINT_ATTRf(cgroup, p_unsigned);

PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned);
PRINT_ATTRf(bp_type, p_unsigned);
Expand Down
4 changes: 4 additions & 0 deletions tools/perf/util/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
tool->comm = process_event_stub;
if (tool->namespaces == NULL)
tool->namespaces = process_event_stub;
if (tool->cgroup == NULL)
tool->cgroup = process_event_stub;
if (tool->fork == NULL)
tool->fork = process_event_stub;
if (tool->exit == NULL)
Expand Down Expand Up @@ -1436,6 +1438,8 @@ static int machines__deliver_event(struct machines *machines,
return tool->comm(tool, event, sample, machine);
case PERF_RECORD_NAMESPACES:
return tool->namespaces(tool, event, sample, machine);
case PERF_RECORD_CGROUP:
return tool->cgroup(tool, event, sample, machine);
case PERF_RECORD_FORK:
return tool->fork(tool, event, sample, machine);
case PERF_RECORD_EXIT:
Expand Down
8 changes: 8 additions & 0 deletions tools/perf/util/synthetic-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,9 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
if (type & PERF_SAMPLE_PHYS_ADDR)
result += sizeof(u64);

if (type & PERF_SAMPLE_CGROUP)
result += sizeof(u64);

if (type & PERF_SAMPLE_AUX) {
result += sizeof(u64);
result += sample->aux_sample.size;
Expand Down Expand Up @@ -1404,6 +1407,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
array++;
}

if (type & PERF_SAMPLE_CGROUP) {
*array = sample->cgroup;
array++;
}

if (type & PERF_SAMPLE_AUX) {
sz = sample->aux_sample.size;
*array++ = sz;
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/tool.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct perf_tool {
mmap2,
comm,
namespaces,
cgroup,
fork,
exit,
lost,
Expand Down

0 comments on commit ba78c1c

Please sign in to comment.