~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/cgroup.c

Version: ~ [ linux-5.14-rc3 ] ~ [ linux-5.13.5 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.53 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.135 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.198 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.240 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.276 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.276 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include "util.h"
  2 #include "../perf.h"
  3 #include "parse-options.h"
  4 #include "evsel.h"
  5 #include "cgroup.h"
  6 #include "evlist.h"
  7 
  8 int nr_cgroups;
  9 
 10 static int
 11 cgroupfs_find_mountpoint(char *buf, size_t maxlen)
 12 {
 13         FILE *fp;
 14         char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1];
 15         char *token, *saved_ptr = NULL;
 16         int found = 0;
 17 
 18         fp = fopen("/proc/mounts", "r");
 19         if (!fp)
 20                 return -1;
 21 
 22         /*
 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
 26          */
 27         while (fscanf(fp, "%*s %"STR(PATH_MAX)"s %"STR(PATH_MAX)"s %"
 28                                 STR(PATH_MAX)"s %*d %*d\n",
 29                                 mountpoint, type, tokens) == 3) {
 30 
 31                 if (!strcmp(type, "cgroup")) {
 32 
 33                         token = strtok_r(tokens, ",", &saved_ptr);
 34 
 35                         while (token != NULL) {
 36                                 if (!strcmp(token, "perf_event")) {
 37                                         found = 1;
 38                                         break;
 39                                 }
 40                                 token = strtok_r(NULL, ",", &saved_ptr);
 41                         }
 42                 }
 43                 if (found)
 44                         break;
 45         }
 46         fclose(fp);
 47         if (!found)
 48                 return -1;
 49 
 50         if (strlen(mountpoint) < maxlen) {
 51                 strcpy(buf, mountpoint);
 52                 return 0;
 53         }
 54         return -1;
 55 }
 56 
 57 static int open_cgroup(char *name)
 58 {
 59         char path[PATH_MAX + 1];
 60         char mnt[PATH_MAX + 1];
 61         int fd;
 62 
 63 
 64         if (cgroupfs_find_mountpoint(mnt, PATH_MAX + 1))
 65                 return -1;
 66 
 67         snprintf(path, PATH_MAX, "%s/%s", mnt, name);
 68 
 69         fd = open(path, O_RDONLY);
 70         if (fd == -1)
 71                 fprintf(stderr, "no access to cgroup %s\n", path);
 72 
 73         return fd;
 74 }
 75 
 76 static int add_cgroup(struct perf_evlist *evlist, char *str)
 77 {
 78         struct perf_evsel *counter;
 79         struct cgroup_sel *cgrp = NULL;
 80         int n;
 81         /*
 82          * check if cgrp is already defined, if so we reuse it
 83          */
 84         evlist__for_each(evlist, counter) {
 85                 cgrp = counter->cgrp;
 86                 if (!cgrp)
 87                         continue;
 88                 if (!strcmp(cgrp->name, str))
 89                         break;
 90 
 91                 cgrp = NULL;
 92         }
 93 
 94         if (!cgrp) {
 95                 cgrp = zalloc(sizeof(*cgrp));
 96                 if (!cgrp)
 97                         return -1;
 98 
 99                 cgrp->name = str;
100 
101                 cgrp->fd = open_cgroup(str);
102                 if (cgrp->fd == -1) {
103                         free(cgrp);
104                         return -1;
105                 }
106         }
107 
108         /*
109          * find corresponding event
110          * if add cgroup N, then need to find event N
111          */
112         n = 0;
113         evlist__for_each(evlist, counter) {
114                 if (n == nr_cgroups)
115                         goto found;
116                 n++;
117         }
118         if (atomic_read(&cgrp->refcnt) == 0)
119                 free(cgrp);
120 
121         return -1;
122 found:
123         atomic_inc(&cgrp->refcnt);
124         counter->cgrp = cgrp;
125         return 0;
126 }
127 
128 void close_cgroup(struct cgroup_sel *cgrp)
129 {
130         if (cgrp && atomic_dec_and_test(&cgrp->refcnt)) {
131                 close(cgrp->fd);
132                 zfree(&cgrp->name);
133                 free(cgrp);
134         }
135 }
136 
137 int parse_cgroups(const struct option *opt __maybe_unused, const char *str,
138                   int unset __maybe_unused)
139 {
140         struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
141         const char *p, *e, *eos = str + strlen(str);
142         char *s;
143         int ret;
144 
145         if (list_empty(&evlist->entries)) {
146                 fprintf(stderr, "must define events before cgroups\n");
147                 return -1;
148         }
149 
150         for (;;) {
151                 p = strchr(str, ',');
152                 e = p ? p : eos;
153 
154                 /* allow empty cgroups, i.e., skip */
155                 if (e - str) {
156                         /* termination added */
157                         s = strndup(str, e - str);
158                         if (!s)
159                                 return -1;
160                         ret = add_cgroup(evlist, s);
161                         if (ret) {
162                                 free(s);
163                                 return -1;
164                         }
165                 }
166                 /* nr_cgroups is increased een for empty cgroups */
167                 nr_cgroups++;
168                 if (!p)
169                         break;
170                 str = p+1;
171         }
172         return 0;
173 }
174 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp