1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <internal/cpumap.h> 4 #include "../../../util/cpumap.h" 5 #include "../../../util/pmu.h" 6 #include <api/fs/fs.h> 7 #include <math.h> 8 9 static struct perf_pmu *pmu__find_core_pmu(void) 10 { 11 struct perf_pmu *pmu = NULL; 12 13 while ((pmu = perf_pmu__scan(pmu))) { 14 if (!is_pmu_core(pmu->name)) 15 continue; 16 17 /* 18 * The cpumap should cover all CPUs. Otherwise, some CPUs may 19 * not support some events or have different event IDs. 20 */ 21 if (pmu->cpus->nr != cpu__max_cpu().cpu) 22 return NULL; 23 24 return pmu; 25 } 26 27 return NULL; 28 } 29 30 const struct pmu_events_table *pmu_events_table__find(void) 31 { 32 struct perf_pmu *pmu = pmu__find_core_pmu(); 33 34 if (pmu) 35 return perf_pmu__find_table(pmu); 36 37 return NULL; 38 } 39 40 double perf_pmu__cpu_slots_per_cycle(void) 41 { 42 char path[PATH_MAX]; 43 unsigned long long slots = 0; 44 struct perf_pmu *pmu = pmu__find_core_pmu(); 45 46 if (pmu) { 47 perf_pmu__pathname_scnprintf(path, sizeof(path), 48 pmu->name, "caps/slots"); 49 /* 50 * The value of slots is not greater than 32 bits, but sysfs__read_int 51 * can't read value with 0x prefix, so use sysfs__read_ull instead. 52 */ 53 sysfs__read_ull(path, &slots); 54 } 55 56 return slots ? (double)slots : NAN; 57 } 58