Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1377164 > unrolled thread

[PATCH 0/6 v4] arm64/perf: Add ACPI support

Started byJeremy Linton <jeremy.linton@arm.com>
First post2016-04-12 22:30 +0200
Last post2016-04-15 08:50 +0200
Articles 6 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/6 v4] arm64/perf: Add ACPI support Jeremy Linton <jeremy.linton@arm.com> - 2016-04-12 22:30 +0200
    [PATCH 1/6] arm: pmu: Fix non-devicetree probing Jeremy Linton <jeremy.linton@arm.com> - 2016-04-12 22:30 +0200
    [PATCH 3/6] arm64: pmu: Add support for probing with ACPI Jeremy Linton <jeremy.linton@arm.com> - 2016-04-12 22:30 +0200
    [PATCH 4/6] arm: arm64: Add routine to determine cpuid of other cpus Jeremy Linton <jeremy.linton@arm.com> - 2016-04-12 22:30 +0200
    [PATCH 2/6] arm64: pmu: add fallback probe table Jeremy Linton <jeremy.linton@arm.com> - 2016-04-12 22:30 +0200
    Re: [PATCH 0/6 v4] arm64/perf: Add ACPI support Jan Glauber <jglauber@cavium.com> - 2016-04-15 08:50 +0200

#1377164 — [PATCH 0/6 v4] arm64/perf: Add ACPI support

FromJeremy Linton <jeremy.linton@arm.com>
Date2016-04-12 22:30 +0200
Subject[PATCH 0/6 v4] arm64/perf: Add ACPI support
Message-ID<rnd6F-4Yr-3@gated-at.bofh.it>
v3->v4:
Correct build issues with ARM (!ARM64) kernels.
Add ThunderX to list of PMU types.

v3:
Enable ARM performance monitoring units on ACPI/arm64 machines.

This patch expands and reworks the patches published by Mark Salter
in order to clean up a few of the previous review comments, as well as
add support for newer CPUs and big/little configurations.

I've been testing this patch in concert with an assortment of ACPI
patches to enable things like PCIe. Its been tested on juno, seattle
and some xgene systems.

Thanks,

*** BLURB HERE ***

Jeremy Linton (3):
  arm: arm64: Add routine to determine cpuid of other cpus
  arm64: pmu: Add ACPI support for A72 and ThunderX
  arm64: pmu: Detect multiple PMU types in an ACPI system

Mark Salter (3):
  arm: pmu: Fix non-devicetree probing
  arm64: pmu: add fallback probe table
  arm64: pmu: Add support for probing with ACPI

 arch/arm/include/asm/cputype.h   |   4 +
 arch/arm64/include/asm/cputype.h |   4 +
 arch/arm64/kernel/perf_event.c   |  12 ++-
 arch/arm64/kernel/smp.c          |   5 +
 drivers/perf/Kconfig             |   4 +
 drivers/perf/Makefile            |   1 +
 drivers/perf/arm_pmu.c           |  51 ++++++++--
 drivers/perf/arm_pmu_acpi.c      | 213 +++++++++++++++++++++++++++++++++++++++
 include/linux/perf/arm_pmu.h     |  10 ++
 9 files changed, 293 insertions(+), 11 deletions(-)
 create mode 100644 drivers/perf/arm_pmu_acpi.c

-- 
2.4.3

[toc] | [next] | [standalone]


#1377165 — [PATCH 1/6] arm: pmu: Fix non-devicetree probing

FromJeremy Linton <jeremy.linton@arm.com>
Date2016-04-12 22:30 +0200
Subject[PATCH 1/6] arm: pmu: Fix non-devicetree probing
Message-ID<rnd6G-4Yr-11@gated-at.bofh.it>
In reply to#1377164
From: Mark Salter <msalter@redhat.com>

