Skip to content

Commit 9ee68b3

Browse files
cdleonardwilldeacon
authored andcommitted
perf/imx_ddr: Fix cpu hotplug state cleanup
This driver allocates a dynamic cpu hotplug state but never releases it. If reloaded in a loop it will quickly trigger a WARN message: "No more dynamic states available for CPU hotplug" Fix by calling cpuhp_remove_multi_state on remove like several other perf pmu drivers. Also fix the cleanup logic on probe error paths: add the missing cpuhp_remove_multi_state call and properly check the return value from cpuhp_state_add_instant_nocalls. Fixes: 9a66d36 ("drivers/perf: imx_ddr: Add DDR performance counter support to perf") Acked-by: Joakim Zhang <[email protected]> Signed-off-by: Leonard Crestez <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent 73daf0b commit 9ee68b3

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

drivers/perf/fsl_imx8_ddr_perf.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -633,13 +633,17 @@ static int ddr_perf_probe(struct platform_device *pdev)
633633

634634
if (ret < 0) {
635635
dev_err(&pdev->dev, "cpuhp_setup_state_multi failed\n");
636-
goto ddr_perf_err;
636+
goto cpuhp_state_err;
637637
}
638638

639639
pmu->cpuhp_state = ret;
640640

641641
/* Register the pmu instance for cpu hotplug */
642-
cpuhp_state_add_instance_nocalls(pmu->cpuhp_state, &pmu->node);
642+
ret = cpuhp_state_add_instance_nocalls(pmu->cpuhp_state, &pmu->node);
643+
if (ret) {
644+
dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
645+
goto cpuhp_instance_err;
646+
}
643647

644648
/* Request irq */
645649
irq = of_irq_get(np, 0);
@@ -673,9 +677,10 @@ static int ddr_perf_probe(struct platform_device *pdev)
673677
return 0;
674678

675679
ddr_perf_err:
676-
if (pmu->cpuhp_state)
677-
cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node);
678-
680+
cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node);
681+
cpuhp_instance_err:
682+
cpuhp_remove_multi_state(pmu->cpuhp_state);
683+
cpuhp_state_err:
679684
ida_simple_remove(&ddr_ida, pmu->id);
680685
dev_warn(&pdev->dev, "i.MX8 DDR Perf PMU failed (%d), disabled\n", ret);
681686
return ret;
@@ -686,6 +691,7 @@ static int ddr_perf_remove(struct platform_device *pdev)
686691
struct ddr_pmu *pmu = platform_get_drvdata(pdev);
687692

688693
cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node);
694+
cpuhp_remove_multi_state(pmu->cpuhp_state);
689695
irq_set_affinity_hint(pmu->irq, NULL);
690696

691697
perf_pmu_unregister(&pmu->pmu);

0 commit comments

Comments
 (0)