]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - tools/perf/util/cgroup.c
3 #include <subcmd/parse-options.h>
11 cgroupfs_find_mountpoint(char *buf
, size_t maxlen
)
14 char mountpoint
[PATH_MAX
+ 1], tokens
[PATH_MAX
+ 1], type
[PATH_MAX
+ 1];
15 char path_v1
[PATH_MAX
+ 1], path_v2
[PATH_MAX
+ 2], *path
;
16 char *token
, *saved_ptr
= NULL
;
18 fp
= fopen("/proc/mounts", "r");
23 * in order to handle split hierarchy, we need to scan /proc/mounts
24 * and inspect every cgroupfs mount point to find one that has
25 * perf_event subsystem
30 while (fscanf(fp
, "%*s %"STR(PATH_MAX
)"s %"STR(PATH_MAX
)"s %"
31 STR(PATH_MAX
)"s %*d %*d\n",
32 mountpoint
, type
, tokens
) == 3) {
34 if (!path_v1
[0] && !strcmp(type
, "cgroup")) {
36 token
= strtok_r(tokens
, ",", &saved_ptr
);
38 while (token
!= NULL
) {
39 if (!strcmp(token
, "perf_event")) {
40 strcpy(path_v1
, mountpoint
);
43 token
= strtok_r(NULL
, ",", &saved_ptr
);
47 if (!path_v2
[0] && !strcmp(type
, "cgroup2"))
48 strcpy(path_v2
, mountpoint
);
50 if (path_v1
[0] && path_v2
[0])
62 if (strlen(path
) < maxlen
) {
69 static int open_cgroup(char *name
)
71 char path
[PATH_MAX
+ 1];
72 char mnt
[PATH_MAX
+ 1];
76 if (cgroupfs_find_mountpoint(mnt
, PATH_MAX
+ 1))
79 snprintf(path
, PATH_MAX
, "%s/%s", mnt
, name
);
81 fd
= open(path
, O_RDONLY
);
83 fprintf(stderr
, "no access to cgroup %s\n", path
);
88 static int add_cgroup(struct perf_evlist
*evlist
, char *str
)
90 struct perf_evsel
*counter
;
91 struct cgroup_sel
*cgrp
= NULL
;
94 * check if cgrp is already defined, if so we reuse it
96 evlist__for_each_entry(evlist
, counter
) {
100 if (!strcmp(cgrp
->name
, str
))
107 cgrp
= zalloc(sizeof(*cgrp
));
113 cgrp
->fd
= open_cgroup(str
);
114 if (cgrp
->fd
== -1) {
121 * find corresponding event
122 * if add cgroup N, then need to find event N
125 evlist__for_each_entry(evlist
, counter
) {
130 if (atomic_read(&cgrp
->refcnt
) == 0)
135 atomic_inc(&cgrp
->refcnt
);
136 counter
->cgrp
= cgrp
;
140 void close_cgroup(struct cgroup_sel
*cgrp
)
142 if (cgrp
&& atomic_dec_and_test(&cgrp
->refcnt
)) {
149 int parse_cgroups(const struct option
*opt __maybe_unused
, const char *str
,
150 int unset __maybe_unused
)
152 struct perf_evlist
*evlist
= *(struct perf_evlist
**)opt
->value
;
153 const char *p
, *e
, *eos
= str
+ strlen(str
);
157 if (list_empty(&evlist
->entries
)) {
158 fprintf(stderr
, "must define events before cgroups\n");
163 p
= strchr(str
, ',');
166 /* allow empty cgroups, i.e., skip */
168 /* termination added */
169 s
= strndup(str
, e
- str
);
172 ret
= add_cgroup(evlist
, s
);
178 /* nr_cgroups is increased een for empty cgroups */