From 3ca32f69592be4d667c701763335fa496a0ede1d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 6 Mar 2018 09:51:48 -0300 Subject: perf cgroup: Rename 'struct cgroup_sel' to 'struct cgroup' That name isn't used, is shorter, lets switch to it. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-e51yphwgvepd1y4f5fjptmjq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cgroup.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/cgroup.h') diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h index afafc87e9201..934daa8e4c19 100644 --- a/tools/perf/util/cgroup.h +++ b/tools/perf/util/cgroup.h @@ -6,7 +6,7 @@ struct option; -struct cgroup_sel { +struct cgroup { char *name; int fd; refcount_t refcnt; @@ -14,7 +14,8 @@ struct cgroup_sel { extern int nr_cgroups; /* number of explicit cgroups defined */ -void close_cgroup(struct cgroup_sel *cgrp); +void close_cgroup(struct cgroup *cgrp); + int parse_cgroups(const struct option *opt, const char *str, int unset); #endif /* __CGROUP_H__ */ -- cgit v1.2.3 From a53b646030ee6f65accdc49e772823b8134a37f6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 6 Mar 2018 10:10:45 -0300 Subject: perf cgroup: Rename close_cgroup() to cgroup__put() It is not really closing the cgroup, but instead dropping a reference count and if it hits zero, then calling delete, which will, among other cleanup shores, close the cgroup fd. So it is really dropping a reference to that cgroup, and the method name for that is "put", so rename close_cgroup() to cgroup__put() to follow this naming convention. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-sccxpnd7bgwc1llgokt6fcey@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cgroup.c | 5 ++--- tools/perf/util/cgroup.h | 3 ++- tools/perf/util/evsel.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'tools/perf/util/cgroup.h') diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 4dd52feb1ae6..b078d54d4245 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -135,9 +135,8 @@ 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; @@ -151,7 +150,7 @@ static void cgroup__delete(struct cgroup *cgroup) free(cgroup); } -void close_cgroup(struct cgroup *cgrp) +void cgroup__put(struct cgroup *cgrp) { if (cgrp && refcount_dec_and_test(&cgrp->refcnt)) { cgroup__delete(cgrp); diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h index 934daa8e4c19..69169fbf8d13 100644 --- a/tools/perf/util/cgroup.h +++ b/tools/perf/util/cgroup.h @@ -14,7 +14,8 @@ struct cgroup { extern int nr_cgroups; /* number of explicit cgroups defined */ -void close_cgroup(struct cgroup *cgrp); + +void cgroup__put(struct cgroup *cgroup); int parse_cgroups(const struct option *opt, const char *str, int unset); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index b56e1c2ddaee..f1f883bb41a8 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1233,7 +1233,7 @@ void perf_evsel__exit(struct perf_evsel *evsel) perf_evsel__free_fd(evsel); perf_evsel__free_id(evsel); perf_evsel__free_config_terms(evsel); - close_cgroup(evsel->cgrp); + cgroup__put(evsel->cgrp); cpu_map__put(evsel->cpus); cpu_map__put(evsel->own_cpus); thread_map__put(evsel->threads); -- cgit v1.2.3 From fc9ffb9cf085c78f49d4d1a602d723504c0d9c75 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 6 Mar 2018 10:18:40 -0300 Subject: perf cgroup: Introduce cgroup__get() The refcount operation counterpart to cgroup__put(), use it when reusing a cgroup. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-14ynvrl7y2cz8gyuy5q5v41g@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cgroup.c | 16 ++++++++++------ tools/perf/util/cgroup.h | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'tools/perf/util/cgroup.h') diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index b078d54d4245..8ea964461eb7 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -99,15 +99,12 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) * 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) { @@ -157,6 +154,13 @@ void cgroup__put(struct cgroup *cgrp) } } +struct cgroup *cgroup__get(struct cgroup *cgroup) +{ + if (cgroup) + refcount_inc(&cgroup->refcnt); + return cgroup; +} + int parse_cgroups(const struct option *opt, const char *str, int unset __maybe_unused) { diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h index 69169fbf8d13..34a6c11543dc 100644 --- a/tools/perf/util/cgroup.h +++ b/tools/perf/util/cgroup.h @@ -15,6 +15,7 @@ struct cgroup { extern int nr_cgroups; /* number of explicit cgroups defined */ +struct cgroup *cgroup__get(struct cgroup *cgroup); void cgroup__put(struct cgroup *cgroup); int parse_cgroups(const struct option *opt, const char *str, int unset); -- cgit v1.2.3 From 69239ec81d596c57e0cf2d2f26cfe92e8cbd0929 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 6 Mar 2018 15:27:08 -0300 Subject: perf cgroup: Add evlist__findnew_cgroup() Similar to machine__findnew_thread(), etc, i.e. try to find, get a refcount if found and return it, otherwise return a new cgroup object. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-im1omevlihhyneiic4nl3g24@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cgroup.c | 17 ++++++++++------- tools/perf/util/cgroup.h | 4 ++++ 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'tools/perf/util/cgroup.h') diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 26a837037797..6fd33ffc2488 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -128,18 +128,21 @@ out_err: return NULL; } +struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, char *name) +{ + struct cgroup *cgroup = evlist__find_cgroup(evlist, name); + + return cgroup ?: cgroup__new(name); +} + static int add_cgroup(struct perf_evlist *evlist, char *str) { struct perf_evsel *counter; - struct cgroup *cgrp = evlist__find_cgroup(evlist, str); + struct cgroup *cgrp = evlist__findnew_cgroup(evlist, str); int n; - if (!cgrp) { - cgrp = cgroup__new(str); - if (!cgrp) - return -1; - } - + if (!cgrp) + return -1; /* * find corresponding event * if add cgroup N, then need to find event N diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h index 34a6c11543dc..0e377e6340dd 100644 --- a/tools/perf/util/cgroup.h +++ b/tools/perf/util/cgroup.h @@ -18,6 +18,10 @@ extern int nr_cgroups; /* number of explicit cgroups defined */ struct cgroup *cgroup__get(struct cgroup *cgroup); void cgroup__put(struct cgroup *cgroup); +struct perf_evlist; + +struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, char *name); + int parse_cgroups(const struct option *opt, const char *str, int unset); #endif /* __CGROUP_H__ */ -- cgit v1.2.3 From 483322dda03a7ad807e82f9c25fac315a4eee1c5 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 6 Mar 2018 15:48:10 -0300 Subject: perf cgroup: Add evlist__add_default_cgroup() So that tools like 'perf trace' can allow the user to set a cgroup to be used for all the evsels still without a crgroup setup by parse_cgroups(), such as the one to use for the syscalls, vfs_getname and other events involved in strace like syscall tracing. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-zf9jjsbj661r3lk6qb7g8j70@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cgroup.c | 14 ++++++++++++++ tools/perf/util/cgroup.h | 2 ++ 2 files changed, 16 insertions(+) (limited to 'tools/perf/util/cgroup.h') diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 6fd33ffc2488..d8cd0e601c56 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -182,6 +182,20 @@ struct cgroup *cgroup__get(struct cgroup *cgroup) 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) { diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h index 0e377e6340dd..b213f5e9a3ed 100644 --- a/tools/perf/util/cgroup.h +++ b/tools/perf/util/cgroup.h @@ -22,6 +22,8 @@ struct perf_evlist; struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, char *name); +void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgroup); + int parse_cgroups(const struct option *opt, const char *str, int unset); #endif /* __CGROUP_H__ */ -- cgit v1.2.3 From 3b5692864da3a8dec95d8c757147f436d19f8ff7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 6 Mar 2018 15:53:22 -0300 Subject: perf cgroup: Make the cgroup name be const char * The usual thing is for a constructor to allocate space for its members, not to require that the caller pass a pre-allocated 'name' and then, at its destructor, to free something not allocated by it. Fix it by making cgroup__new() to receive a const char pointer, then allocate cgroup->name that then can continue to be freed at cgroup__delete(), balancing the alloc/free operations inside the cgroup struct methods. This eases calling evlist__findnew_cgroup() from the custom 'perf trace' cgroup parser, that will only call parse_cgroups() when the '-G cgroup' is passed on the command line after '-e event' entries, when it'll behave just like 'perf stat' and 'perf record', i.e. the previous parse_cgroup() users that mandate that -G only can come after a -e. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-4leugnuyqi10t98990o3xi1t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cgroup.c | 24 ++++++++++++++---------- tools/perf/util/cgroup.h | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'tools/perf/util/cgroup.h') diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index d8cd0e601c56..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,7 +90,7 @@ static int open_cgroup(char *name) return fd; } -static struct cgroup *evlist__find_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 *cgrp = NULL; @@ -109,33 +109,38 @@ static struct cgroup *evlist__find_cgroup(struct perf_evlist *evlist, char *str) return cgrp; } -static struct cgroup *cgroup__new(char *name) +static struct cgroup *cgroup__new(const char *name) { struct cgroup *cgroup = zalloc(sizeof(*cgroup)); if (cgroup != NULL) { - cgroup->name = name; refcount_set(&cgroup->refcnt, 1); + cgroup->name = strdup(name); + if (!cgroup->name) + goto out_err; cgroup->fd = open_cgroup(name); if (cgroup->fd == -1) - goto out_err; + 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, char *name) +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, char *str) +static int add_cgroup(struct perf_evlist *evlist, const char *str) { struct perf_evsel *counter; struct cgroup *cgrp = evlist__findnew_cgroup(evlist, str); @@ -222,10 +227,9 @@ int parse_cgroups(const struct option *opt, 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++; diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h index b213f5e9a3ed..f033a80c1b14 100644 --- a/tools/perf/util/cgroup.h +++ b/tools/perf/util/cgroup.h @@ -20,7 +20,7 @@ void cgroup__put(struct cgroup *cgroup); struct perf_evlist; -struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, char *name); +struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, const char *name); void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgroup); -- cgit v1.2.3