0001
0002 #include <stdio.h>
0003 #include <stdlib.h>
0004 #include "util/evsel.h"
0005 #include "util/env.h"
0006 #include "util/pmu.h"
0007 #include "linux/string.h"
0008 #include "evsel.h"
0009 #include "util/debug.h"
0010
0011 #define IBS_FETCH_L3MISSONLY (1ULL << 59)
0012 #define IBS_OP_L3MISSONLY (1ULL << 16)
0013
0014 void arch_evsel__set_sample_weight(struct evsel *evsel)
0015 {
0016 evsel__set_sample_bit(evsel, WEIGHT_STRUCT);
0017 }
0018
0019 void arch_evsel__fixup_new_cycles(struct perf_event_attr *attr)
0020 {
0021 struct perf_env env = { .total_mem = 0, } ;
0022
0023 if (!perf_env__cpuid(&env))
0024 return;
0025
0026
0027
0028
0029
0030
0031
0032
0033 if (env.cpuid && strstarts(env.cpuid, "AuthenticAMD"))
0034 attr->exclude_guest = 0;
0035
0036 free(env.cpuid);
0037 }
0038
0039
0040 bool evsel__sys_has_perf_metrics(const struct evsel *evsel)
0041 {
0042 const char *pmu_name = evsel->pmu_name ? evsel->pmu_name : "cpu";
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 if ((evsel->core.attr.type == PERF_TYPE_RAW) &&
0053 pmu_have_event(pmu_name, "slots"))
0054 return true;
0055
0056 return false;
0057 }
0058
0059 bool arch_evsel__must_be_in_group(const struct evsel *evsel)
0060 {
0061 if (!evsel__sys_has_perf_metrics(evsel))
0062 return false;
0063
0064 return evsel->name &&
0065 (strcasestr(evsel->name, "slots") ||
0066 strcasestr(evsel->name, "topdown"));
0067 }
0068
0069 int arch_evsel__hw_name(struct evsel *evsel, char *bf, size_t size)
0070 {
0071 u64 event = evsel->core.attr.config & PERF_HW_EVENT_MASK;
0072 u64 pmu = evsel->core.attr.config >> PERF_PMU_TYPE_SHIFT;
0073 const char *event_name;
0074
0075 if (event < PERF_COUNT_HW_MAX && evsel__hw_names[event])
0076 event_name = evsel__hw_names[event];
0077 else
0078 event_name = "unknown-hardware";
0079
0080
0081 if (!pmu)
0082 return scnprintf(bf, size, "%s", event_name);
0083
0084 return scnprintf(bf, size, "%s/%s/",
0085 evsel->pmu_name ? evsel->pmu_name : "cpu",
0086 event_name);
0087 }
0088
0089 static void ibs_l3miss_warn(void)
0090 {
0091 pr_warning(
0092 "WARNING: Hw internally resets sampling period when L3 Miss Filtering is enabled\n"
0093 "and tagged operation does not cause L3 Miss. This causes sampling period skew.\n");
0094 }
0095
0096 void arch__post_evsel_config(struct evsel *evsel, struct perf_event_attr *attr)
0097 {
0098 struct perf_pmu *evsel_pmu, *ibs_fetch_pmu, *ibs_op_pmu;
0099 static int warned_once;
0100
0101 static int is_amd;
0102
0103 if (warned_once || is_amd == -1)
0104 return;
0105
0106 if (!is_amd) {
0107 struct perf_env *env = evsel__env(evsel);
0108
0109 if (!perf_env__cpuid(env) || !env->cpuid ||
0110 !strstarts(env->cpuid, "AuthenticAMD")) {
0111 is_amd = -1;
0112 return;
0113 }
0114 is_amd = 1;
0115 }
0116
0117 evsel_pmu = evsel__find_pmu(evsel);
0118 if (!evsel_pmu)
0119 return;
0120
0121 ibs_fetch_pmu = perf_pmu__find("ibs_fetch");
0122 ibs_op_pmu = perf_pmu__find("ibs_op");
0123
0124 if (ibs_fetch_pmu && ibs_fetch_pmu->type == evsel_pmu->type) {
0125 if (attr->config & IBS_FETCH_L3MISSONLY) {
0126 ibs_l3miss_warn();
0127 warned_once = 1;
0128 }
0129 } else if (ibs_op_pmu && ibs_op_pmu->type == evsel_pmu->type) {
0130 if (attr->config & IBS_OP_L3MISSONLY) {
0131 ibs_l3miss_warn();
0132 warned_once = 1;
0133 }
0134 }
0135 }