Home Home > GIT Browse > stable
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2019-02-12 22:18:26 +0100
committerJiri Slaby <jslaby@suse.cz>2019-02-12 22:21:30 +0100
commitdc63ddf5cca3d5e754afe82a198314d64b9d1e1d (patch)
tree5b6d7aaf94de8de1d87b09dd718dd88647df7503
parent8f87c73ec8b9927571c3147473e5a1e125ab78c2 (diff)
perf/x86/intel: Delay memory deallocation until
x86_pmu_dead_cpu() (bnc#1012628).
-rw-r--r--patches.kernel.org/4.20.8-335-perf-x86-intel-Delay-memory-deallocation-until.patch113
-rw-r--r--series.conf1
2 files changed, 114 insertions, 0 deletions
diff --git a/patches.kernel.org/4.20.8-335-perf-x86-intel-Delay-memory-deallocation-until.patch b/patches.kernel.org/4.20.8-335-perf-x86-intel-Delay-memory-deallocation-until.patch
new file mode 100644
index 0000000000..232b8b3ab7
--- /dev/null
+++ b/patches.kernel.org/4.20.8-335-perf-x86-intel-Delay-memory-deallocation-until.patch
@@ -0,0 +1,113 @@
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Wed, 19 Dec 2018 17:53:50 +0100
+Subject: [PATCH] perf/x86/intel: Delay memory deallocation until
+ x86_pmu_dead_cpu()
+References: bnc#1012628
+Patch-mainline: 4.20.8
+Git-commit: 602cae04c4864bb3487dfe4c2126c8d9e7e1614a
+
+commit 602cae04c4864bb3487dfe4c2126c8d9e7e1614a upstream.
+
+intel_pmu_cpu_prepare() allocated memory for ->shared_regs among other
+members of struct cpu_hw_events. This memory is released in
+intel_pmu_cpu_dying() which is wrong. The counterpart of the
+intel_pmu_cpu_prepare() callback is x86_pmu_dead_cpu().
+
+Otherwise if the CPU fails on the UP path between CPUHP_PERF_X86_PREPARE
+and CPUHP_AP_PERF_X86_STARTING then it won't release the memory but
+allocate new memory on the next attempt to online the CPU (leaking the
+old memory).
+Also, if the CPU down path fails between CPUHP_AP_PERF_X86_STARTING and
+CPUHP_PERF_X86_PREPARE then the CPU will go back online but never
+allocate the memory that was released in x86_pmu_dying_cpu().
+
+Make the memory allocation/free symmetrical in regard to the CPU hotplug
+notifier by moving the deallocation to intel_pmu_cpu_dead().
+
+This started in commit:
+
+ a7e3ed1e47011 ("perf: Add support for supplementary event registers").
+
+In principle the bug was introduced in v2.6.39 (!), but it will almost
+certainly not backport cleanly across the big CPU hotplug rewrite between v4.7-v4.15...
+
+[ bigeasy: Added patch description. ]
+[ mingo: Added backporting guidance. ]
+
+Reported-by: He Zhe <zhe.he@windriver.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> # With developer hat on
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> # With maintainer hat on
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: acme@kernel.org
+Cc: bp@alien8.de
+Cc: hpa@zytor.com
+Cc: jolsa@kernel.org
+Cc: kan.liang@linux.intel.com
+Cc: namhyung@kernel.org
+Cc: <stable@vger.kernel.org>
+Fixes: a7e3ed1e47011 ("perf: Add support for supplementary event registers").
+Link: https://lkml.kernel.org/r/20181219165350.6s3jvyxbibpvlhtq@linutronix.de
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/events/intel/core.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
+index ecc3e34ca955..90b6718ff861 100644
+--- a/arch/x86/events/intel/core.c
++++ b/arch/x86/events/intel/core.c
+@@ -3558,6 +3558,14 @@ static void free_excl_cntrs(int cpu)
+ }
+
+ static void intel_pmu_cpu_dying(int cpu)
++{
++ fini_debug_store_on_cpu(cpu);
++
++ if (x86_pmu.counter_freezing)
++ disable_counter_freeze();
++}
++
++static void intel_pmu_cpu_dead(int cpu)
+ {
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+ struct intel_shared_regs *pc;
+@@ -3570,11 +3578,6 @@ static void intel_pmu_cpu_dying(int cpu)
+ }
+
+ free_excl_cntrs(cpu);
+-
+- fini_debug_store_on_cpu(cpu);
+-
+- if (x86_pmu.counter_freezing)
+- disable_counter_freeze();
+ }
+
+ static void intel_pmu_sched_task(struct perf_event_context *ctx,
+@@ -3663,6 +3666,7 @@ static __initconst const struct x86_pmu core_pmu = {
+ .cpu_prepare = intel_pmu_cpu_prepare,
+ .cpu_starting = intel_pmu_cpu_starting,
+ .cpu_dying = intel_pmu_cpu_dying,
++ .cpu_dead = intel_pmu_cpu_dead,
+ };
+
+ static struct attribute *intel_pmu_attrs[];
+@@ -3703,6 +3707,8 @@ static __initconst const struct x86_pmu intel_pmu = {
+ .cpu_prepare = intel_pmu_cpu_prepare,
+ .cpu_starting = intel_pmu_cpu_starting,
+ .cpu_dying = intel_pmu_cpu_dying,
++ .cpu_dead = intel_pmu_cpu_dead,
++
+ .guest_get_msrs = intel_guest_get_msrs,
+ .sched_task = intel_pmu_sched_task,
+ };
+--
+2.20.1
+
diff --git a/series.conf b/series.conf
index fbe8595143..a552f32d9f 100644
--- a/series.conf
+++ b/series.conf
@@ -1071,6 +1071,7 @@
patches.kernel.org/4.20.8-332-KVM-nVMX-unconditionally-cancel-preemption-tim.patch
patches.kernel.org/4.20.8-333-cpu-hotplug-Fix-SMT-disabled-by-BIOS-detection.patch
patches.kernel.org/4.20.8-334-perf-x86-intel-uncore-Add-Node-ID-mask.patch
+ patches.kernel.org/4.20.8-335-perf-x86-intel-Delay-memory-deallocation-until.patch
########################################################
# Build fixes that apply to the vanilla kernel too.