pmu-hybrid.c (1570B)
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/list.h> 3#include <linux/compiler.h> 4#include <linux/string.h> 5#include <linux/zalloc.h> 6#include <sys/types.h> 7#include <errno.h> 8#include <fcntl.h> 9#include <sys/stat.h> 10#include <unistd.h> 11#include <stdio.h> 12#include <stdbool.h> 13#include <stdarg.h> 14#include <locale.h> 15#include <api/fs/fs.h> 16#include "fncache.h" 17#include "pmu-hybrid.h" 18 19LIST_HEAD(perf_pmu__hybrid_pmus); 20 21bool perf_pmu__hybrid_mounted(const char *name) 22{ 23 char path[PATH_MAX]; 24 const char *sysfs; 25 FILE *file; 26 int n, cpu; 27 28 if (strncmp(name, "cpu_", 4)) 29 return false; 30 31 sysfs = sysfs__mountpoint(); 32 if (!sysfs) 33 return false; 34 35 snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name); 36 if (!file_available(path)) 37 return false; 38 39 file = fopen(path, "r"); 40 if (!file) 41 return false; 42 43 n = fscanf(file, "%u", &cpu); 44 fclose(file); 45 if (n <= 0) 46 return false; 47 48 return true; 49} 50 51struct perf_pmu *perf_pmu__find_hybrid_pmu(const char *name) 52{ 53 struct perf_pmu *pmu; 54 55 if (!name) 56 return NULL; 57 58 perf_pmu__for_each_hybrid_pmu(pmu) { 59 if (!strcmp(name, pmu->name)) 60 return pmu; 61 } 62 63 return NULL; 64} 65 66bool perf_pmu__is_hybrid(const char *name) 67{ 68 return perf_pmu__find_hybrid_pmu(name) != NULL; 69} 70 71char *perf_pmu__hybrid_type_to_pmu(const char *type) 72{ 73 char *pmu_name = NULL; 74 75 if (asprintf(&pmu_name, "cpu_%s", type) < 0) 76 return NULL; 77 78 if (perf_pmu__is_hybrid(pmu_name)) 79 return pmu_name; 80 81 /* 82 * pmu may be not scanned, check the sysfs. 83 */ 84 if (perf_pmu__hybrid_mounted(pmu_name)) 85 return pmu_name; 86 87 free(pmu_name); 88 return NULL; 89}