diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/0067-perf-x86-amd-Add-idle-hooks-for-branch-sampling.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/0067-perf-x86-amd-Add-idle-hooks-for-branch-sampling.patch | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/0067-perf-x86-amd-Add-idle-hooks-for-branch-sampling.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/0067-perf-x86-amd-Add-idle-hooks-for-branch-sampling.patch new file mode 100644 index 00000000..fe0cd084 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/0067-perf-x86-amd-Add-idle-hooks-for-branch-sampling.patch @@ -0,0 +1,153 @@ +From fbc9f8129c3070cebecd797ee9f9facfc238dd1e Mon Sep 17 00:00:00 2001 +From: Stephane Eranian <eranian@google.com> +Date: Tue, 22 Mar 2022 15:15:13 -0700 +Subject: [PATCH 67/86] perf/x86/amd: Add idle hooks for branch sampling + +commit d5616bac7adadbf42a3b63b8717e75eb82a2cc2c upstream + +On AMD Fam19h Zen3, the branch sampling (BRS) feature must be disabled before +entering low power and re-enabled (if was active) when returning from low +power. Otherwise, the NMI interrupt may be held up for too long and cause +problems. Stopping BRS will cause the NMI to be delivered if it was held up. + +Define a perf_amd_brs_lopwr_cb() callback to stop/restart BRS. The callback +is protected by a jump label which is enabled only when AMD BRS is detected. +In all other cases, the callback is never called. + +Signed-off-by: Stephane Eranian <eranian@google.com> +[peterz: static_call() and build fixes] +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Link: https://lore.kernel.org/r/20220322221517.2510440-10-eranian@google.com +Signed-off-by: Zhaolong Zhang <zhaolong.zhang@windriver.com> +--- + arch/x86/events/amd/brs.c | 33 +++++++++++++++++++++++++++++++ + arch/x86/events/amd/core.c | 4 ++++ + arch/x86/events/perf_event.h | 1 + + arch/x86/include/asm/perf_event.h | 23 +++++++++++++++++++++ + 4 files changed, 61 insertions(+) + +diff --git a/arch/x86/events/amd/brs.c b/arch/x86/events/amd/brs.c +index 40461c3ce714..895c82165d85 100644 +--- a/arch/x86/events/amd/brs.c ++++ b/arch/x86/events/amd/brs.c +@@ -7,6 +7,7 @@ + * Contributed by Stephane Eranian <eranian@google.com> + */ + #include <linux/kernel.h> ++#include <linux/jump_label.h> + #include <asm/msr.h> + #include <asm/cpufeature.h> + +@@ -329,3 +330,35 @@ void amd_pmu_brs_sched_task(struct perf_event_context *ctx, bool sched_in) + if (sched_in) + amd_brs_poison_buffer(); + } ++ ++/* ++ * called from ACPI processor_idle.c or acpi_pad.c ++ * with interrupts disabled ++ */ ++void perf_amd_brs_lopwr_cb(bool lopwr_in) ++{ ++ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); ++ union amd_debug_extn_cfg cfg; ++ ++ /* ++ * on mwait in, we may end up in non C0 state. ++ * we must disable branch sampling to avoid holding the NMI ++ * for too long. We disable it in hardware but we ++ * keep the state in cpuc, so we can re-enable. ++ * ++ * The hardware will deliver the NMI if needed when brsmen cleared ++ */ ++ if (cpuc->brs_active) { ++ cfg.val = get_debug_extn_cfg(); ++ cfg.brsmen = !lopwr_in; ++ set_debug_extn_cfg(cfg.val); ++ } ++} ++ ++DEFINE_STATIC_CALL_NULL(perf_lopwr_cb, perf_amd_brs_lopwr_cb); ++EXPORT_STATIC_CALL_TRAMP_GPL(perf_lopwr_cb); ++ ++void __init amd_brs_lopwr_init(void) ++{ ++ static_call_update(perf_lopwr_cb, perf_amd_brs_lopwr_cb); ++} +diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c +index f7bce8364fe4..8e1e818f8195 100644 +--- a/arch/x86/events/amd/core.c ++++ b/arch/x86/events/amd/core.c +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + #include <linux/perf_event.h> ++#include <linux/jump_label.h> + #include <linux/export.h> + #include <linux/types.h> + #include <linux/init.h> +@@ -1225,6 +1226,9 @@ static int __init amd_core_pmu_init(void) + /* + * put_event_constraints callback same as Fam17h, set above + */ ++ ++ /* branch sampling must be stopped when entering low power */ ++ amd_brs_lopwr_init(); + } + + x86_pmu.attr_update = amd_attr_update; +diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h +index e2c4dc114bda..49948372b44a 100644 +--- a/arch/x86/events/perf_event.h ++++ b/arch/x86/events/perf_event.h +@@ -1224,6 +1224,7 @@ void amd_brs_enable(void); + void amd_brs_enable_all(void); + void amd_brs_disable_all(void); + void amd_brs_drain(void); ++void amd_brs_lopwr_init(void); + void amd_brs_disable_all(void); + int amd_brs_setup_filter(struct perf_event *event); + void amd_brs_reset(void); +diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h +index a2b6626c681f..0e72770c45ff 100644 +--- a/arch/x86/include/asm/perf_event.h ++++ b/arch/x86/include/asm/perf_event.h +@@ -2,6 +2,8 @@ + #ifndef _ASM_X86_PERF_EVENT_H + #define _ASM_X86_PERF_EVENT_H + ++#include <linux/static_call.h> ++ + /* + * Performance event hw details: + */ +@@ -518,6 +520,27 @@ static inline void intel_pt_handle_vmx(int on) + #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) + extern void amd_pmu_enable_virt(void); + extern void amd_pmu_disable_virt(void); ++ ++#if defined(CONFIG_PERF_EVENTS_AMD_BRS) ++ ++#define PERF_NEEDS_LOPWR_CB 1 ++ ++/* ++ * architectural low power callback impacts ++ * drivers/acpi/processor_idle.c ++ * drivers/acpi/acpi_pad.c ++ */ ++extern void perf_amd_brs_lopwr_cb(bool lopwr_in); ++ ++DECLARE_STATIC_CALL(perf_lopwr_cb, perf_amd_brs_lopwr_cb); ++ ++static inline void perf_lopwr_cb(bool lopwr_in) ++{ ++ static_call_mod(perf_lopwr_cb)(lopwr_in); ++} ++ ++#endif /* PERF_NEEDS_LOPWR_CB */ ++ + #else + static inline void amd_pmu_enable_virt(void) { } + static inline void amd_pmu_disable_virt(void) { } +-- +2.37.3 + |