Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-4leugnuyqi10t98990o3xi1t@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+15 -11
+14 -10
tools/perf/util/cgroup.c
··· 71 71 return -1; 72 72 } 73 73 74 - static int open_cgroup(char *name) 74 + static int open_cgroup(const char *name) 75 75 { 76 76 char path[PATH_MAX + 1]; 77 77 char mnt[PATH_MAX + 1]; ··· 90 90 return fd; 91 91 } 92 92 93 - static struct cgroup *evlist__find_cgroup(struct perf_evlist *evlist, char *str) 93 + static struct cgroup *evlist__find_cgroup(struct perf_evlist *evlist, const char *str) 94 94 { 95 95 struct perf_evsel *counter; 96 96 struct cgroup *cgrp = NULL; ··· 109 109 return cgrp; 110 110 } 111 111 112 - static struct cgroup *cgroup__new(char *name) 112 + static struct cgroup *cgroup__new(const char *name) 113 113 { 114 114 struct cgroup *cgroup = zalloc(sizeof(*cgroup)); 115 115 116 116 if (cgroup != NULL) { 117 - cgroup->name = name; 118 117 refcount_set(&cgroup->refcnt, 1); 119 118 119 + cgroup->name = strdup(name); 120 + if (!cgroup->name) 121 + goto out_err; 120 122 cgroup->fd = open_cgroup(name); 121 123 if (cgroup->fd == -1) 122 - goto out_err; 124 + goto out_free_name; 123 125 } 124 126 125 127 return cgroup; 128 + 129 + out_free_name: 130 + free(cgroup->name); 126 131 out_err: 127 132 free(cgroup); 128 133 return NULL; 129 134 } 130 135 131 - struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, char *name) 136 + struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, const char *name) 132 137 { 133 138 struct cgroup *cgroup = evlist__find_cgroup(evlist, name); 134 139 135 140 return cgroup ?: cgroup__new(name); 136 141 } 137 142 138 - static int add_cgroup(struct perf_evlist *evlist, char *str) 143 + static int add_cgroup(struct perf_evlist *evlist, const char *str) 139 144 { 140 145 struct perf_evsel *counter; 141 146 struct cgroup *cgrp = evlist__findnew_cgroup(evlist, str); ··· 227 222 if (!s) 228 223 return -1; 229 224 ret = add_cgroup(evlist, s); 230 - if (ret) { 231 - free(s); 225 + free(s); 226 + if (ret) 232 227 return -1; 233 - } 234 228 } 235 229 /* nr_cgroups is increased een for empty cgroups */ 236 230 nr_cgroups++;
+1 -1
tools/perf/util/cgroup.h
··· 20 20 21 21 struct perf_evlist; 22 22 23 - struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, char *name); 23 + struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, const char *name); 24 24 25 25 void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgroup); 26 26