diff options
author | Ingo Molnar <mingo@kernel.org> | 2018-03-09 08:27:55 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-03-09 08:27:55 +0100 |
commit | fbf8a1e12c3ba3afdf0804bc80f5f13dfec1cffe (patch) | |
tree | 6b0dd23c7646cd4ec13b0636cdda11188d6845a3 /tools/perf/util/cgroup.c | |
parent | 1af22eba248efe2de25658041a80a3d40fb3e92e (diff) | |
parent | 2427b432e63b4b911100f717c48289195b7a7d62 (diff) |
Merge tag 'perf-core-for-mingo-4.17-20180308' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
- Support to display the IPC/Cycle in 'annotate' TUI, for systems
where this info can be obtained, like Intel's >= Skylake (Jin Yao)
- Support wildcards on PMU name in dynamic PMU events (Agustin Vega-Frias)
- Display pmu name when printing unmerged events in stat (Agustin Vega-Frias)
- Auto-merge PMU events created by prefix or glob match (Agustin Vega-Frias)
- Fix s390 'call' operations target function annotation (Thomas Richter)
- Handle s390 PC relative load and store instruction in the augmented
'annotate', code, used so far in the TUI modes of 'perf report' and
'perf annotate' (Thomas Richter)
- Provide libtraceevent with a kernel symbol resolver, so that
symbols in tracepoint fields can be resolved when showing them in
tools such as 'perf report' (Wang YanQing)
- Refactor the cgroups code to look more like other code in tools/perf,
using cgroup__{put,get} for refcount operations instead of its
open-coded equivalent, breaking larger functions, etc (Arnaldo Carvalho de Melo)
- Implement support for the -G/--cgroup target in 'perf trace', allowing
strace like tracing (plus other events, backtraces, etc) for cgroups
(Arnaldo Carvalho de Melo)
- Update thread shortname in 'perf sched map' when the thread's COMM
changes (Changbin Du)
- refcount 'struct mem_info', for better sharing it over several
users, avoid duplicating structs and fixing crashes related to
use after free (Jiri Olsa)
- Display perf.data version, offsets in 'perf report --header' (Jiri Olsa)
- Record the machine's memory topology information in a perf.data
feature section, to be used by tools such as 'perf c2c' (Jiri Olsa)
- Fix output of forced groups in the header for 'perf report' --stdio
and --tui (Jiri Olsa)
- Better support llvm, clang, cxx make tests in the build process (Jiri Olsa)
- Streamline the 'struct perf_mmap' methods, storing some info in the
struct instead of passing it via various methods, shortening its
signatures (Kan Liang)
- Update the quipper perf.data parser library site information (Stephane Eranian)
- Correct perf's man pages title markers for asciidoctor (Takashi Iwai)
- Intel PT fixes and refactorings paving the way for implementing
support for AUX area sampling (Adrian Hunter)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/cgroup.c')
-rw-r--r-- | tools/perf/util/cgroup.c | 111 |
1 files changed, 79 insertions, 32 deletions
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 5dd9b5ea314d..78408f5c4bad 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -71,7 +71,7 @@ cgroupfs_find_mountpoint(char *buf, size_t maxlen) return -1; } -static int open_cgroup(char *name) +static int open_cgroup(const char *name) { char path[PATH_MAX + 1]; char mnt[PATH_MAX + 1]; @@ -90,41 +90,64 @@ static int open_cgroup(char *name) return fd; } -static int add_cgroup(struct perf_evlist *evlist, char *str) +static struct cgroup *evlist__find_cgroup(struct perf_evlist *evlist, const char *str) { struct perf_evsel *counter; - struct cgroup_sel *cgrp = NULL; - int n; + struct cgroup *cgrp = NULL; /* * check if cgrp is already defined, if so we reuse it */ evlist__for_each_entry(evlist, counter) { - cgrp = counter->cgrp; - if (!cgrp) + if (!counter->cgrp) continue; - if (!strcmp(cgrp->name, str)) { - refcount_inc(&cgrp->refcnt); + if (!strcmp(counter->cgrp->name, str)) { + cgrp = cgroup__get(counter->cgrp); break; } - - cgrp = NULL; } - if (!cgrp) { - cgrp = zalloc(sizeof(*cgrp)); - if (!cgrp) - return -1; + return cgrp; +} + +static struct cgroup *cgroup__new(const char *name) +{ + struct cgroup *cgroup = zalloc(sizeof(*cgroup)); - cgrp->name = str; - refcount_set(&cgrp->refcnt, 1); + if (cgroup != NULL) { + refcount_set(&cgroup->refcnt, 1); - cgrp->fd = open_cgroup(str); - if (cgrp->fd == -1) { - free(cgrp); - return -1; - } + cgroup->name = strdup(name); + if (!cgroup->name) + goto out_err; + cgroup->fd = open_cgroup(name); + if (cgroup->fd == -1) + goto out_free_name; } + return cgroup; + +out_free_name: + free(cgroup->name); +out_err: + free(cgroup); + return NULL; +} + +struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, const char *name) +{ + struct cgroup *cgroup = evlist__find_cgroup(evlist, name); + + return cgroup ?: cgroup__new(name); +} + +static int add_cgroup(struct perf_evlist *evlist, const char *str) +{ + struct perf_evsel *counter; + struct cgroup *cgrp = evlist__findnew_cgroup(evlist, str); + int n; + + if (!cgrp) + return -1; /* * find corresponding event * if add cgroup N, then need to find event N @@ -135,30 +158,55 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) goto found; n++; } - if (refcount_dec_and_test(&cgrp->refcnt)) - free(cgrp); + cgroup__put(cgrp); return -1; found: counter->cgrp = cgrp; return 0; } -void close_cgroup(struct cgroup_sel *cgrp) +static void cgroup__delete(struct cgroup *cgroup) +{ + close(cgroup->fd); + zfree(&cgroup->name); + free(cgroup); +} + +void cgroup__put(struct cgroup *cgrp) { if (cgrp && refcount_dec_and_test(&cgrp->refcnt)) { - close(cgrp->fd); - zfree(&cgrp->name); - free(cgrp); + cgroup__delete(cgrp); } } -int parse_cgroups(const struct option *opt __maybe_unused, const char *str, +struct cgroup *cgroup__get(struct cgroup *cgroup) +{ + if (cgroup) + refcount_inc(&cgroup->refcnt); + return cgroup; +} + +static void evsel__set_default_cgroup(struct perf_evsel *evsel, struct cgroup *cgroup) +{ + if (evsel->cgrp == NULL) + evsel->cgrp = cgroup__get(cgroup); +} + +void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgroup) +{ + struct perf_evsel *evsel; + + evlist__for_each_entry(evlist, evsel) + evsel__set_default_cgroup(evsel, cgroup); +} + +int parse_cgroups(const struct option *opt, 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; + struct cgroup *cgrp = NULL; const char *p, *e, *eos = str + strlen(str); char *s; int ret, i; @@ -179,10 +227,9 @@ int parse_cgroups(const struct option *opt __maybe_unused, const char *str, if (!s) return -1; ret = add_cgroup(evlist, s); - if (ret) { - free(s); + free(s); + if (ret) return -1; - } } /* nr_cgroups is increased een for empty cgroups */ nr_cgroups++; |