diff options
author | Peter Zijlstra <peterz@infradead.org> | 2015-08-10 08:17:34 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-08-12 05:37:22 -0400 |
commit | dbc72b7a0c673ff00fdeb21d3a26064e2185baf4 (patch) | |
tree | 7dc5bf5f492b24fe6eecb7058292fa1eb532e00e | |
parent | c7999c6f3fed9e383d3131474588f282ae6d56b9 (diff) |
perf/x86/intel: Fix memory leak on hot-plug allocation fail
We fail to free the shared_regs allocation if the constraint_list
allocation fails.
Cure this and be more consistent in NULL-ing the pointers after free.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index b9826a981fb2..6326ae24e4d5 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -2534,7 +2534,7 @@ static int intel_pmu_cpu_prepare(int cpu) | |||
2534 | if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) { | 2534 | if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) { |
2535 | cpuc->shared_regs = allocate_shared_regs(cpu); | 2535 | cpuc->shared_regs = allocate_shared_regs(cpu); |
2536 | if (!cpuc->shared_regs) | 2536 | if (!cpuc->shared_regs) |
2537 | return NOTIFY_BAD; | 2537 | goto err; |
2538 | } | 2538 | } |
2539 | 2539 | ||
2540 | if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { | 2540 | if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { |
@@ -2542,18 +2542,27 @@ static int intel_pmu_cpu_prepare(int cpu) | |||
2542 | 2542 | ||
2543 | cpuc->constraint_list = kzalloc(sz, GFP_KERNEL); | 2543 | cpuc->constraint_list = kzalloc(sz, GFP_KERNEL); |
2544 | if (!cpuc->constraint_list) | 2544 | if (!cpuc->constraint_list) |
2545 | return NOTIFY_BAD; | 2545 | goto err_shared_regs; |
2546 | 2546 | ||
2547 | cpuc->excl_cntrs = allocate_excl_cntrs(cpu); | 2547 | cpuc->excl_cntrs = allocate_excl_cntrs(cpu); |
2548 | if (!cpuc->excl_cntrs) { | 2548 | if (!cpuc->excl_cntrs) |
2549 | kfree(cpuc->constraint_list); | 2549 | goto err_constraint_list; |
2550 | kfree(cpuc->shared_regs); | 2550 | |
2551 | return NOTIFY_BAD; | ||
2552 | } | ||
2553 | cpuc->excl_thread_id = 0; | 2551 | cpuc->excl_thread_id = 0; |
2554 | } | 2552 | } |
2555 | 2553 | ||
2556 | return NOTIFY_OK; | 2554 | return NOTIFY_OK; |
2555 | |||
2556 | err_constraint_list: | ||
2557 | kfree(cpuc->constraint_list); | ||
2558 | cpuc->constraint_list = NULL; | ||
2559 | |||
2560 | err_shared_regs: | ||
2561 | kfree(cpuc->shared_regs); | ||
2562 | cpuc->shared_regs = NULL; | ||
2563 | |||
2564 | err: | ||
2565 | return NOTIFY_BAD; | ||
2557 | } | 2566 | } |
2558 | 2567 | ||
2559 | static void intel_pmu_cpu_starting(int cpu) | 2568 | static void intel_pmu_cpu_starting(int cpu) |