Release 4.10 tools/perf/util/pmu.c
#include <linux/list.h>
#include <linux/compiler.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdarg.h>
#include <dirent.h>
#include <api/fs/fs.h>
#include <locale.h>
#include "util.h"
#include "pmu.h"
#include "parse-events.h"
#include "cpumap.h"
#include "header.h"
#include "pmu-events/pmu-events.h"
#include "cache.h"
struct perf_pmu_format {
char *name;
int value;
DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
struct list_head list;
};
#define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
int perf_pmu_parse(struct list_head *list, char *name);
extern FILE *perf_pmu_in;
static LIST_HEAD(pmus);
/*
* Parse & process all the sysfs attributes located under
* the directory specified in 'dir' parameter.
*/
int perf_pmu__format_parse(char *dir, struct list_head *head)
{
struct dirent *evt_ent;
DIR *format_dir;
int ret = 0;
format_dir = opendir(dir);
if (!format_dir)
return -EINVAL;
while (!ret && (evt_ent = readdir(format_dir))) {
char path[PATH_MAX];
char *name = evt_ent->d_name;
FILE *file;
if (!strcmp(name, ".") || !strcmp(name, ".."))
continue;
snprintf(path, PATH_MAX, "%s/%s", dir, name);
ret = -EINVAL;
file = fopen(path, "r");
if (!file)
break;
perf_pmu_in = file;
ret = perf_pmu_parse(head, name);
fclose(file);
}
closedir(format_dir);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 156 | 100.00% | 2 | 100.00% |
| Total | 156 | 100.00% | 2 | 100.00% |
/*
* Reading/parsing the default pmu format definition, which should be
* located at:
* /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
*/
static int pmu_format(const char *name, struct list_head *format)
{
struct stat st;
char path[PATH_MAX];
const char *sysfs = sysfs__mountpoint();
if (!sysfs)
return -1;
snprintf(path, PATH_MAX,
"%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
if (stat(path, &st) < 0)
return 0; /* no error if format does not exist */
if (perf_pmu__format_parse(path, format))
return -1;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 81 | 90.00% | 2 | 33.33% |
robert richter | robert richter | 5 | 5.56% | 2 | 33.33% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 3 | 3.33% | 1 | 16.67% |
adrian hunter | adrian hunter | 1 | 1.11% | 1 | 16.67% |
| Total | 90 | 100.00% | 6 | 100.00% |
static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
{
struct stat st;
ssize_t sret;
char scale[128];
int fd, ret = -1;
char path[PATH_MAX];
char *lc;
snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
fd = open(path, O_RDONLY);
if (fd == -1)
return -1;
if (fstat(fd, &st) < 0)
goto error;
sret = read(fd, scale, sizeof(scale)-1);
if (sret < 0)
goto error;
if (scale[sret - 1] == '\n')
scale[sret - 1] = '\0';
else
scale[sret] = '\0';
/*
* save current locale
*/
lc = setlocale(LC_NUMERIC, NULL);
/*
* The lc string may be allocated in static storage,
* so get a dynamic copy to make it survive setlocale
* call below.
*/
lc = strdup(lc);
if (!lc) {
ret = -ENOMEM;
goto error;
}
/*
* force to C locale to ensure kernel
* scale string is converted correctly.
* kernel uses default C locale.
*/
setlocale(LC_NUMERIC, "C");
alias->scale = strtod(scale, NULL);
/* restore locale */
setlocale(LC_NUMERIC, lc);
free(lc);
ret = 0;
error:
close(fd);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
stephane eranian | stephane eranian | 181 | 78.70% | 1 | 33.33% |
jiri olsa | jiri olsa | 28 | 12.17% | 1 | 33.33% |
madhavan srinivasan | madhavan srinivasan | 21 | 9.13% | 1 | 33.33% |
| Total | 230 | 100.00% | 3 | 100.00% |
static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
{
char path[PATH_MAX];
ssize_t sret;
int fd;
snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
fd = open(path, O_RDONLY);
if (fd == -1)
return -1;
sret = read(fd, alias->unit, UNIT_MAX_LEN);
if (sret < 0)
goto error;
close(fd);
if (alias->unit[sret - 1] == '\n')
alias->unit[sret - 1] = '\0';
else
alias->unit[sret] = '\0';
return 0;
error:
close(fd);
alias->unit[0] = '\0';
return -1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
stephane eranian | stephane eranian | 123 | 83.11% | 1 | 50.00% |
madhavan srinivasan | madhavan srinivasan | 25 | 16.89% | 1 | 50.00% |
| Total | 148 | 100.00% | 2 | 100.00% |
static int
perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name)
{
char path[PATH_MAX];
int fd;
snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
fd = open(path, O_RDONLY);
if (fd == -1)
return -1;
close(fd);
alias->per_pkg = true;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
matt fleming | matt fleming | 75 | 100.00% | 1 | 100.00% |
| Total | 75 | 100.00% | 1 | 100.00% |
static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
char *dir, char *name)
{
char path[PATH_MAX];
int fd;
snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
fd = open(path, O_RDONLY);
if (fd == -1)
return -1;
alias->snapshot = true;
close(fd);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 75 | 100.00% | 1 | 100.00% |
| Total | 75 | 100.00% | 1 | 100.00% |
static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
char *desc, char *val, char *long_desc,
char *topic)
{
struct perf_pmu_alias *alias;
int ret;
alias = malloc(sizeof(*alias));
if (!alias)
return -ENOMEM;
INIT_LIST_HEAD(&alias->terms);
alias->scale = 1.0;
alias->unit[0] = '\0';
alias->per_pkg = false;
alias->snapshot = false;
ret = parse_events_terms(&alias->terms, val);
if (ret) {
pr_err("Cannot parse alias %s: %d\n", val, ret);
free(alias);
return ret;
}
alias->name = strdup(name);
if (dir) {
/*
* load unit name and scale if available
*/
perf_pmu__parse_unit(alias, dir, name);
perf_pmu__parse_scale(alias, dir, name);
perf_pmu__parse_per_pkg(alias, dir, name);
perf_pmu__parse_snapshot(alias, dir, name);
}
alias->desc = desc ? strdup(desc) : NULL;
alias->long_desc = long_desc ? strdup(long_desc) :
desc ? strdup(desc) : NULL;
alias->topic = topic ? strdup(topic) : NULL;
list_add_tail(&alias->list, list);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
zheng yan | zheng yan | 98 | 40.16% | 1 | 10.00% |
sukadev bhattiprolu | sukadev bhattiprolu | 48 | 19.67% | 2 | 20.00% |
stephane eranian | stephane eranian | 43 | 17.62% | 2 | 20.00% |
andi kleen | andi kleen | 30 | 12.30% | 2 | 20.00% |
matt fleming | matt fleming | 15 | 6.15% | 1 | 10.00% |
jiri olsa | jiri olsa | 9 | 3.69% | 1 | 10.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 1 | 0.41% | 1 | 10.00% |
| Total | 244 | 100.00% | 10 | 100.00% |
static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
{
char buf[256];
int ret;
ret = fread(buf, 1, sizeof(buf), file);
if (ret == 0)
return -EINVAL;
buf[ret] = 0;
return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
sukadev bhattiprolu | sukadev bhattiprolu | 81 | 97.59% | 2 | 66.67% |
andi kleen | andi kleen | 2 | 2.41% | 1 | 33.33% |
| Total | 83 | 100.00% | 3 | 100.00% |
static inline bool pmu_alias_info_file(char *name)
{
size_t len;
len = strlen(name);
if (len > 5 && !strcmp(name + len - 5, ".unit"))
return true;
if (len > 6 && !strcmp(name + len - 6, ".scale"))
return true;
if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
return true;
if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
return true;
return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
matt fleming | matt fleming | 87 | 80.56% | 2 | 66.67% |
jiri olsa | jiri olsa | 21 | 19.44% | 1 | 33.33% |
| Total | 108 | 100.00% | 3 | 100.00% |
/*
* Process all the sysfs attributes located under the directory
* specified in 'dir' parameter.
*/
static int pmu_aliases_parse(char *dir, struct list_head *head)
{
struct dirent *evt_ent;
DIR *event_dir;
event_dir = opendir(dir);
if (!event_dir)
return -EINVAL;
while ((evt_ent = readdir(event_dir))) {
char path[PATH_MAX];
char *name = evt_ent->d_name;
FILE *file;
if (!strcmp(name, ".") || !strcmp(name, ".."))
continue;
/*
* skip info files parsed in perf_pmu__new_alias()
*/
if (pmu_alias_info_file(name))
continue;
snprintf(path, PATH_MAX, "%s/%s", dir, name);
file = fopen(path, "r");
if (!file) {
pr_debug("Cannot open %s\n", path);
continue;
}
if (perf_pmu__new_alias(head, dir, name, file) < 0)
pr_debug("Cannot set up %s\n", name);
fclose(file);
}
closedir(event_dir);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
zheng yan | zheng yan | 138 | 80.70% | 1 | 25.00% |
andi kleen | andi kleen | 22 | 12.87% | 1 | 25.00% |
stephane eranian | stephane eranian | 9 | 5.26% | 1 | 25.00% |
matt fleming | matt fleming | 2 | 1.17% | 1 | 25.00% |
| Total | 171 | 100.00% | 4 | 100.00% |
/*
* Reading the pmu event aliases definition, which should be located at:
* /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
*/
static int pmu_aliases(const char *name, struct list_head *head)
{
struct stat st;
char path[PATH_MAX];
const char *sysfs = sysfs__mountpoint();
if (!sysfs)
return -1;
snprintf(path, PATH_MAX,
"%s/bus/event_source/devices/%s/events", sysfs, name);
if (stat(path, &st) < 0)
return 0; /* no error if 'events' does not exist */
if (pmu_aliases_parse(path, head))
return -1;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
zheng yan | zheng yan | 82 | 93.18% | 1 | 25.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 3 | 3.41% | 1 | 25.00% |
jiri olsa | jiri olsa | 2 | 2.27% | 1 | 25.00% |
adrian hunter | adrian hunter | 1 | 1.14% | 1 | 25.00% |
| Total | 88 | 100.00% | 4 | 100.00% |
static int pmu_alias_terms(struct perf_pmu_alias *alias,
struct list_head *terms)
{
struct parse_events_term *term, *cloned;
LIST_HEAD(list);
int ret;
list_for_each_entry(term, &alias->terms, list) {
ret = parse_events_term__clone(&cloned, term);
if (ret) {
parse_events_terms__purge(&list);
return ret;
}
list_add_tail(&cloned->list, &list);
}
list_splice(&list, terms);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
zheng yan | zheng yan | 82 | 92.13% | 1 | 20.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 4 | 4.49% | 3 | 60.00% |
jiri olsa | jiri olsa | 3 | 3.37% | 1 | 20.00% |
| Total | 89 | 100.00% | 5 | 100.00% |
/*
* Reading/parsing the default pmu type value, which should be
* located at:
* /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
*/
static int pmu_type(const char *name, __u32 *type)
{
struct stat st;
char path[PATH_MAX];
FILE *file;
int ret = 0;
const char *sysfs = sysfs__mountpoint();
if (!sysfs)
return -1;
snprintf(path, PATH_MAX,
"%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
if (stat(path, &st) < 0)
return -1;
file = fopen(path, "r");
if (!file)
return -EINVAL;
if (1 != fscanf(file, "%u", type))
ret = -1;
fclose(file);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 116 | 92.06% | 1 | 25.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 6 | 4.76% | 1 | 25.00% |
robert richter | robert richter | 3 | 2.38% | 1 | 25.00% |
adrian hunter | adrian hunter | 1 | 0.79% | 1 | 25.00% |
| Total | 126 | 100.00% | 4 | 100.00% |
/* Add all pmus in sysfs to pmu list: */
static void pmu_read_sysfs(void)
{
char path[PATH_MAX];
DIR *dir;
struct dirent *dent;
const char *sysfs = sysfs__mountpoint();
if (!sysfs)
return;
snprintf(path, PATH_MAX,
"%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
dir = opendir(path);
if (!dir)
return;
while ((dent = readdir(dir))) {
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
continue;
/* add to static LIST_HEAD(pmus): */
perf_pmu__find(dent->d_name);
}
closedir(dir);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
robert richter | robert richter | 105 | 94.59% | 1 | 50.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 6 | 5.41% | 1 | 50.00% |
| Total | 111 | 100.00% | 2 | 100.00% |
static struct cpu_map *pmu_cpumask(const char *name)
{
struct stat st;
char path[PATH_MAX];
FILE *file;
struct cpu_map *cpus;
const char *sysfs = sysfs__mountpoint();
const char *templates[] = {
"%s/bus/event_source/devices/%s/cpumask",
"%s/bus/event_source/devices/%s/cpus",
NULL
};
const char **template;
if (!sysfs)
return NULL;
for (template = templates; *template; template++) {
snprintf(path, PATH_MAX, *template, sysfs, name);
if (stat(path, &st) == 0)
break;
}
if (!*template)
return NULL;
file = fopen(path, "r");
if (!file)
return NULL;
cpus = cpu_map__read(file);
fclose(file);
return cpus;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
zheng yan | zheng yan | 99 | 66.00% | 1 | 25.00% |
mark rutland | mark rutland | 44 | 29.33% | 1 | 25.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 6 | 4.00% | 1 | 25.00% |
adrian hunter | adrian hunter | 1 | 0.67% | 1 | 25.00% |
| Total | 150 | 100.00% | 4 | 100.00% |
/*
* Return the CPU id as a raw string.
*
* Each architecture should provide a more precise id string that
* can be use to match the architecture's "mapfile".
*/
char * __weak get_cpuid_str(void)
{
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
sukadev bhattiprolu | sukadev bhattiprolu | 12 | 100.00% | 1 | 100.00% |
| Total | 12 | 100.00% | 1 | 100.00% |
/*
* From the pmu_events_map, find the table of PMU events that corresponds
* to the current running CPU. Then, add all PMU events from that table
* as aliases.
*/
static void pmu_add_cpu_aliases(struct list_head *head)
{
int i;
struct pmu_events_map *map;
struct pmu_event *pe;
char *cpuid;
static bool printed;
cpuid = getenv("PERF_CPUID");
if (cpuid)
cpuid = strdup(cpuid);
if (!cpuid)
cpuid = get_cpuid_str();
if (!cpuid)
return;
if (!printed) {
pr_debug("Using CPUID %s\n", cpuid);
printed = true;
}
i = 0;
while (1) {
map = &pmu_events_map[i++];
if (!map->table)
goto out;
if (!strcmp(map->cpuid, cpuid))
break;
}
/*
* Found a matching PMU events table. Create aliases
*/
i = 0;
while (1) {
pe = &map->table[i++];
if (!pe->name)
break;
/* need type casts to override 'const' */
__perf_pmu__new_alias(head, NULL, (char *)pe->name,
(char *)pe->desc, (char *)pe->event,
(char *)pe->long_desc, (char *)pe->topic);
}
out:
free(cpuid);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
sukadev bhattiprolu | sukadev bhattiprolu | 158 | 74.88% | 2 | 40.00% |
andi kleen | andi kleen | 53 | 25.12% | 3 | 60.00% |
| Total | 211 | 100.00% | 5 | 100.00% |
struct perf_event_attr * __weak
perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
{
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
adrian hunter | adrian hunter | 12 | 70.59% | 1 | 50.00% |
sukadev bhattiprolu | sukadev bhattiprolu | 5 | 29.41% | 1 | 50.00% |
| Total | 17 | 100.00% | 2 | 100.00% |
static struct perf_pmu *pmu_lookup(const char *name)
{
struct perf_pmu *pmu;
LIST_HEAD(format);
LIST_HEAD(aliases);
__u32 type;
/*
* The pmu data we store & need consists of the pmu
* type value and format definitions. Load both right
* now.
*/
if (pmu_format(name, &format))
return NULL;
if (pmu_aliases(name, &aliases))
return NULL;
if (!strcmp(name, "cpu"))
pmu_add_cpu_aliases(&aliases);
if (pmu_type(name, &type))
return NULL;
pmu = zalloc(sizeof(*pmu));
if (!pmu)
return NULL;
pmu->cpus = pmu_cpumask(name);
INIT_LIST_HEAD(&pmu->format);
INIT_LIST_HEAD(&pmu->aliases);
list_splice(&format, &pmu->format);
list_splice(&aliases, &pmu->aliases);
pmu->name = strdup(name);
pmu->type = type;
list_add_tail(&pmu->list, &pmus);
pmu->default_config = perf_pmu__get_default_config(pmu);
return pmu;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 121 | 63.35% | 2 | 25.00% |
zheng yan | zheng yan | 33 | 17.28% | 2 | 25.00% |
sukadev bhattiprolu | sukadev bhattiprolu | 16 | 8.38% | 1 | 12.50% |
robert richter | robert richter | 11 | 5.76% | 1 | 12.50% |
adrian hunter | adrian hunter | 10 | 5.24% | 2 | 25.00% |
| Total | 191 | 100.00% | 8 | 100.00% |
static struct perf_pmu *pmu_find(const char *name)
{
struct perf_pmu *pmu;
list_for_each_entry(pmu, &pmus, list)
if (!strcmp(pmu->name, name))
return pmu;
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 43 | 97.73% | 1 | 50.00% |
adrian hunter | adrian hunter | 1 | 2.27% | 1 | 50.00% |
| Total | 44 | 100.00% | 2 | 100.00% |
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
{
/*
* pmu iterator: If pmu is NULL, we start at the begin,
* otherwise return the next pmu. Returns NULL on end.
*/
if (!pmu) {
pmu_read_sysfs();
pmu = list_prepare_entry(pmu, &pmus, list);
}
list_for_each_entry_continue(pmu, &pmus, list)
return pmu;
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
robert richter | robert richter | 49 | 100.00% | 1 | 100.00% |
| Total | 49 | 100.00% | 1 | 100.00% |
struct perf_pmu *perf_pmu__find(const char *name)
{
struct perf_pmu *pmu;
/*
* Once PMU is loaded it stays in the list,
* so we keep us from multiple reading/parsing
* the pmu format definitions.
*/
pmu = pmu_find(name);
if (pmu)
return pmu;
return pmu_lookup(name);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 37 | 97.37% | 1 | 50.00% |
adrian hunter | adrian hunter | 1 | 2.63% | 1 | 50.00% |
| Total | 38 | 100.00% | 2 | 100.00% |
static struct perf_pmu_format *
pmu_find_format(struct list_head *formats, const char *name)
{
struct perf_pmu_format *format;
list_for_each_entry(format, formats, list)
if (!strcmp(format->name, name))
return format;
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 46 | 93.88% | 1 | 33.33% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 2 | 4.08% | 1 | 33.33% |
adrian hunter | adrian hunter | 1 | 2.04% | 1 | 33.33% |
| Total | 49 | 100.00% | 3 | 100.00% |
__u64 perf_pmu__format_bits(struct list_head *formats, const char *name)
{
struct perf_pmu_format *format = pmu_find_format(formats, name);
__u64 bits = 0;
int fbit;
if (!format)
return 0;
for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS)
bits |= 1ULL << fbit;
return bits;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
adrian hunter | adrian hunter | 60 | 100.00% | 1 | 100.00% |
| Total | 60 | 100.00% | 1 | 100.00% |
/*
* Sets value based on the format definition (format parameter)
* and unformated value (value parameter).
*/
static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
bool zero)
{
unsigned long fbit, vbit;
for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
if (!test_bit(fbit, format))
continue;
if (value & (1llu << vbit++))
*v |= (1llu << fbit);
else if (zero)
*v &= ~(1llu << fbit);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 68 | 73.91% | 1 | 50.00% |
adrian hunter | adrian hunter | 24 | 26.09% | 1 | 50.00% |
| Total | 92 | 100.00% | 2 | 100.00% |
static __u64 pmu_format_max_value(const unsigned long *format)
{
__u64 w = 0;
int fbit;
for_each_set_bit(fbit, format, PERF_PMU_FORMAT_BITS)
w |= (1ULL << fbit);
return w;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
adrian hunter | adrian hunter | 24 | 61.54% | 1 | 50.00% |
kan liang | kan liang | 15 | 38.46% | 1 | 50.00% |
| Total | 39 | 100.00% | 2 | 100.00% |
/*
* Term is a string term, and might be a param-term. Try to look up it's value
* in the remaining terms.
* - We have a term like "base-or-format-term=param-term",
* - We need to find the value supplied for "param-term" (with param-term named
* in a config string) later on in the term list.
*/
static int pmu_resolve_param_term(struct parse_events_term *term,
struct list_head *head_terms,
__u64 *value)
{
struct parse_events_term *