1 // SPDX-License-Identifier: GPL-2.0
4 #include "util/evsel.h"
8 #include "linux/string.h"
11 #include "util/debug.h"
14 #define IBS_FETCH_L3MISSONLY (1ULL << 59)
15 #define IBS_OP_L3MISSONLY (1ULL << 16)
17 void arch_evsel__set_sample_weight(struct evsel
*evsel
)
19 evsel__set_sample_bit(evsel
, WEIGHT_STRUCT
);
22 /* Check whether the evsel's PMU supports the perf metrics */
23 bool evsel__sys_has_perf_metrics(const struct evsel
*evsel
)
26 u32 type
= evsel
->core
.attr
.type
;
29 * The PERF_TYPE_RAW type is the core PMU type, e.g., "cpu" PMU
30 * on a non-hybrid machine, "cpu_core" PMU on a hybrid machine.
31 * The slots event is only available for the core PMU, which
32 * supports the perf metrics feature.
33 * Checking both the PERF_TYPE_RAW type and the slots event
34 * should be good enough to detect the perf metrics feature.
38 case PERF_TYPE_HARDWARE
:
39 case PERF_TYPE_HW_CACHE
:
40 type
= evsel
->core
.attr
.config
>> PERF_PMU_TYPE_SHIFT
;
51 if (pmu
&& perf_pmu__is_fake(pmu
))
55 while ((pmu
= perf_pmus__scan_core(pmu
)) != NULL
) {
56 if (pmu
->type
== PERF_TYPE_RAW
)
60 return pmu
&& perf_pmu__have_event(pmu
, "slots");
63 bool arch_evsel__must_be_in_group(const struct evsel
*evsel
)
65 if (!evsel__sys_has_perf_metrics(evsel
) || !evsel
->name
||
66 strcasestr(evsel
->name
, "uops_retired.slots"))
69 return arch_is_topdown_metrics(evsel
) || arch_is_topdown_slots(evsel
);
72 int arch_evsel__hw_name(struct evsel
*evsel
, char *bf
, size_t size
)
74 u64 event
= evsel
->core
.attr
.config
& PERF_HW_EVENT_MASK
;
75 u64 pmu
= evsel
->core
.attr
.config
>> PERF_PMU_TYPE_SHIFT
;
76 const char *event_name
;
78 if (event
< PERF_COUNT_HW_MAX
&& evsel__hw_names
[event
])
79 event_name
= evsel__hw_names
[event
];
81 event_name
= "unknown-hardware";
83 /* The PMU type is not required for the non-hybrid platform. */
85 return scnprintf(bf
, size
, "%s", event_name
);
87 return scnprintf(bf
, size
, "%s/%s/",
88 evsel
->pmu
? evsel
->pmu
->name
: "cpu",
92 static void ibs_l3miss_warn(void)
95 "WARNING: Hw internally resets sampling period when L3 Miss Filtering is enabled\n"
96 "and tagged operation does not cause L3 Miss. This causes sampling period skew.\n");
99 void arch__post_evsel_config(struct evsel
*evsel
, struct perf_event_attr
*attr
)
101 struct perf_pmu
*evsel_pmu
, *ibs_fetch_pmu
, *ibs_op_pmu
;
102 static int warned_once
;
104 if (warned_once
|| !x86__is_amd_cpu())
107 evsel_pmu
= evsel__find_pmu(evsel
);
111 ibs_fetch_pmu
= perf_pmus__find("ibs_fetch");
112 ibs_op_pmu
= perf_pmus__find("ibs_op");
114 if (ibs_fetch_pmu
&& ibs_fetch_pmu
->type
== evsel_pmu
->type
) {
115 if (attr
->config
& IBS_FETCH_L3MISSONLY
) {
119 } else if (ibs_op_pmu
&& ibs_op_pmu
->type
== evsel_pmu
->type
) {
120 if (attr
->config
& IBS_OP_L3MISSONLY
) {
127 int arch_evsel__open_strerror(struct evsel
*evsel
, char *msg
, size_t size
)
129 if (!x86__is_amd_cpu())
132 if (!evsel
->core
.attr
.precise_ip
&&
133 !(evsel
->pmu
&& !strncmp(evsel
->pmu
->name
, "ibs", 3)))
136 /* More verbose IBS errors. */
137 if (evsel
->core
.attr
.exclude_kernel
|| evsel
->core
.attr
.exclude_user
||
138 evsel
->core
.attr
.exclude_hv
|| evsel
->core
.attr
.exclude_idle
||
139 evsel
->core
.attr
.exclude_host
|| evsel
->core
.attr
.exclude_guest
) {
140 return scnprintf(msg
, size
, "AMD IBS doesn't support privilege filtering. Try "
141 "again without the privilege modifiers (like 'k') at the end.");