There is a problem in the non-devicetree PMU probing where some
probe functions may get the number of supported events through
smp_call_function_any() using the arm_pmu supported_cpus mask.
But at the time the probe function is called, the supported_cpus
mask is empty so the call fails. This patch makes sure the mask
is set before calling the init function rather than after.

Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
 drivers/perf/arm_pmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 32346b5..49fa845 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -997,8 +997,8 @@ int arm_pmu_device_probe(struct platform_device *pdev,
 		if (!ret)
 			ret = init_fn(pmu);
 	} else {
-		ret = probe_current_pmu(pmu, probe_table);
 		cpumask_setall(&pmu->supported_cpus);
+		ret = probe_current_pmu(pmu, probe_table);
 	}
 
 	if (ret) {
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1377167 — [PATCH 3/6] arm64: pmu: Add support for probing with ACPI

FromJeremy Linton <jeremy.linton@arm.com>
Date2016-04-12 22:30 +0200
Subject[PATCH 3/6] arm64: pmu: Add support for probing with ACPI
Message-ID<rnd6G-4Yr-17@gated-at.bofh.it>
In reply to#1377164
From: Mark Salter <msalter@redhat.com>

In the case of ACPI, the PMU IRQ information is contained in the
MADT table. Also, since the PMU does not exist as a device in the
ACPI DSDT table, it is necessary to create a platform device so
that the appropriate driver probing is triggered.

Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
 arch/arm64/kernel/smp.c      |   5 ++
 drivers/perf/Kconfig         |   4 ++
 drivers/perf/Makefile        |   1 +
 drivers/perf/arm_pmu_acpi.c  | 125 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/perf/arm_pmu.h |   7 +++
 5 files changed, 142 insertions(+)
 create mode 100644 drivers/perf/arm_pmu_acpi.c

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index b2d5f4e..c6f2c53 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -37,6 +37,7 @@
 #include <linux/completion.h>
 #include <linux/of.h>
 #include <linux/irq_work.h>
+#include <linux/perf/arm_pmu.h>
 
 #include <asm/alternative.h>
 #include <asm/atomic.h>
@@ -502,6 +503,7 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
 			return;
 		}
 		bootcpu_valid = true;
+		arm_pmu_parse_acpi(0, processor);
 		return;
 	}
 
@@ -522,6 +524,9 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
 	 */
 	acpi_set_mailbox_entry(cpu_count, processor);
 
+	/* get PMU irq info */
+	arm_pmu_parse_acpi(cpu_count, processor);
+
 	cpu_count++;
 }
 
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 04e2653..818fa3b 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -12,4 +12,8 @@ config ARM_PMU
 	  Say y if you want to use CPU performance monitors on ARM-based
 	  systems.
 
