1 // SPDX-License-Identifier: GPL-2.0 2 #include <stdio.h> 3 #include "api/fs/fs.h" 4 #include "util/pmu.h" 5 #include "util/topdown.h" 6 #include "topdown.h" 7 8 /* Check whether there is a PMU which supports the perf metrics. */ 9 bool topdown_sys_has_perf_metrics(void) 10 { 11 static bool has_perf_metrics; 12 static bool cached; 13 struct perf_pmu *pmu; 14 15 if (cached) 16 return has_perf_metrics; 17 18 /* 19 * The perf metrics feature is a core PMU feature. 20 * The PERF_TYPE_RAW type is the type of a core PMU. 21 * The slots event is only available when the core PMU 22 * supports the perf metrics feature. 23 */ 24 pmu = perf_pmu__find_by_type(PERF_TYPE_RAW); 25 if (pmu && pmu_have_event(pmu->name, "slots")) 26 has_perf_metrics = true; 27 28 cached = true; 29 return has_perf_metrics; 30 } 31 32 /* 33 * Check whether we can use a group for top down. 34 * Without a group may get bad results due to multiplexing. 35 */ 36 bool arch_topdown_check_group(bool *warn) 37 { 38 int n; 39 40 if (sysctl__read_int("kernel/nmi_watchdog", &n) < 0) 41 return false; 42 if (n > 0) { 43 *warn = true; 44 return false; 45 } 46 return true; 47 } 48 49 void arch_topdown_group_warn(void) 50 { 51 fprintf(stderr, 52 "nmi_watchdog enabled with topdown. May give wrong results.\n" 53 "Disable with echo 0 > /proc/sys/kernel/nmi_watchdog\n"); 54 } 55 56 #define TOPDOWN_SLOTS 0x0400 57 58 static bool is_topdown_slots_event(struct evsel *counter) 59 { 60 if (!counter->pmu_name) 61 return false; 62 63 if (strcmp(counter->pmu_name, "cpu")) 64 return false; 65 66 if (counter->core.attr.config == TOPDOWN_SLOTS) 67 return true; 68 69 return false; 70 } 71 72 /* 73 * Check whether a topdown group supports sample-read. 74 * 75 * Only Topdown metic supports sample-read. The slots 76 * event must be the leader of the topdown group. 77 */ 78 79 bool arch_topdown_sample_read(struct evsel *leader) 80 { 81 if (!pmu_have_event("cpu", "slots")) 82 return false; 83 84 if (is_topdown_slots_event(leader)) 85 return true; 86 87 return false; 88 } 89