cregit-Linux how code gets into the kernel

Release 4.18 tools/perf/util/cgroup.c

Directory: tools/perf/util
// SPDX-License-Identifier: GPL-2.0
#include "util.h"
#include "../perf.h"
#include <subcmd/parse-options.h>
#include "evsel.h"
#include "cgroup.h"
#include "evlist.h"
#include <linux/stringify.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int nr_cgroups;


static int cgroupfs_find_mountpoint(char *buf, size_t maxlen) { FILE *fp; char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1]; char path_v1[PATH_MAX + 1], path_v2[PATH_MAX + 2], *path; char *token, *saved_ptr = NULL; fp = fopen("/proc/mounts", "r"); if (!fp) return -1; /* * in order to handle split hierarchy, we need to scan /proc/mounts * and inspect every cgroupfs mount point to find one that has * perf_event subsystem */ path_v1[0] = '\0'; path_v2[0] = '\0'; while (fscanf(fp, "%*s %"__stringify(PATH_MAX)"s %"__stringify(PATH_MAX)"s %" __stringify(PATH_MAX)"s %*d %*d\n", mountpoint, type, tokens) == 3) { if (!path_v1[0] && !strcmp(type, "cgroup")) { token = strtok_r(tokens, ",", &saved_ptr); while (token != NULL) { if (!strcmp(token, "perf_event")) { strcpy(path_v1, mountpoint); break; } token = strtok_r(NULL, ",", &saved_ptr); } } if (!path_v2[0] && !strcmp(type, "cgroup2")) strcpy(path_v2, mountpoint); if (path_v1[0] && path_v2[0]) break; } fclose(fp); if (path_v1[0]) path = path_v1; else if (path_v2[0]) path = path_v2; else return -1; if (strlen(path) < maxlen) { strcpy(buf, path); return 0; } return -1; }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian18762.96%120.00%
Tejun Heo9933.33%120.00%
Arnaldo Carvalho de Melo93.03%240.00%
Eric Dumazet20.67%120.00%
Total297100.00%5100.00%


static int open_cgroup(const char *name) { char path[PATH_MAX + 1]; char mnt[PATH_MAX + 1]; int fd; if (cgroupfs_find_mountpoint(mnt, PATH_MAX + 1)) return -1; scnprintf(path, PATH_MAX, "%s/%s", mnt, name); fd = open(path, O_RDONLY); if (fd == -1) fprintf(stderr, "no access to cgroup %s\n", path); return fd; }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian8093.02%125.00%
Arnaldo Carvalho de Melo55.81%250.00%
Jiri Olsa11.16%125.00%
Total86100.00%4100.00%


static struct cgroup *evlist__find_cgroup(struct perf_evlist *evlist, const char *str) { struct perf_evsel *counter; /* * check if cgrp is already defined, if so we reuse it */ evlist__for_each_entry(evlist, counter) { if (!counter->cgrp) continue; if (!strcmp(counter->cgrp->name, str)) return cgroup__get(counter->cgrp); } return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian4163.08%112.50%
Arnaldo Carvalho de Melo2436.92%787.50%
Total65100.00%8100.00%


static struct cgroup *cgroup__new(const char *name) { struct cgroup *cgroup = zalloc(sizeof(*cgroup)); if (cgroup != NULL) { 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_free_name; } return cgroup; out_free_name: free(cgroup->name); out_err: free(cgroup); return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Arnaldo Carvalho de Melo8074.77%480.00%
Stéphane Eranian2725.23%120.00%
Total107100.00%5100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Arnaldo Carvalho de Melo38100.00%2100.00%
Total38100.00%2100.00%


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 */ n = 0; evlist__for_each_entry(evlist, counter) { if (n == nr_cgroups) goto found; n++; } cgroup__put(cgrp); return -1; found: counter->cgrp = cgrp; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian4752.22%114.29%
Arnaldo Carvalho de Melo4347.78%685.71%
Total90100.00%7100.00%


static void cgroup__delete(struct cgroup *cgroup) { close(cgroup->fd); zfree(&cgroup->name); free(cgroup); }

Contributors

PersonTokensPropCommitsCommitProp
Arnaldo Carvalho de Melo31100.00%1100.00%
Total31100.00%1100.00%


void cgroup__put(struct cgroup *cgrp) { if (cgrp && refcount_dec_and_test(&cgrp->refcnt)) { cgroup__delete(cgrp); } }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian2172.41%116.67%
Arnaldo Carvalho de Melo724.14%466.67%
Elena Reshetova13.45%116.67%
Total29100.00%6100.00%


struct cgroup *cgroup__get(struct cgroup *cgroup) { if (cgroup) refcount_inc(&cgroup->refcnt); return cgroup; }

Contributors

PersonTokensPropCommitsCommitProp
Arnaldo Carvalho de Melo27100.00%1100.00%
Total27100.00%1100.00%


static void evsel__set_default_cgroup(struct perf_evsel *evsel, struct cgroup *cgroup) { if (evsel->cgrp == NULL) evsel->cgrp = cgroup__get(cgroup); }

Contributors

PersonTokensPropCommitsCommitProp
Arnaldo Carvalho de Melo33100.00%1100.00%
Total33100.00%1100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
Arnaldo Carvalho de Melo33100.00%1100.00%
Total33100.00%1100.00%


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 *cgrp = NULL; const char *p, *e, *eos = str + strlen(str); char *s; int ret, i; if (list_empty(&evlist->entries)) { fprintf(stderr, "must define events before cgroups\n"); return -1; } for (;;) { p = strchr(str, ','); e = p ? p : eos; /* allow empty cgroups, i.e., skip */ if (e - str) { /* termination added */ s = strndup(str, e - str); if (!s) return -1; ret = add_cgroup(evlist, s); free(s); if (ret) return -1; } /* nr_cgroups is increased een for empty cgroups */ nr_cgroups++; if (!p) break; str = p+1; } /* for the case one cgroup combine to multiple events */ i = 0; if (nr_cgroups == 1) { evlist__for_each_entry(evlist, counter) { if (i == 0) cgrp = counter->cgrp; else { counter->cgrp = cgrp; refcount_inc(&cgrp->refcnt); } i++; } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian17470.73%120.00%
weiping zhang6626.83%120.00%
Arnaldo Carvalho de Melo52.03%240.00%
Irina Tirdea10.41%120.00%
Total246100.00%5100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian59753.49%13.85%
Arnaldo Carvalho de Melo34731.09%1765.38%
Tejun Heo998.87%13.85%
weiping zhang665.91%13.85%
Eric Dumazet20.18%13.85%
Greg Kroah-Hartman10.09%13.85%
Jiri Olsa10.09%13.85%
Elena Reshetova10.09%13.85%
Josh Poimboeuf10.09%13.85%
Irina Tirdea10.09%13.85%
Total1116100.00%26100.00%
Directory: tools/perf/util
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.