0001
0002 #include <linux/list.h>
0003 #include <linux/compiler.h>
0004 #include <linux/string.h>
0005 #include <linux/zalloc.h>
0006 #include <sys/types.h>
0007 #include <errno.h>
0008 #include <fcntl.h>
0009 #include <sys/stat.h>
0010 #include <unistd.h>
0011 #include <stdio.h>
0012 #include <stdbool.h>
0013 #include <stdarg.h>
0014 #include <locale.h>
0015 #include <api/fs/fs.h>
0016 #include "fncache.h"
0017 #include "pmu-hybrid.h"
0018
0019 LIST_HEAD(perf_pmu__hybrid_pmus);
0020
0021 bool perf_pmu__hybrid_mounted(const char *name)
0022 {
0023 char path[PATH_MAX];
0024 const char *sysfs;
0025 FILE *file;
0026 int n, cpu;
0027
0028 if (strncmp(name, "cpu_", 4))
0029 return false;
0030
0031 sysfs = sysfs__mountpoint();
0032 if (!sysfs)
0033 return false;
0034
0035 snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name);
0036 if (!file_available(path))
0037 return false;
0038
0039 file = fopen(path, "r");
0040 if (!file)
0041 return false;
0042
0043 n = fscanf(file, "%u", &cpu);
0044 fclose(file);
0045 if (n <= 0)
0046 return false;
0047
0048 return true;
0049 }
0050
0051 struct perf_pmu *perf_pmu__find_hybrid_pmu(const char *name)
0052 {
0053 struct perf_pmu *pmu;
0054
0055 if (!name)
0056 return NULL;
0057
0058 perf_pmu__for_each_hybrid_pmu(pmu) {
0059 if (!strcmp(name, pmu->name))
0060 return pmu;
0061 }
0062
0063 return NULL;
0064 }
0065
0066 bool perf_pmu__is_hybrid(const char *name)
0067 {
0068 return perf_pmu__find_hybrid_pmu(name) != NULL;
0069 }
0070
0071 char *perf_pmu__hybrid_type_to_pmu(const char *type)
0072 {
0073 char *pmu_name = NULL;
0074
0075 if (asprintf(&pmu_name, "cpu_%s", type) < 0)
0076 return NULL;
0077
0078 if (perf_pmu__is_hybrid(pmu_name))
0079 return pmu_name;
0080
0081
0082
0083
0084 if (perf_pmu__hybrid_mounted(pmu_name))
0085 return pmu_name;
0086
0087 free(pmu_name);
0088 return NULL;
0089 }