if use -G with one cgroup and -e with multiple events, only the first event has correct cgroup setting, all events from the second will track system-wide events.
if user want track multiple events for a specific cgroup, user must give parameters like follow: $ perf stat -e e1 -e e2 -e e3 -G test,test,test this patch simplify this case, just type one cgroup, like following: $ perf stat -e e1 -e e2 -e e3 -G test reproduce: $ mkdir -p /sys/fs/cgroup/perf_event/test $ perf stat -e cycles -e cache-misses -a -I 1000 -G test before: 1.001007226 <not counted> cycles test 1.001007226 7,506 cache-misses after: 1.000834097 <not counted> cycles test 1.000834097 <not counted> cache-misses test Signed-off-by: weiping zhang <zhangweip...@didichuxing.com> --- tools/perf/util/cgroup.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index d9ffc1e..38aaeb2 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -154,9 +154,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"); @@ -185,5 +187,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; } -- 2.9.4