From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jeremy Linton Subject: [PATCH 5/8] arm: arm64: pmu: Assign platform PMU CPU affinity Date: Thu, 9 Jun 2016 17:23:30 -0500 Message-ID: <1465511013-10742-6-git-send-email-jeremy.linton@arm.com> References: <1465511013-10742-1-git-send-email-jeremy.linton@arm.com> Return-path: Received: from foss.arm.com ([217.140.101.70]:34804 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752031AbcFIWXh (ORCPT ); Thu, 9 Jun 2016 18:23:37 -0400 In-Reply-To: <1465511013-10742-1-git-send-email-jeremy.linton@arm.com> Sender: linux-acpi-owner@vger.kernel.org List-Id: linux-acpi@vger.kernel.org To: linux-arm-kernel@lists.infradead.org Cc: linux-acpi@vger.kernel.org, will.deacon@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, catalin.marinas@arm.com, peterz@infradead.org, mingo@redhat.com, acme@kernel.org, alexander.shishkin@linux.intel.com, mlangsdorf@redhat.com On systems with multiple PMU types the PMU to CPU affinity needs to be detected and set. The CPU to interrupt affinity should also be set. Signed-off-by: Jeremy Linton --- drivers/perf/arm_pmu.c | 52 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index fee4be0e8..865a9db 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -11,6 +11,7 @@ */ #define pr_fmt(fmt) "hw perfevents: " fmt +#include #include #include #include @@ -24,6 +25,7 @@ #include #include +#include #include #include @@ -872,25 +874,56 @@ static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu) } /* - * CPU PMU identification and probing. + * CPU PMU identification and probing. Its possible to have + * multiple CPU types in an ARM machine. Assure that we are + * picking the right PMU types based on the CPU in question */ -static int probe_current_pmu(struct arm_pmu *pmu, - const struct pmu_probe_info *info) +static int probe_plat_pmu(struct arm_pmu *pmu, + const struct pmu_probe_info *info, + unsigned int pmuid) { - int cpu = get_cpu(); - unsigned int cpuid = read_cpuid_id(); int ret = -ENODEV; + int cpu; + int aff_ctr = 0; + struct platform_device *pdev = pmu->plat_device; + int irq = platform_get_irq(pdev, 0); - pr_info("probing PMU on CPU %d\n", cpu); + if (irq >= 0 && !irq_is_percpu(irq)) { + pmu->irq_affinity = kcalloc(pdev->num_resources, sizeof(int), + GFP_KERNEL); + if (!pmu->irq_affinity) + return -ENOMEM; + } + + for_each_possible_cpu(cpu) { + unsigned int cpuid = read_specific_cpuid(cpu); + + if (cpuid == pmuid) { + cpumask_set_cpu(cpu, &pmu->supported_cpus); + pr_devel("enable pmu on cpu %d\n", cpu); + if (pmu->irq_affinity) { + pmu->irq_affinity[aff_ctr] = cpu; + aff_ctr++; + } + } + } + pr_debug("probing PMU %X\n", pmuid); + /* find the type of PMU given the CPU */ for (; info->init != NULL; info++) { - if ((cpuid & info->mask) != info->cpuid) + if ((pmuid & info->mask) != info->cpuid) continue; + pr_devel("Found PMU\n"); ret = info->init(pmu); + if (!info->cpuid) { + pmu->name = kasprintf(GFP_KERNEL, "%s_0x%x", + pmu->name, ARM_PARTNUM(pmuid)); + if (!pmu->name) + return -ENOMEM; + } break; } - put_cpu(); return ret; } @@ -1016,8 +1049,7 @@ int arm_pmu_device_probe(struct platform_device *pdev, if (!ret) ret = init_fn(pmu); } else { - cpumask_setall(&pmu->supported_cpus); - ret = probe_current_pmu(pmu, probe_table); + ret = probe_plat_pmu(pmu, probe_table, read_cpuid_id()); } if (ret) { -- 2.5.5 From mboxrd@z Thu Jan 1 00:00:00 1970 From: jeremy.linton@arm.com (Jeremy Linton) Date: Thu, 9 Jun 2016 17:23:30 -0500 Subject: [PATCH 5/8] arm: arm64: pmu: Assign platform PMU CPU affinity In-Reply-To: <1465511013-10742-1-git-send-email-jeremy.linton@arm.com> References: <1465511013-10742-1-git-send-email-jeremy.linton@arm.com> Message-ID: <1465511013-10742-6-git-send-email-jeremy.linton@arm.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On systems with multiple PMU types the PMU to CPU affinity needs to be detected and set. The CPU to interrupt affinity should also be set. Signed-off-by: Jeremy Linton --- drivers/perf/arm_pmu.c | 52 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index fee4be0e8..865a9db 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -11,6 +11,7 @@ */ #define pr_fmt(fmt) "hw perfevents: " fmt +#include #include #include #include @@ -24,6 +25,7 @@ #include #include +#include #include #include @@ -872,25 +874,56 @@ static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu) } /* - * CPU PMU identification and probing. + * CPU PMU identification and probing. Its possible to have + * multiple CPU types in an ARM machine. Assure that we are + * picking the right PMU types based on the CPU in question */ -static int probe_current_pmu(struct arm_pmu *pmu, - const struct pmu_probe_info *info) +static int probe_plat_pmu(struct arm_pmu *pmu, + const struct pmu_probe_info *info, + unsigned int pmuid) { - int cpu = get_cpu(); - unsigned int cpuid = read_cpuid_id(); int ret = -ENODEV; + int cpu; + int aff_ctr = 0; + struct platform_device *pdev = pmu->plat_device; + int irq = platform_get_irq(pdev, 0); - pr_info("probing PMU on CPU %d\n", cpu); + if (irq >= 0 && !irq_is_percpu(irq)) { + pmu->irq_affinity = kcalloc(pdev->num_resources, sizeof(int), + GFP_KERNEL); + if (!pmu->irq_affinity) + return -ENOMEM; + } + + for_each_possible_cpu(cpu) { + unsigned int cpuid = read_specific_cpuid(cpu); + + if (cpuid == pmuid) { + cpumask_set_cpu(cpu, &pmu->supported_cpus); + pr_devel("enable pmu on cpu %d\n", cpu); + if (pmu->irq_affinity) { + pmu->irq_affinity[aff_ctr] = cpu; + aff_ctr++; + } + } + } + pr_debug("probing PMU %X\n", pmuid); + /* find the type of PMU given the CPU */ for (; info->init != NULL; info++) { - if ((cpuid & info->mask) != info->cpuid) + if ((pmuid & info->mask) != info->cpuid) continue; + pr_devel("Found PMU\n"); ret = info->init(pmu); + if (!info->cpuid) { + pmu->name = kasprintf(GFP_KERNEL, "%s_0x%x", + pmu->name, ARM_PARTNUM(pmuid)); + if (!pmu->name) + return -ENOMEM; + } break; } - put_cpu(); return ret; } @@ -1016,8 +1049,7 @@ int arm_pmu_device_probe(struct platform_device *pdev, if (!ret) ret = init_fn(pmu); } else { - cpumask_setall(&pmu->supported_cpus); - ret = probe_current_pmu(pmu, probe_table); + ret = probe_plat_pmu(pmu, probe_table, read_cpuid_id()); } if (ret) { -- 2.5.5