From bccd6d62e7e4906ad7ef07492b89382895b1b516 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 11 Feb 2019 15:19:41 +0100 Subject: [PATCH] 4.19-stable patches added patches: perf-x86-intel-delay-memory-deallocation-until-x86_pmu_dead_cpu.patch --- ...-deallocation-until-x86_pmu_dead_cpu.patch | 104 ++++++++++++++++++ queue-4.19/series | 1 + 2 files changed, 105 insertions(+) create mode 100644 queue-4.19/perf-x86-intel-delay-memory-deallocation-until-x86_pmu_dead_cpu.patch diff --git a/queue-4.19/perf-x86-intel-delay-memory-deallocation-until-x86_pmu_dead_cpu.patch b/queue-4.19/perf-x86-intel-delay-memory-deallocation-until-x86_pmu_dead_cpu.patch new file mode 100644 index 00000000000..c1c0c6a3f4a --- /dev/null +++ b/queue-4.19/perf-x86-intel-delay-memory-deallocation-until-x86_pmu_dead_cpu.patch @@ -0,0 +1,104 @@ +From 602cae04c4864bb3487dfe4c2126c8d9e7e1614a Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Wed, 19 Dec 2018 17:53:50 +0100 +Subject: perf/x86/intel: Delay memory deallocation until x86_pmu_dead_cpu() + +From: Peter Zijlstra + +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 +Signed-off-by: Peter Zijlstra (Intel) # With developer hat on +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Peter Zijlstra (Intel) # With maintainer hat on +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +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: +Fixes: a7e3ed1e47011 ("perf: Add support for supplementary event registers"). +Link: https://lkml.kernel.org/r/20181219165350.6s3jvyxbibpvlhtq@linutronix.de +Signed-off-by: Ingo Molnar +[ He Zhe: Fixes conflict caused by missing disable_counter_freeze which is + introduced since v4.20 af3bdb991a5cb. ] +Signed-off-by: He Zhe +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/events/intel/core.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3440,6 +3440,11 @@ static void free_excl_cntrs(int cpu) + + static void intel_pmu_cpu_dying(int cpu) + { ++ fini_debug_store_on_cpu(cpu); ++} ++ ++static void intel_pmu_cpu_dead(int cpu) ++{ + struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); + struct intel_shared_regs *pc; + +@@ -3451,8 +3456,6 @@ static void intel_pmu_cpu_dying(int cpu) + } + + free_excl_cntrs(cpu); +- +- fini_debug_store_on_cpu(cpu); + } + + static void intel_pmu_sched_task(struct perf_event_context *ctx, +@@ -3541,6 +3544,7 @@ static __initconst const struct x86_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[]; +@@ -3581,6 +3585,8 @@ static __initconst const struct x86_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, + }; diff --git a/queue-4.19/series b/queue-4.19/series index d2c85caa9e4..1a0433999a0 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -310,3 +310,4 @@ serial-8250_pci-make-pci-class-test-non-fatal.patch serial-sh-sci-do-not-free-irqs-that-have-already-been-freed.patch cacheinfo-keep-the-old-value-if-of_property_read_u32-fails.patch ib-hfi1-add-limit-test-for-rc-uc-send-via-loopback.patch +perf-x86-intel-delay-memory-deallocation-until-x86_pmu_dead_cpu.patch -- 2.47.2