diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2016-12-22 05:02:08 -0500 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2016-12-25 04:47:40 -0500 |
| commit | 834fcd298003c10ce450e66960c78893cb1cc4b5 (patch) | |
| tree | dff2a6b96422f400423424f3d2f9f2d878f8a1dc | |
| parent | a051f220d6b9bf9367695e2c319ccc3712b631ee (diff) | |
perf/x86/intel/cstate: Prevent hotplug callback leak
If the pmu registration fails the registered hotplug callbacks are not
removed. Wrong in any case, but fatal in case of a modular driver.
Replace the nonsensical state names with proper ones while at it.
Fixes: 77c34ef1c319 ("perf/x86/intel/cstate: Convert Intel CSTATE to hotplug state machine")
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: stable@vger.kernel.org
| -rw-r--r-- | arch/x86/events/intel/cstate.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index da51e5a3e2ff..fec8a461bdef 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c | |||
| @@ -594,6 +594,9 @@ static int __init cstate_probe(const struct cstate_model *cm) | |||
| 594 | 594 | ||
| 595 | static inline void cstate_cleanup(void) | 595 | static inline void cstate_cleanup(void) |
| 596 | { | 596 | { |
| 597 | cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_ONLINE); | ||
| 598 | cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_STARTING); | ||
| 599 | |||
| 597 | if (has_cstate_core) | 600 | if (has_cstate_core) |
| 598 | perf_pmu_unregister(&cstate_core_pmu); | 601 | perf_pmu_unregister(&cstate_core_pmu); |
| 599 | 602 | ||
| @@ -606,16 +609,16 @@ static int __init cstate_init(void) | |||
| 606 | int err; | 609 | int err; |
| 607 | 610 | ||
| 608 | cpuhp_setup_state(CPUHP_AP_PERF_X86_CSTATE_STARTING, | 611 | cpuhp_setup_state(CPUHP_AP_PERF_X86_CSTATE_STARTING, |
| 609 | "AP_PERF_X86_CSTATE_STARTING", cstate_cpu_init, | 612 | "perf/x86/cstate:starting", cstate_cpu_init, NULL); |
| 610 | NULL); | ||
| 611 | cpuhp_setup_state(CPUHP_AP_PERF_X86_CSTATE_ONLINE, | 613 | cpuhp_setup_state(CPUHP_AP_PERF_X86_CSTATE_ONLINE, |
| 612 | "AP_PERF_X86_CSTATE_ONLINE", NULL, cstate_cpu_exit); | 614 | "perf/x86/cstate:online", NULL, cstate_cpu_exit); |
| 613 | 615 | ||
| 614 | if (has_cstate_core) { | 616 | if (has_cstate_core) { |
| 615 | err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1); | 617 | err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1); |
| 616 | if (err) { | 618 | if (err) { |
| 617 | has_cstate_core = false; | 619 | has_cstate_core = false; |
| 618 | pr_info("Failed to register cstate core pmu\n"); | 620 | pr_info("Failed to register cstate core pmu\n"); |
| 621 | cstate_cleanup(); | ||
| 619 | return err; | 622 | return err; |
| 620 | } | 623 | } |
| 621 | } | 624 | } |
| @@ -629,8 +632,7 @@ static int __init cstate_init(void) | |||
| 629 | return err; | 632 | return err; |
| 630 | } | 633 | } |
| 631 | } | 634 | } |
| 632 | 635 | return 0; | |
| 633 | return err; | ||
| 634 | } | 636 | } |
| 635 | 637 | ||
| 636 | static int __init cstate_pmu_init(void) | 638 | static int __init cstate_pmu_init(void) |
| @@ -655,8 +657,6 @@ module_init(cstate_pmu_init); | |||
| 655 | 657 | ||
| 656 | static void __exit cstate_pmu_exit(void) | 658 | static void __exit cstate_pmu_exit(void) |
| 657 | { | 659 | { |
| 658 | cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_ONLINE); | ||
| 659 | cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_STARTING); | ||
| 660 | cstate_cleanup(); | 660 | cstate_cleanup(); |
| 661 | } | 661 | } |
| 662 | module_exit(cstate_pmu_exit); | 662 | module_exit(cstate_pmu_exit); |