+config ARM_PMU_ACPI
+	def_bool y
+	depends on ARM_PMU && ACPI
+
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index acd2397..fd8090d 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_ARM_PMU) += arm_pmu.o
+obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o
diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c
new file mode 100644
index 0000000..722f4ca
--- /dev/null
+++ b/drivers/perf/arm_pmu_acpi.c
@@ -0,0 +1,125 @@
+/*
+ * PMU support
+ *
+ * Copyright (C) 2015 Red Hat Inc.
+ * Author: Mark Salter <msalter@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <linux/perf/arm_pmu.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+
+#define PMU_PDEV_NAME "armv8-pmu"
+
+struct pmu_irq {
+	int gsi;
+	int trigger;
+};
+
+static struct pmu_irq pmu_irqs[NR_CPUS] __initdata;
+
+void __init arm_pmu_parse_acpi(int cpu, struct acpi_madt_generic_interrupt *gic)
+{
+	pmu_irqs[cpu].gsi = gic->performance_interrupt;
+	if (gic->flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
+		pmu_irqs[cpu].trigger = ACPI_EDGE_SENSITIVE;
+	else
+		pmu_irqs[cpu].trigger = ACPI_LEVEL_SENSITIVE;
+}
+
+#ifndef CONFIG_SMP
+/*
+ * In !SMP case, we parse for boot CPU IRQ here.
+ */
+static int __init acpi_parse_pmu_irqs(struct acpi_subtable_header *header,
+				      const unsigned long end)
+{
+	struct acpi_madt_generic_interrupt *gic;
+
+	gic = (struct acpi_madt_generic_interrupt *)header;
+
+	if (cpu_logical_map(0) == (gic->arm_mpidr & MPIDR_HWID_BITMASK))
+		arm_pmu_parse_acpi(0, gic);
+
+	return 0;
+}
+
+static void __init acpi_parse_boot_cpu(void)
+{
+	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+				      acpi_parse_pmu_irqs, 0);
+}
+#else
+#define acpi_parse_boot_cpu() do {} while (0)
+#endif
+
+static int __init pmu_acpi_init(void)
+{
+	struct platform_device *pdev;
+	struct pmu_irq *pirq = pmu_irqs;
+	struct resource	*res, *r;
+	int err = -ENOMEM;
+	int i, count, irq;
+
+	if (acpi_disabled)
+		return 0;
+
+	acpi_parse_boot_cpu();
+
+	/* Must have irq for boot boot cpu, at least */
+	if (pirq->gsi == 0)
+		return -EINVAL;
+
+	irq = acpi_register_gsi(NULL, pirq->gsi, pirq->trigger,
+				ACPI_ACTIVE_HIGH);
+
+	if (irq_is_percpu(irq))
+		count = 1;
+	else
+		for (i = 1, count = 1; i < NR_CPUS; i++)
+			if (pmu_irqs[i].gsi)
+				++count;
+
+	pdev = platform_device_alloc(PMU_PDEV_NAME, -1);
+	if (!pdev)
+		goto err_free_gsi;
+
+	res = kcalloc(count, sizeof(*res), GFP_KERNEL);
+	if (!res)
+		goto err_free_device;
+
+	for (i = 0, r = res; i < count; i++, pirq++, r++) {
+		if (i)
+			irq = acpi_register_gsi(NULL, pirq->gsi, pirq->trigger,
+						ACPI_ACTIVE_HIGH);
+		r->start = r->end = irq;
+		r->flags = IORESOURCE_IRQ;
+		if (pirq->trigger == ACPI_EDGE_SENSITIVE)
+			r->flags |= IORESOURCE_IRQ_HIGHEDGE;
+		else
+			r->flags |= IORESOURCE_IRQ_HIGHLEVEL;
+	}
+
+	err = platform_device_add_resources(pdev, res, count);
+	if (!err)
+		err = platform_device_add(pdev);
+	kfree(res);
+	if (!err)
+		return 0;
+
+err_free_device:
+	platform_device_put(pdev);
+
+err_free_gsi:
+	for (i = 0; i < count; i++)
+		acpi_unregister_gsi(pmu_irqs[i].gsi);
+
+	return err;
+}
+arch_initcall(pmu_acpi_init);
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 495332f..d002269 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -154,4 +154,11 @@ int arm_pmu_device_probe(struct platform_device *pdev,
 
 #endif /* CONFIG_ARM_PMU */
 
+#ifdef CONFIG_ARM_PMU_ACPI
+struct acpi_madt_generic_interrupt;
+void arm_pmu_parse_acpi(int cpu, struct acpi_madt_generic_interrupt *gic);
+#else
+#define arm_pmu_parse_acpi(a, b) do { } while (0)
+#endif /* CONFIG_ARM_PMU_ACPI */
+
 #endif /* __ARM_PMU_H__ */
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1377168 — [PATCH 4/6] arm: arm64: Add routine to determine cpuid of other cpus

FromJeremy Linton <jeremy.linton@arm.com>
Date2016-04-12 22:30 +0200
Subject[PATCH 4/6] arm: arm64: Add routine to determine cpuid of other cpus
Message-ID<rnd6H-4Yr-21@gated-at.bofh.it>
In reply to#1377164
It is helpful if we can read the cpuid/midr of other CPUs
in the system independent of arm/arm64.

Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
 arch/arm/include/asm/cputype.h   | 4 ++++
 arch/arm64/include/asm/cputype.h | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index b23c6c8..274baf4 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -208,6 +208,10 @@ static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
 	return read_cpuid(CPUID_MPIDR);
 }
 
+#define read_specific_cpuid(cpu_num) per_cpu_ptr(&cpu_data, cpu_num)->cpuid
+
+
+
 /*
  * Intel's XScale3 core supports some v6 features (supersections, L2)
  * but advertises itself as v5 as it does not support the v6 ISA.  For
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 87e1985..76423a7 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -126,6 +126,9 @@ static inline u32 __attribute_const__ read_cpuid_cachetype(void)
 {
 	return read_cpuid(CTR_EL0);
 }
+
+#define read_specific_cpuid(cpu_num) per_cpu_ptr(&cpu_data, cpu_num)->reg_midr
+
 #endif /* __ASSEMBLY__ */
 
 #endif
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1377169 — [PATCH 2/6] arm64: pmu: add fallback probe table

