cregit-Linux how code gets into the kernel

Release 4.11 tools/perf/util/cgroup.c

Directory: tools/perf/util
#include "util.h"
#include "../perf.h"
#include <subcmd/parse-options.h>
#include "evsel.h"
#include "cgroup.h"
#include "evlist.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 %"STR(PATH_MAX)"s %"STR(PATH_MAX)"s %" STR(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 Eranian19063.97%125.00%
Tejun Heo9933.33%125.00%
Arnaldo Carvalho de Melo62.02%125.00%
Eric Dumazet20.67%125.00%
Total297100.00%4100.00%


static int open_cgroup(char *name) { char path[PATH_MAX + 1]; char mnt[PATH_MAX + 1]; int fd; if (cgroupfs_find_mountpoint(mnt, PATH_MAX + 1)) return -1; snprintf(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 Eranian8195.29%150.00%
Arnaldo Carvalho de Melo44.71%150.00%
Total85100.00%2100.00%


static int add_cgroup(struct perf_evlist *evlist, char *str) { struct perf_evsel *counter; struct cgroup_sel *cgrp = NULL; int n; /* * check if cgrp is already defined, if so we reuse it */ evlist__for_each_entry(evlist, counter) { cgrp = counter->cgrp; if (!cgrp) continue; if (!strcmp(cgrp->name, str)) break; cgrp = NULL; } if (!cgrp) { cgrp = zalloc(sizeof(*cgrp)); if (!cgrp) return -1; cgrp->name = str; cgrp->fd = open_cgroup(str); if (cgrp->fd == -1) { free(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++; } if (atomic_read(&cgrp->refcnt) == 0) free(cgrp); return -1; found: atomic_inc(&cgrp->refcnt); counter->cgrp = cgrp; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian18192.82%125.00%
Arnaldo Carvalho de Melo147.18%375.00%
Total195100.00%4100.00%


void close_cgroup(struct cgroup_sel *cgrp) { if (cgrp && atomic_dec_and_test(&cgrp->refcnt)) { close(cgrp->fd); zfree(&cgrp->name); free(cgrp); } }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian3784.09%133.33%
Arnaldo Carvalho de Melo715.91%266.67%
Total44100.00%3100.00%


int parse_cgroups(const struct option *opt __maybe_unused, const char *str, int unset __maybe_unused) { struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; const char *p, *e, *eos = str + strlen(str); char *s; int ret; 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); if (ret) { free(s); return -1; } } /* nr_cgroups is increased een for empty cgroups */ nr_cgroups++; if (!p) break; str = p+1; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian18098.90%150.00%
Irina Tirdea21.10%150.00%
Total182100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Stéphane Eranian68983.62%110.00%
Tejun Heo9912.01%110.00%
Arnaldo Carvalho de Melo313.76%550.00%
Eric Dumazet20.24%110.00%
Irina Tirdea20.24%110.00%
Josh Poimboeuf10.12%110.00%
Total824100.00%10100.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.