#include "../../../util/pmus.h"
#include "env.h"
-struct pmu_alias {
- char *name;
- char *alias;
- struct list_head list;
-};
-
-static LIST_HEAD(pmu_alias_name_list);
-static bool cached_list;
-
struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
{
#ifdef HAVE_AUXTRACE_SUPPORT
return NULL;
}
-static void pmu_alias__delete(struct pmu_alias *pmu_alias)
-{
- if (!pmu_alias)
- return;
-
- zfree(&pmu_alias->name);
- zfree(&pmu_alias->alias);
- free(pmu_alias);
-}
-
-static struct pmu_alias *pmu_alias__new(char *name, char *alias)
-{
- struct pmu_alias *pmu_alias = zalloc(sizeof(*pmu_alias));
-
- if (pmu_alias) {
- pmu_alias->name = strdup(name);
- if (!pmu_alias->name)
- goto out_delete;
-
- pmu_alias->alias = strdup(alias);
- if (!pmu_alias->alias)
- goto out_delete;
- }
- return pmu_alias;
-
-out_delete:
- pmu_alias__delete(pmu_alias);
- return NULL;
-}
-
-static int setup_pmu_alias_list(void)
-{
- int fd, dirfd;
- DIR *dir;
- struct dirent *dent;
- struct pmu_alias *pmu_alias;
- char buf[MAX_PMU_NAME_LEN];
- FILE *file;
- int ret = -ENOMEM;
-
- dirfd = perf_pmu__event_source_devices_fd();
- if (dirfd < 0)
- return -1;
-
- dir = fdopendir(dirfd);
- if (!dir)
- return -errno;
-
- while ((dent = readdir(dir))) {
- if (!strcmp(dent->d_name, ".") ||
- !strcmp(dent->d_name, ".."))
- continue;
-
- fd = perf_pmu__pathname_fd(dirfd, dent->d_name, "alias", O_RDONLY);
- if (fd < 0)
- continue;
-
- file = fdopen(fd, "r");
- if (!file)
- continue;
-
- if (!fgets(buf, sizeof(buf), file)) {
- fclose(file);
- continue;
- }
-
- fclose(file);
-
- /* Remove the last '\n' */
- buf[strlen(buf) - 1] = 0;
-
- pmu_alias = pmu_alias__new(dent->d_name, buf);
- if (!pmu_alias)
- goto close_dir;
-
- list_add_tail(&pmu_alias->list, &pmu_alias_name_list);
- }
-
- ret = 0;
-
-close_dir:
- closedir(dir);
- return ret;
-}
-
-static const char *__pmu_find_real_name(const char *name)
-{
- struct pmu_alias *pmu_alias;
-
- list_for_each_entry(pmu_alias, &pmu_alias_name_list, list) {
- if (!strcmp(name, pmu_alias->alias))
- return pmu_alias->name;
- }
-
- return name;
-}
-
-const char *pmu_find_real_name(const char *name)
-{
- if (cached_list)
- return __pmu_find_real_name(name);
-
- setup_pmu_alias_list();
- cached_list = true;
-
- return __pmu_find_real_name(name);
-}
-
-static const char *__pmu_find_alias_name(const char *name)
-{
- struct pmu_alias *pmu_alias;
-
- list_for_each_entry(pmu_alias, &pmu_alias_name_list, list) {
- if (!strcmp(name, pmu_alias->name))
- return pmu_alias->alias;
- }
- return NULL;
-}
-
-const char *pmu_find_alias_name(const char *name)
-{
- if (cached_list)
- return __pmu_find_alias_name(name);
-
- setup_pmu_alias_list();
- cached_list = true;
-
- return __pmu_find_alias_name(name);
-}
-
int perf_pmus__num_mem_pmus(void)
{
/* AMD uses IBS OP pmu and not a core PMU for perf mem/c2c */
return NULL;
}
-const char * __weak
-pmu_find_real_name(const char *name)
+static char *pmu_find_alias_name(struct perf_pmu *pmu, int dirfd)
{
- return name;
-}
+ FILE *file = perf_pmu__open_file_at(pmu, dirfd, "alias");
+ char *line = NULL;
+ size_t line_len = 0;
+ ssize_t ret;
-const char * __weak
-pmu_find_alias_name(const char *name __maybe_unused)
-{
- return NULL;
+ if (!file)
+ return NULL;
+
+ ret = getline(&line, &line_len, file);
+ if (ret < 0) {
+ fclose(file);
+ return NULL;
+ }
+ /* Remove trailing newline. */
+ if (ret > 0 && line[ret - 1] == '\n')
+ line[--ret] = '\0';
+
+ fclose(file);
+ return line;
}
static int pmu_max_precise(int dirfd, struct perf_pmu *pmu)
return max_precise;
}
-struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char *lookup_name)
+struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char *name)
{
struct perf_pmu *pmu;
__u32 type;
- const char *name = pmu_find_real_name(lookup_name);
- const char *alias_name;
pmu = zalloc(sizeof(*pmu));
if (!pmu)
pmu->is_core = is_pmu_core(name);
pmu->cpus = pmu_cpumask(dirfd, name, pmu->is_core);
- alias_name = pmu_find_alias_name(name);
- if (alias_name) {
- pmu->alias_name = strdup(alias_name);
- if (!pmu->alias_name)
- goto err;
- }
-
pmu->type = type;
pmu->is_uncore = pmu_is_uncore(dirfd, name);
if (pmu->is_uncore)
pmu->id = pmu_id(name);
pmu->max_precise = pmu_max_precise(dirfd, pmu);
+ pmu->alias_name = pmu_find_alias_name(pmu, dirfd);
pmu->events_table = perf_pmu__find_events_table(pmu);
pmu_add_sys_aliases(pmu);
list_add_tail(&pmu->list, pmus);