From 25f72f9ed88d5be86c92432fc779e2725e3506cd Mon Sep 17 00:00:00 2001 From: weiping zhang Date: Mon, 29 Jan 2018 23:48:09 +0800 Subject: perf cgroup: Simplify arguments when tracking multiple events When using -G with one cgroup and -e with multiple events, only the first event gets the correct cgroup setting, all events from the second onwards will track system-wide events. If the user wants to track multiple events for a specific cgroup, the user must give parameters like the following: $ perf stat -e e1 -e e2 -e e3 -G test,test,test This patch simplify this case, just type one cgroup: $ perf stat -e e1 -e e2 -e e3 -G test $ mkdir -p /sys/fs/cgroup/perf_event/empty_cgroup $ perf stat -e cycles -e cache-misses -a -I 1000 -G empty_cgroup Before: 1.001007226 cycles empty_cgroup 1.001007226 7,506 cache-misses After: 1.000834097 cycles empty_cgroup 1.000834097 cache-misses empty_cgroup Signed-off-by: weiping zhang Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20180129154805.GA6284@localhost.didichuxing.com [ Improved the doc text a bit, providing an example for cgroup + system wide counting ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cgroup.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'tools/perf/util/cgroup.c') diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 984f69144f87..5dd9b5ea314d 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -157,9 +157,11 @@ int parse_cgroups(const struct option *opt __maybe_unused, const char *str, int unset __maybe_unused) { struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; + struct perf_evsel *counter; + struct cgroup_sel *cgrp = NULL; const char *p, *e, *eos = str + strlen(str); char *s; - int ret; + int ret, i; if (list_empty(&evlist->entries)) { fprintf(stderr, "must define events before cgroups\n"); @@ -188,5 +190,18 @@ int parse_cgroups(const struct option *opt __maybe_unused, const char *str, break; str = p+1; } + /* for the case one cgroup combine to multiple events */ + i = 0; + if (nr_cgroups == 1) { + evlist__for_each_entry(evlist, counter) { + if (i == 0) + cgrp = counter->cgrp; + else { + counter->cgrp = cgrp; + refcount_inc(&cgrp->refcnt); + } + i++; + } + } return 0; } -- cgit v1.2.3