aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2022-03-22 15:15:10 -0700
committerXie Haocheng <haocheng.xie@amd.com>2022-09-20 17:53:44 +0800
commita6e05fc17ad3c4467b92a379aa49a06402edab54 (patch)
tree601b524c02414602181a569a2e63c3cda56a2427
parentfbeacba301033893999d486eef91d22395810ae7 (diff)
downloadopenEuler-kernel-a6e05fc17ad3c4467b92a379aa49a06402edab54.tar.gz
perf/x86/amd: Add AMD branch sampling period adjustment
mainline inclusion from mainline-v5.19 commit ba2fe7500845a30fc845a72081999cf632051862 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I5S3WV CVE: NA ------------------------------------------------- Add code to adjust the sampling event period when used with the Branch Sampling feature (BRS). Given the depth of the BRS (16), the period is reduced by that depth such that in the best case scenario, BRS saturates at the desired sampling period. In practice, though, the processor may execute more branches. Given a desired period P and a depth D, the kernel programs the actual period at P - D. After P occurrences of the sampling event, the counter overflows. It then may take X branches (skid) before the NMI is caught and held by the hardware and BRS activates. Then, after D branches, BRS saturates and the NMI is delivered. With no skid, the effective period would be (P - D) + D = P. In practice, however, it will likely be (P - D) + X + D. There is no way to eliminate X or predict X. Signed-off-by: Stephane Eranian <eranian@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220322221517.2510440-7-eranian@google.com Signed-off-by: Xie Haocheng <haocheng.xie@amd.com>
-rw-r--r--arch/x86/events/core.c7
-rw-r--r--arch/x86/events/perf_event.h12
2 files changed, 19 insertions, 0 deletions
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 14f545fdfc6b48..648a92e6d013cf 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1333,6 +1333,13 @@ int x86_perf_event_set_period(struct perf_event *event)
return x86_pmu.set_topdown_event_period(event);
/*
+ * decrease period by the depth of the BRS feature to get
+ * the last N taken branches and approximate the desired period
+ */
+ if (has_branch_stack(event))
+ period = amd_brs_adjust_period(period);
+
+ /*
* If we are way outside a reasonable range then just skip forward:
*/
if (unlikely(left <= -period)) {
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index f3bae299863265..fc06b2332d6d32 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -1134,6 +1134,14 @@ static inline bool amd_brs_active(void)
return cpuc->brs_active;
}
+static inline s64 amd_brs_adjust_period(s64 period)
+{
+ if (period > x86_pmu.lbr_nr)
+ return period - x86_pmu.lbr_nr;
+
+ return period;
+}
+
#else /* CONFIG_CPU_SUP_AMD */
static inline int amd_pmu_init(void)
@@ -1158,6 +1166,10 @@ static inline void amd_brs_disable_all(void)
{
}
+static inline s64 amd_brs_adjust_period(s64 period)
+{
+ return period;
+}
#endif /* CONFIG_CPU_SUP_AMD */
static inline int is_pebs_pt(struct perf_event *event)