FromJeremy Linton <jeremy.linton@arm.com>
Date2016-04-12 22:30 +0200
Subject[PATCH 2/6] arm64: pmu: add fallback probe table
Message-ID<rnd6G-4Yr-19@gated-at.bofh.it>
In reply to#1377164
From: Mark Salter <msalter@redhat.com>

In preparation for ACPI support, add a pmu_probe_info table to
the arm_pmu_device_probe() call. This table gets used when
probing in the absence of a devicetree node for PMU.

Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
 arch/arm64/kernel/perf_event.c | 10 +++++++++-
 include/linux/perf/arm_pmu.h   |  3 +++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index f419a7c..8f12eac 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -867,9 +867,17 @@ static const struct of_device_id armv8_pmu_of_device_ids[] = {
 	{},
 };
 
+static const struct pmu_probe_info armv8_pmu_probe_table[] = {
+	ARMV8_PMU_PART_PROBE(ARM_CPU_PART_CORTEX_A53, armv8_a53_pmu_init),
+	ARMV8_PMU_PART_PROBE(ARM_CPU_PART_CORTEX_A57, armv8_a57_pmu_init),
+	PMU_PROBE(0, 0, armv8_pmuv3_init), /* if all else fails... */
+	{ /* sentinel value */ }
+};
+
 static int armv8_pmu_device_probe(struct platform_device *pdev)
 {
-	return arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids, NULL);
+	return arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids,
+				    armv8_pmu_probe_table);
 }
 
 static struct platform_driver armv8_pmu_driver = {
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 4196c90..495332f 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -145,6 +145,9 @@ struct pmu_probe_info {
 #define XSCALE_PMU_PROBE(_version, _fn) \
 	PMU_PROBE(ARM_CPU_IMP_INTEL << 24 | _version, ARM_PMU_XSCALE_MASK, _fn)
 
+#define ARMV8_PMU_PART_PROBE(_part, _fn) \
+	PMU_PROBE((_part) << MIDR_PARTNUM_SHIFT, MIDR_PARTNUM_MASK, _fn)
+
 int arm_pmu_device_probe(struct platform_device *pdev,
 			 const struct of_device_id *of_table,
 			 const struct pmu_probe_info *probe_table);
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1379488

FromJan Glauber <jglauber@cavium.com>
Date2016-04-15 08:50 +0200
Message-ID<ro5JL-760-1@gated-at.bofh.it>
In reply to#1377164
Hi Jeremy,

I've tested the patches on ThunderX and got perf running with ACPI,
so you can add my Tested-by if you like.

Thanks,
Jan

On Tue, Apr 12, 2016 at 03:21:05PM -0500, Jeremy Linton wrote:
> v3->v4:
> Correct build issues with ARM (!ARM64) kernels.
> Add ThunderX to list of PMU types.
> 
> v3:
> Enable ARM performance monitoring units on ACPI/arm64 machines.
> 
> This patch expands and reworks the patches published by Mark Salter
> in order to clean up a few of the previous review comments, as well as
> add support for newer CPUs and big/little configurations.
> 
> I've been testing this patch in concert with an assortment of ACPI
> patches to enable things like PCIe. Its been tested on juno, seattle
> and some xgene systems.
> 
> Thanks,
> 
> *** BLURB HERE ***
> 
> Jeremy Linton (3):
>   arm: arm64: Add routine to determine cpuid of other cpus
>   arm64: pmu: Add ACPI support for A72 and ThunderX
>   arm64: pmu: Detect multiple PMU types in an ACPI system
> 
> Mark Salter (3):
>   arm: pmu: Fix non-devicetree probing
>   arm64: pmu: add fallback probe table
>   arm64: pmu: Add support for probing with ACPI
> 
>  arch/arm/include/asm/cputype.h   |   4 +
>  arch/arm64/include/asm/cputype.h |   4 +
>  arch/arm64/kernel/perf_event.c   |  12 ++-
>  arch/arm64/kernel/smp.c          |   5 +
>  drivers/perf/Kconfig             |   4 +
>  drivers/perf/Makefile            |   1 +
>  drivers/perf/arm_pmu.c           |  51 ++++++++--
>  drivers/perf/arm_pmu_acpi.c      | 213 +++++++++++++++++++++++++++++++++++++++
>  include/linux/perf/arm_pmu.h     |  10 ++
>  9 files changed, 293 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/perf/arm_pmu_acpi.c
> 
> -- 
> 2.4.3

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web