Skip to content

Commit 68fa55f

Browse files
Bharat Bhushanwilldeacon
authored andcommitted
perf/marvell: cn10k DDR perf event core ownership
As DDR perf event counters are not per core, so they should be accessed only by one core at a time. Select new core when previously owning core is going offline. Signed-off-by: Bharat Bhushan <bbhushan2@marvell.com> Reviewed-by: Bhaskara Budiredla <bbudiredla@marvell.com> Link: https://lore.kernel.org/r/20220211045346.17894-5-bbhushan2@marvell.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent 35a4332 commit 68fa55f

3 files changed

Lines changed: 56 additions & 2 deletions

File tree

drivers/perf/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,11 @@ config MARVELL_CN10K_TAD_PMU
148148

149149
source "drivers/perf/hisilicon/Kconfig"
150150

151+
config MARVELL_CN10K_DDR_PMU
152+
tristate "Enable MARVELL CN10K DRAM Subsystem(DSS) PMU Support"
153+
depends on ARM64 || (COMPILE_TEST && 64BIT)
154+
help
155+
Enable perf support for Marvell DDR Performance monitoring
156+
event on CN10K platform.
157+
151158
endmenu

drivers/perf/marvell_cn10k_ddr_pmu.c

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ struct cn10k_ddr_pmu {
129129
int active_events;
130130
struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
131131
struct hrtimer hrtimer;
132+
struct hlist_node node;
132133
};
133134

134135
#define to_cn10k_ddr_pmu(p) container_of(p, struct cn10k_ddr_pmu, pmu)
@@ -610,6 +611,24 @@ static enum hrtimer_restart cn10k_ddr_pmu_timer_handler(struct hrtimer *hrtimer)
610611
return HRTIMER_RESTART;
611612
}
612613

614+
static int cn10k_ddr_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
615+
{
616+
struct cn10k_ddr_pmu *pmu = hlist_entry_safe(node, struct cn10k_ddr_pmu,
617+
node);
618+
unsigned int target;
619+
620+
if (cpu != pmu->cpu)
621+
return 0;
622+
623+
target = cpumask_any_but(cpu_online_mask, cpu);
624+
if (target >= nr_cpu_ids)
625+
return 0;
626+
627+
perf_pmu_migrate_context(&pmu->pmu, cpu, target);
628+
pmu->cpu = target;
629+
return 0;
630+
}
631+
613632
static int cn10k_ddr_perf_probe(struct platform_device *pdev)
614633
{
615634
struct cn10k_ddr_pmu *ddr_pmu;
@@ -661,18 +680,31 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
661680
hrtimer_init(&ddr_pmu->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
662681
ddr_pmu->hrtimer.function = cn10k_ddr_pmu_timer_handler;
663682

683+
cpuhp_state_add_instance_nocalls(
684+
CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
685+
&ddr_pmu->node);
686+
664687
ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
665688
if (ret)
666-
return ret;
689+
goto error;
667690

668691
pr_info("CN10K DDR PMU Driver for ddrc@%llx\n", res->start);
669692
return 0;
693+
error:
694+
cpuhp_state_remove_instance_nocalls(
695+
CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
696+
&ddr_pmu->node);
697+
return ret;
670698
}
671699

672700
static int cn10k_ddr_perf_remove(struct platform_device *pdev)
673701
{
674702
struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
675703

704+
cpuhp_state_remove_instance_nocalls(
705+
CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
706+
&ddr_pmu->node);
707+
676708
perf_pmu_unregister(&ddr_pmu->pmu);
677709
return 0;
678710
}
@@ -697,12 +729,26 @@ static struct platform_driver cn10k_ddr_pmu_driver = {
697729

698730
static int __init cn10k_ddr_pmu_init(void)
699731
{
700-
return platform_driver_register(&cn10k_ddr_pmu_driver);
732+
int ret;
733+
734+
ret = cpuhp_setup_state_multi(
735+
CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
736+
"perf/marvell/cn10k/ddr:online", NULL,
737+
cn10k_ddr_pmu_offline_cpu);
738+
if (ret)
739+
return ret;
740+
741+
ret = platform_driver_register(&cn10k_ddr_pmu_driver);
742+
if (ret)
743+
cpuhp_remove_multi_state(
744+
CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE);
745+
return ret;
701746
}
702747

703748
static void __exit cn10k_ddr_pmu_exit(void)
704749
{
705750
platform_driver_unregister(&cn10k_ddr_pmu_driver);
751+
cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE);
706752
}
707753

708754
module_init(cn10k_ddr_pmu_init);

include/linux/cpuhotplug.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ enum cpuhp_state {
231231
CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
232232
CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE,
233233
CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE,
234+
CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
234235
CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
235236
CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
236237
CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,

0 commit comments

Comments
 (0)