Skip to contentSkip to conversation

ARM perf updates for 3.7

PATCH New Will Deacon 11 participants 29 messages Aug 10, 2012 – Feb 28, 2013

Subsystems (10)
lore
Share & tools
lore
#0 lore raw

cover ARM perf updates for 3.7

Hello,

This patch series contains the ARM perf updates I'd like to push for 3.7 Most of the code is cleanup in preparation for big.LITTLE PMU support, where we will need to support different types of CPU PMU on the same SoC.

The PMU probing has changed so that we try to identify the PMU using its DT binding before falling back to probing the current core. The unused PMU registration mechanism is also removed and platforms registering the device have been updated accordingly.

Given that this touches a few platforms, I anticipate sending it via arm-soc.

All feedback welcome,

Will

Jon Hunter (1):
ARM: PMU: Add runtime PM Support

Sudeep KarkadaNagesha (2):
ARM: pmu: remove arm_pmu_type enumeration
ARM: perf: move irq registration into pmu implementation

Will Deacon (6):
ARM: perf: add devicetree bindings for 11MPcore, A5, A7 and A15 PMUs
ARM: pmu: remove unused reservation mechanism
ARM: perf: remove mysterious compiler barrier
ARM: perf: probe devicetree in preference to current CPU
ARM: perf: prepare for moving CPU PMU code into separate file
ARM: perf: move CPU-specific PMU handling code into separate file

 Documentation/devicetree/bindings/arm/pmu.txt |    4 +
 MAINTAINERS                                   |    1 -
 arch/arm/Kconfig                              |    8 +-
 arch/arm/include/asm/perf_event.h             |    9 +-
 arch/arm/include/asm/pmu.h                    |   77 ++----
 arch/arm/kernel/Makefile                      |    3 +-
 arch/arm/kernel/perf_event.c                  |  347 ++++---------------------
 arch/arm/kernel/perf_event_cpu.c              |  295 +++++++++++++++++++++
 arch/arm/kernel/perf_event_v6.c               |   12 +-
 arch/arm/kernel/perf_event_v7.c               |   32 ++--
 arch/arm/kernel/perf_event_xscale.c           |   10 +-
 arch/arm/kernel/pmu.c                         |   36 ---
 arch/arm/mach-bcmring/arch.c                  |    3 +-
 arch/arm/mach-omap2/devices.c                 |    3 +-
 arch/arm/mach-pxa/devices.c                   |    3 +-
 arch/arm/mach-realview/realview_eb.c          |    3 +-
 arch/arm/mach-realview/realview_pb1176.c      |    3 +-
 arch/arm/mach-realview/realview_pb11mp.c      |    3 +-
 arch/arm/mach-realview/realview_pba8.c        |    3 +-
 arch/arm/mach-realview/realview_pbx.c         |    3 +-
 arch/arm/mach-tegra/devices.c                 |    3 +-
 arch/arm/mach-ux500/cpu-db8500.c              |    3 +-
 arch/arm/mach-vexpress/ct-ca9x4.c             |    3 +-
 arch/arm/plat-iop/pmu.c                       |    3 +-
 arch/arm/plat-samsung/devs.c                  |    3 +-
 25 files changed, 424 insertions(+), 449 deletions(-)
 create mode 100644 arch/arm/kernel/perf_event_cpu.c
 delete mode 100644 arch/arm/kernel/pmu.c
Signature · 1 line
1.7.4.1
#1 lore raw

PATCH 1/9 ARM: PMU: Add runtime PM Support

From: Jon Hunter <[email protected]>

Add runtime PM support to the ARM PMU driver so that devices such as OMAP supporting dynamic PM can use the platform->runtime_* hooks to initialise hardware at runtime. Without having these runtime PM hooks in place any configuration of the PMU hardware would be lost when low power states are entered and hence would prevent PMU from working.

This change also replaces the PMU platform functions enable_irq and disable_irq added by Ming Lei with runtime_resume and runtime_suspend funtions. Ming had added the enable_irq and disable_irq functions as a method to configure the cross trigger interface on OMAP4 for routing the PMU interrupts. By adding runtime PM support, we can move the code called by enable_irq and disable_irq into the runtime PM callbacks runtime_resume and runtime_suspend.

Cc Ming Lei <[email protected]>
Cc Benoit Cousson <[email protected]>
Cc Paul Walmsley <[email protected]>
Cc Kevin Hilman <[email protected]>
---
 arch/arm/include/asm/pmu.h   |   20 ++++++++++++--------
 arch/arm/kernel/perf_event.c |   41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 16 deletions(-)
arch/arm/include/asm/pmu.h +12 -8
index 4432305..40d7dff 100644
@@ -31,18 +31,22 @@ enum arm_pmu_type {
  *	interrupt and passed the address of the low level handler,
  *	and can be used to implement any platform specific handling
  *	before or after calling it.
- * @enable_irq: an optional handler which will be called after
- *	request_irq and be used to handle some platform specific
- *	irq enablement
- * @disable_irq: an optional handler which will be called before
- *	free_irq and be used to handle some platform specific
- *	irq disablement
+ * @runtime_resume: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_get().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called once.
+ * @runtime_suspend: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_put().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called following the
+ *	final call to pm_runtime_put() that actually disables the
+ *	hardware.
  */
 struct arm_pmu_platdata {
 	irqreturn_t (*handle_irq)(int irq, void *dev,
 				  irq_handler_t pmu_handler);
-	void (*enable_irq)(int irq);
-	void (*disable_irq)(int irq);
+	int (*runtime_resume)(struct device *dev);
+	int (*runtime_suspend)(struct device *dev);
 };
 
 #ifdef CONFIG_CPU_HAS_PMU
arch/arm/kernel/perf_event.c +33 -8

89 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#2 lore raw

PATCH 1/9 ARM: PMU: Add runtime PM Support

Quoted 85 lines · Will Deacon

From: Jon Hunter <[email protected]>

Add runtime PM support to the ARM PMU driver so that devices such as OMAP supporting dynamic PM can use the platform->runtime_* hooks to initialise hardware at runtime. Without having these runtime PM hooks in place any configuration of the PMU hardware would be lost when low power states are entered and hence would prevent PMU from working.

This change also replaces the PMU platform functions enable_irq and disable_irq added by Ming Lei with runtime_resume and runtime_suspend funtions. Ming had added the enable_irq and disable_irq functions as a method to configure the cross trigger interface on OMAP4 for routing the PMU interrupts. By adding runtime PM support, we can move the code called by enable_irq and disable_irq into the runtime PM callbacks runtime_resume and runtime_suspend.

Cc Ming Lei <[email protected]>
Cc Benoit Cousson <[email protected]>
Cc Paul Walmsley <[email protected]>
Cc Kevin Hilman <[email protected]>
---
 arch/arm/include/asm/pmu.h   |   20 ++++++++++++--------
 arch/arm/kernel/perf_event.c |   41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 16 deletions(-)
arch/arm/include/asm/pmu.h +12 -8
index 4432305..40d7dff 100644
@@ -31,18 +31,22 @@ enum arm_pmu_type {
  *     interrupt and passed the address of the low level handler,
  *     and can be used to implement any platform specific handling
  *     before or after calling it.
- * @enable_irq: an optional handler which will be called after
- *     request_irq and be used to handle some platform specific
- *     irq enablement
- * @disable_irq: an optional handler which will be called before
- *     free_irq and be used to handle some platform specific
- *     irq disablement
+ * @runtime_resume: an optional handler which will be called by the
+ *     runtime PM framework following a call to pm_runtime_get().
+ *     Note that if pm_runtime_get() is called more than once in
+ *     succession this handler will only be called once.
+ * @runtime_suspend: an optional handler which will be called by the
+ *     runtime PM framework following a call to pm_runtime_put().
+ *     Note that if pm_runtime_get() is called more than once in
+ *     succession this handler will only be called following the
+ *     final call to pm_runtime_put() that actually disables the
+ *     hardware.
  */
 struct arm_pmu_platdata {
        irqreturn_t (*handle_irq)(int irq, void *dev,
                                  irq_handler_t pmu_handler);
-       void (*enable_irq)(int irq);
-       void (*disable_irq)(int irq);
+       int (*runtime_resume)(struct device *dev);
+       int (*runtime_suspend)(struct device *dev);
 };
 
 #ifdef CONFIG_CPU_HAS_PMU
arch/arm/kernel/perf_event.c +1 -2
index ab243b8..c44647e 100644
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -364,8 +365,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 {
        int i, irq, irqs;
        struct platform_device *pmu_device = armpmu->plat_device;
-       struct arm_pmu_platdata *plat =
-               dev_get_platdata(&pmu_device->dev);
 
        irqs = min(pmu_device->num_resources, num_possible_cpus());
 
@@ -373,13 +372,11 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
                if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
                        continue;

arch/arm/kernel/perf_event.c armpmu_release_hardware(struct arm_pmu *armpmu) · line 379

Quoted 10 lines
arch/arm/kernel/perf_event.c +2 -4
                irq = platform_get_irq(pmu_device, i);
-               if (irq >= 0) {
-                       if (plat && plat->disable_irq)
-                               plat->disable_irq(irq);
+               if (irq >= 0)
                        free_irq(irq, armpmu);
-               }
        }
 
+       pm_runtime_put_sync(&pmu_device->dev);

One question, each pmu is just inside one cpu core and should be suspended individually, but looks the above don't support it, do it?

arch/arm/kernel/perf_event.c armpmu_reserve_hardware(struct arm_pmu *armpmu) · line 412

Quoted 8 lines
arch/arm/kernel/perf_event.c +1 -0
        release_pmu(armpmu->type);
 }
 
@@ -412,6 +409,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
                return -ENODEV;
        }
 
+       pm_runtime_get_sync(&pmu_device->dev);

Similar with above.

Thanks,
--
Ming Lei

#3 lore raw

PATCH 1/9 ARM: PMU: Add runtime PM Support

Quoted 5 lines · Ming Lei
Quoted 1 line · Will Deacon

+ pm_runtime_put_sync(&pmu_device->dev);

One question, each pmu is just inside one cpu core and should be suspended individually, but looks the above don't support it, do it?

I'll let Jon elaborate, but I'm not sure that suspending the individual PMUs makes much sense if one of them is being used (other than taking the whole CPU offline). Given that tasks can migrate and perf-events can be across multiple CPUs, it makes it a lot easier to treat them as a single entity. It also allows us to implement mutual exclusion using the same hooks and to manage any common IP (e.g. CTI) at the same time, without having to keep track of things like the last man standing.

So, unless Jon has some ideas here, it's not something that I consider to be a real problem.

Will

#4 lore raw

PATCH 1/9 ARM: PMU: Add runtime PM Support

Quoted 15 lines · Will Deacon
Quoted 5 lines · Ming Lei
Quoted 1 line · Will Deacon

+ pm_runtime_put_sync(&pmu_device->dev);

One question, each pmu is just inside one cpu core and should be suspended individually, but looks the above don't support it, do it?

I'll let Jon elaborate, but I'm not sure that suspending the individual PMUs makes much sense if one of them is being used (other than taking the whole CPU offline). Given that tasks can migrate and perf-events can be across multiple CPUs, it makes it a lot easier to treat them as a single entity. It also allows us to implement mutual exclusion using the same hooks and to manage any common IP (e.g. CTI) at the same time, without having to keep track of things like the last man standing.

Quoted 2 lines

So, unless Jon has some ideas here, it's not something that I consider to be a real problem.

So from an OMAP3/4 perspective (which is the only device so far using these runtime PM callbacks that I know of), it does not add any value to suspend each PMU individually. For OMAP3/4, if one or more PMU is active then we need to power up additional power domains and we need to keep them powered until all PMUs are no longer in use.

For OMAP5 (which I have started testing) does not need other power domains apart from the CPU power domain. So this could make more sense, but I have not tried this yet. For now I think it is ok to keep as is and then we can always change later to optimise for newer devices or architectures if we think that they would benefit from this.

Cheers
Jon

#5 lore raw

PATCH 2/9 ARM: perf: add devicetree bindings for 11MPcore, A5, A7 and A15 PMUs

In reply to Will Deacon

This patch adds separate devicetree bindings for 11MPcore and Cortex-{A5,A7,A15} PMUs in preparation for improved devicetree parsing in the ARM perf-event CPU PMU driver.

Cc Grant Likely <[email protected]>
Cc Rob Herring <[email protected]>
---
 Documentation/devicetree/bindings/arm/pmu.txt |    4 ++++
 arch/arm/kernel/perf_event.c                  |    6 +++++-
 2 files changed, 9 insertions(+), 1 deletions(-)
Documentation/devicetree/bindings/arm/pmu.txt +4 -0
index 1c044eb..343781b 100644
@@ -7,8 +7,12 @@ representation in the device tree should be done as under:-
 Required properties:
 
 - compatible : should be one of
+	"arm,cortex-a15-pmu"
 	"arm,cortex-a9-pmu"
 	"arm,cortex-a8-pmu"
+	"arm,cortex-a7-pmu"
+	"arm,cortex-a5-pmu"
+	"arm,arm11mpcore-pmu"
 	"arm,arm1176-pmu"
 	"arm,arm1136-pmu"
 - interrupts : 1 combined interrupt or 1 per core.
arch/arm/kernel/perf_event.c +5 -1
index c44647e..3aa3388 100644
@@ -646,10 +646,14 @@ arch_initcall(cpu_pmu_reset);
  * PMU platform driver and devicetree bindings.
  */
 static struct of_device_id armpmu_of_device_ids[] = {
+	{.compatible = "arm,cortex-a15-pmu"},
 	{.compatible = "arm,cortex-a9-pmu"},
 	{.compatible = "arm,cortex-a8-pmu"},
-	{.compatible = "arm,arm1136-pmu"},
+	{.compatible = "arm,cortex-a7-pmu"},
+	{.compatible = "arm,cortex-a5-pmu"},
+	{.compatible = "arm,arm11mpcore-pmu"},
 	{.compatible = "arm,arm1176-pmu"},
+	{.compatible = "arm,arm1136-pmu"},
 	{},
 };
 
Signature · 1 line
1.7.4.1
#6 lore raw

PATCH 2/9 ARM: perf: add devicetree bindings for 11MPcore, A5, A7 and A15 PMUs

Quoted 8 lines · Will Deacon

This patch adds separate devicetree bindings for 11MPcore and Cortex-{A5,A7,A15} PMUs in preparation for improved devicetree parsing in the ARM perf-event CPU PMU driver.

Cc Grant Likely <[email protected]>
Cc Rob Herring <[email protected]>

---

Quoted 42 lines
 Documentation/devicetree/bindings/arm/pmu.txt |    4 ++++
 arch/arm/kernel/perf_event.c                  |    6 +++++-
 2 files changed, 9 insertions(+), 1 deletions(-)
Documentation/devicetree/bindings/arm/pmu.txt +4 -0
index 1c044eb..343781b 100644
@@ -7,8 +7,12 @@ representation in the device tree should be done as under:-
 Required properties:
 
 - compatible : should be one of
+	"arm,cortex-a15-pmu"
 	"arm,cortex-a9-pmu"
 	"arm,cortex-a8-pmu"
+	"arm,cortex-a7-pmu"
+	"arm,cortex-a5-pmu"
+	"arm,arm11mpcore-pmu"
 	"arm,arm1176-pmu"
 	"arm,arm1136-pmu"
 - interrupts : 1 combined interrupt or 1 per core.
arch/arm/kernel/perf_event.c +5 -1
index c44647e..3aa3388 100644
@@ -646,10 +646,14 @@ arch_initcall(cpu_pmu_reset);
  * PMU platform driver and devicetree bindings.
  */
 static struct of_device_id armpmu_of_device_ids[] = {
+	{.compatible = "arm,cortex-a15-pmu"},
 	{.compatible = "arm,cortex-a9-pmu"},
 	{.compatible = "arm,cortex-a8-pmu"},
-	{.compatible = "arm,arm1136-pmu"},
+	{.compatible = "arm,cortex-a7-pmu"},
+	{.compatible = "arm,cortex-a5-pmu"},
+	{.compatible = "arm,arm11mpcore-pmu"},
 	{.compatible = "arm,arm1176-pmu"},
+	{.compatible = "arm,arm1136-pmu"},
 	{},
 };
 
#7 lore raw

PATCH 3/9 ARM: pmu: remove unused reservation mechanism

In reply to Will Deacon

The PMU reservation mechanism was originally intended to allow OProfile and perf-events to co-ordinate over access to the CPU PMU. Since then, OProfile for ARM has moved to using perf as its backend, so the reservation code is no longer used.

This patch removes the reservation code for the CPU PMU on ARM.

---
 MAINTAINERS                  |    1 -
 arch/arm/Kconfig             |    8 +-------
 arch/arm/include/asm/pmu.h   |   34 ----------------------------------
 arch/arm/kernel/Makefile     |    1 -
 arch/arm/kernel/perf_event.c |    8 --------
 arch/arm/kernel/pmu.c        |   36 ------------------------------------
 6 files changed, 1 insertions(+), 87 deletions(-)
 delete mode 100644 arch/arm/kernel/pmu.c
MAINTAINERS +0 -1
index 94b823f..9dcd1ae 100644
@@ -595,7 +595,6 @@ M:	Will Deacon <[email protected]>
 S:	Maintained
 F:	arch/arm/kernel/perf_event*
 F:	arch/arm/oprofile/common.c
-F:	arch/arm/kernel/pmu.c
 F:	arch/arm/include/asm/pmu.h
 F:	arch/arm/kernel/hw_breakpoint.c
 F:	arch/arm/include/asm/hw_breakpoint.h
arch/arm/Kconfig +1 -7
index e91c7cd..ca05a95 100644
@@ -1185,12 +1185,6 @@ config XSCALE_PMU
 	depends on CPU_XSCALE
 	default y
 
-config CPU_HAS_PMU
-	depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
-		   (!ARCH_OMAP3 || OMAP3_EMU)
-	default y
-	bool
-
 config MULTI_IRQ_HANDLER
 	bool
 	help
@@ -1763,7 +1757,7 @@ config HIGHPTE
 
 config HW_PERF_EVENTS
 	bool "Enable hardware performance counter support for perf events"
-	depends on PERF_EVENTS && CPU_HAS_PMU
+	depends on PERF_EVENTS
 	default y
 	help
 	  Enable hardware performance counter support for perf events. If
arch/arm/include/asm/pmu.h +0 -34
index 40d7dff..05e0401 100644
@@ -49,40 +49,6 @@ struct arm_pmu_platdata {
 	int (*runtime_suspend)(struct device *dev);
 };
 
-#ifdef CONFIG_CPU_HAS_PMU
-
-/**
- * reserve_pmu() - reserve the hardware performance counters
- *
- * Reserve the hardware performance counters in the system for exclusive use.
- * Returns 0 on success or -EBUSY if the lock is already held.
- */
-extern int
-reserve_pmu(enum arm_pmu_type type);
-
-/**
- * release_pmu() - Relinquish control of the performance counters
- *
- * Release the performance counters and allow someone else to use them.
- */
-extern void
-release_pmu(enum arm_pmu_type type);
-
-#else /* CONFIG_CPU_HAS_PMU */
-
-#include <linux/err.h>
-
-static inline int
-reserve_pmu(enum arm_pmu_type type)
-{
-	return -ENODEV;
-}
-
-static inline void
-release_pmu(enum arm_pmu_type type)	{ }
-
-#endif /* CONFIG_CPU_HAS_PMU */
-
 #ifdef CONFIG_HW_PERF_EVENTS
 
 /* The events for a given PMU register set. */
arch/arm/kernel/Makefile +0 -1
index 7ad2d5c..cfbe3b4 100644
@@ -69,7 +69,6 @@ obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
-obj-$(CONFIG_CPU_HAS_PMU)	+= pmu.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
 obj-$(CONFIG_ARM_CPU_TOPOLOGY)  += topology.o
arch/arm/kernel/perf_event.c +0 -8
index 3aa3388..1ac1531 100644
@@ -377,7 +377,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 	}
 
 	pm_runtime_put_sync(&pmu_device->dev);
-	release_pmu(armpmu->type);
 }
 
 static int
@@ -391,12 +390,6 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 	if (!pmu_device)
 		return -ENODEV;
 
-	err = reserve_pmu(armpmu->type);
-	if (err) {
-		pr_warning("unable to reserve pmu\n");
-		return err;
-	}
-
 	plat = dev_get_platdata(&pmu_device->dev);
 	if (plat && plat->handle_irq)
 		handle_irq = armpmu_platform_irq;
@@ -706,7 +699,6 @@ static void __init cpu_pmu_init(struct arm_pmu *armpmu)
 		raw_spin_lock_init(&events->pmu_lock);
 	}
 	armpmu->get_hw_events = armpmu_get_cpu_events;
-	armpmu->type = ARM_PMU_DEVICE_CPU;
 }
 
 /*
arch/arm/kernel/pmu.c deleted +0 -36
deleted file mode 100644
index 2334bf8..0000000
@@ -1,36 +0,0 @@
-/*
- *  linux/arch/arm/kernel/pmu.c
- *
- *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
- *  Copyright (C) 2010 ARM Ltd, Will Deacon
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <asm/pmu.h>
-
-/*
- * PMU locking to ensure mutual exclusion between different subsystems.
- */
-static unsigned long pmu_lock[BITS_TO_LONGS(ARM_NUM_PMU_DEVICES)];
-
-int
-reserve_pmu(enum arm_pmu_type type)
-{
-	return test_and_set_bit_lock(type, pmu_lock) ? -EBUSY : 0;
-}
-EXPORT_SYMBOL_GPL(reserve_pmu);
-
-void
-release_pmu(enum arm_pmu_type type)
-{
-	clear_bit_unlock(type, pmu_lock);
-}
-EXPORT_SYMBOL_GPL(release_pmu);
Signature · 1 line
1.7.4.1
#8 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

In reply to Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>

The arm_pmu_type enumeration was initially introduced to identify different PMU types in the system, the usual one being that on the CPU (ARM_PMU_DEVICE_CPU). With the removal of the PMU reservation code and the introduction of devicetree bindings for the CPU PMU, the enumeration is no longer required.

This patch removes the enumeration and updates the various CPU PMU platform devices so that they no longer pass an .id field referring to identify the PMU type.

Cc JD Zheng <[email protected]>
Cc Jon Hunter <[email protected]>
Cc Haojian Zhuang <[email protected]>
Cc Olof Johansson <[email protected]>
Cc Linus Walleij <[email protected]>
Cc Kukjin Kim <[email protected]>
Cc Pawel Moll <[email protected]>
[will: cosmetic edits and actual removal of the enum type]
---
 arch/arm/include/asm/pmu.h               |   10 ----------
 arch/arm/mach-bcmring/arch.c             |    3 +--
 arch/arm/mach-omap2/devices.c            |    3 +--
 arch/arm/mach-pxa/devices.c              |    3 +--
 arch/arm/mach-realview/realview_eb.c     |    3 +--
 arch/arm/mach-realview/realview_pb1176.c |    3 +--
 arch/arm/mach-realview/realview_pb11mp.c |    3 +--
 arch/arm/mach-realview/realview_pba8.c   |    3 +--
 arch/arm/mach-realview/realview_pbx.c    |    3 +--
 arch/arm/mach-tegra/devices.c            |    3 +--
 arch/arm/mach-ux500/cpu-db8500.c         |    3 +--
 arch/arm/mach-vexpress/ct-ca9x4.c        |    3 +--
 arch/arm/plat-iop/pmu.c                  |    3 +--
 arch/arm/plat-samsung/devs.c             |    3 +--
 14 files changed, 13 insertions(+), 36 deletions(-)
arch/arm/include/asm/pmu.h +0 -10
index 05e0401..fbec73a 100644
@@ -16,15 +16,6 @@
 #include <linux/perf_event.h>
 
 /*
- * Types of PMUs that can be accessed directly and require mutual
- * exclusion between profiling tools.
- */
-enum arm_pmu_type {
-	ARM_PMU_DEVICE_CPU	= 0,
-	ARM_NUM_PMU_DEVICES,
-};
-
-/*
  * struct arm_pmu_platdata - ARM PMU platform data
  *
  * @handle_irq: an optional handler which will be called from the
@@ -73,7 +64,6 @@ struct pmu_hw_events {
 
 struct arm_pmu {
 	struct pmu	pmu;
-	enum arm_pmu_type type;
 	cpumask_t	active_irqs;
 	char		*name;
 	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
arch/arm/mach-bcmring/arch.c +1 -2
index 45c97b1..76e7953 100644
@@ -29,7 +29,6 @@
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/time.h>
-#include <asm/pmu.h>
 
 #include <asm/mach/arch.h>
 #include <mach/dma.h>
@@ -116,7 +115,7 @@ static struct resource pmu_resource = {
 
 static struct platform_device pmu_device = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.resource	= &pmu_resource,
 	.num_resources	= 1,
 };
arch/arm/mach-omap2/devices.c +1 -2
index c00c689..02b9478 100644
@@ -23,7 +23,6 @@
 #include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 
 #include "iomap.h"
 #include <plat/board.h>
@@ -448,7 +447,7 @@ static struct resource omap3_pmu_resource = {
 
 static struct platform_device omap_pmu_device = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.num_resources	= 1,
 };
 
arch/arm/mach-pxa/devices.c +1 -2
index 166eee5..c1f3b12 100644
@@ -6,7 +6,6 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/i2c/pxa-i2c.h>
 
-#include <asm/pmu.h>
 #include <mach/udc.h>
 #include <mach/pxa3xx-u2d.h>
 #include <mach/pxafb.h>
@@ -42,7 +41,7 @@ static struct resource pxa_resource_pmu = {
 
 struct platform_device pxa_device_pmu = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.resource	= &pxa_resource_pmu,
 	.num_resources	= 1,
 };
arch/arm/mach-realview/realview_eb.c +1 -2
index baf382c..d7a6e9c 100644
@@ -32,7 +32,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -297,7 +296,7 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
 	.name			= "arm-pmu",
-	.id			= ARM_PMU_DEVICE_CPU,
+	.id			= -1,
 	.num_resources		= ARRAY_SIZE(pmu_resources),
 	.resource		= pmu_resources,
 };
arch/arm/mach-realview/realview_pb1176.c +1 -2
index b1d7caf..361f898 100644
@@ -34,7 +34,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -280,7 +279,7 @@ static struct resource pmu_resource = {
 
 static struct platform_device pmu_device = {
 	.name			= "arm-pmu",
-	.id			= ARM_PMU_DEVICE_CPU,
+	.id			= -1,
 	.num_resources		= 1,
 	.resource		= &pmu_resource,
 };
arch/arm/mach-realview/realview_pb11mp.c +1 -2
index a98c536..c56bc8d 100644
@@ -32,7 +32,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -263,7 +262,7 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
 	.name			= "arm-pmu",
-	.id			= ARM_PMU_DEVICE_CPU,
+	.id			= -1,
 	.num_resources		= ARRAY_SIZE(pmu_resources),
 	.resource		= pmu_resources,
 };
arch/arm/mach-realview/realview_pba8.c +1 -2
index 5965017..0409375 100644
@@ -31,7 +31,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 
@@ -241,7 +240,7 @@ static struct resource pmu_resource = {
 
 static struct platform_device pmu_device = {
 	.name			= "arm-pmu",
-	.id			= ARM_PMU_DEVICE_CPU,
+	.id			= -1,
 	.num_resources		= 1,
 	.resource		= &pmu_resource,
 };
arch/arm/mach-realview/realview_pbx.c +1 -2
index 3f2f605..97885dc 100644
@@ -30,7 +30,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/smp_twd.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
@@ -280,7 +279,7 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
 	.name			= "arm-pmu",
-	.id			= ARM_PMU_DEVICE_CPU,
+	.id			= -1,
 	.num_resources		= ARRAY_SIZE(pmu_resources),
 	.resource		= pmu_resources,
 };
arch/arm/mach-tegra/devices.c +1 -2
index c70e65f..61e9603 100644
@@ -23,7 +23,6 @@
 #include <linux/fsl_devices.h>
 #include <linux/serial_8250.h>
 #include <linux/i2c-tegra.h>
-#include <asm/pmu.h>
 #include <mach/irqs.h>
 #include <mach/iomap.h>
 #include <mach/dma.h>
@@ -516,7 +515,7 @@ static struct resource tegra_pmu_resources[] = {
 
 struct platform_device tegra_pmu_device = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.num_resources	= ARRAY_SIZE(tegra_pmu_resources),
 	.resource	= tegra_pmu_resources,
 };
arch/arm/mach-ux500/cpu-db8500.c +1 -2
index db3c52d..3ee761d 100644
@@ -19,7 +19,6 @@
 #include <linux/mfd/abx500/ab8500.h>
 
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 #include <plat/gpio-nomadik.h>
 #include <mach/hardware.h>
 #include <mach/setup.h>
@@ -122,7 +121,7 @@ struct arm_pmu_platdata db8500_pmu_platdata = {
 
 static struct platform_device db8500_pmu_device = {
 	.name			= "arm-pmu",
-	.id			= ARM_PMU_DEVICE_CPU,
+	.id			= -1,
 	.num_resources		= ARRAY_SIZE(db8500_pmu_resources),
 	.resource		= db8500_pmu_resources,
 	.dev.platform_data	= &db8500_pmu_platdata,
arch/arm/mach-vexpress/ct-ca9x4.c +1 -2
index 61c4924..e4073a6 100644
@@ -13,7 +13,6 @@
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
-#include <asm/pmu.h>
 #include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 
@@ -144,7 +143,7 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.num_resources	= ARRAY_SIZE(pmu_resources),
 	.resource	= pmu_resources,
 };
arch/arm/plat-iop/pmu.c +1 -2
index a2024b8..ad9f974 100644
@@ -9,7 +9,6 @@
  */
 
 #include <linux/platform_device.h>
-#include <asm/pmu.h>
 #include <mach/irqs.h>
 
 static struct resource pmu_resource = {
@@ -26,7 +25,7 @@ static struct resource pmu_resource = {
 
 static struct platform_device pmu_device = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.resource	= &pmu_resource,
 	.num_resources	= 1,
 };
arch/arm/plat-samsung/devs.c +1 -2
index 74e31ce..8154fab 100644
@@ -33,7 +33,6 @@
 #include <linux/platform_data/s3c-hsotg.h>
 
 #include <asm/irq.h>
-#include <asm/pmu.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -1105,7 +1104,7 @@ static struct resource s5p_pmu_resource[] = {
 
 static struct platform_device s5p_device_pmu = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.num_resources	= ARRAY_SIZE(s5p_pmu_resource),
 	.resource	= s5p_pmu_resource,
 };
Signature · 1 line
1.7.4.1
#9 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

Quoted 11 lines · Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>

The arm_pmu_type enumeration was initially introduced to identify different PMU types in the system, the usual one being that on the CPU (ARM_PMU_DEVICE_CPU). With the removal of the PMU reservation code and the introduction of devicetree bindings for the CPU PMU, the enumeration is no longer required.

This patch removes the enumeration and updates the various CPU PMU platform devices so that they no longer pass an .id field referring to identify the PMU type.

Yours,
Linus Walleij

#10 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

In reply to Will Deacon
Quoted 81 lines · Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>

The arm_pmu_type enumeration was initially introduced to identify different PMU types in the system, the usual one being that on the CPU (ARM_PMU_DEVICE_CPU). With the removal of the PMU reservation code and the introduction of devicetree bindings for the CPU PMU, the enumeration is no longer required.

This patch removes the enumeration and updates the various CPU PMU platform devices so that they no longer pass an .id field referring to identify the PMU type.

Cc JD Zheng <[email protected]>
Cc Jon Hunter <[email protected]>
Cc Haojian Zhuang <[email protected]>
Cc Olof Johansson <[email protected]>
Cc Linus Walleij <[email protected]>
Cc Kukjin Kim <[email protected]>
Cc Pawel Moll <[email protected]>
[will: cosmetic edits and actual removal of the enum type]
---
  arch/arm/include/asm/pmu.h               |   10 ----------
  arch/arm/mach-bcmring/arch.c             |    3 +--
  arch/arm/mach-omap2/devices.c            |    3 +--
  arch/arm/mach-pxa/devices.c              |    3 +--
  arch/arm/mach-realview/realview_eb.c     |    3 +--
  arch/arm/mach-realview/realview_pb1176.c |    3 +--
  arch/arm/mach-realview/realview_pb11mp.c |    3 +--
  arch/arm/mach-realview/realview_pba8.c   |    3 +--
  arch/arm/mach-realview/realview_pbx.c    |    3 +--
  arch/arm/mach-tegra/devices.c            |    3 +--
  arch/arm/mach-ux500/cpu-db8500.c         |    3 +--
  arch/arm/mach-vexpress/ct-ca9x4.c        |    3 +--
  arch/arm/plat-iop/pmu.c                  |    3 +--
  arch/arm/plat-samsung/devs.c             |    3 +--
  14 files changed, 13 insertions(+), 36 deletions(-)
arch/arm/include/asm/pmu.h +0 -10
index 05e0401..fbec73a 100644
@@ -16,15 +16,6 @@
  #include <linux/perf_event.h>
 
  /*
- * Types of PMUs that can be accessed directly and require mutual
- * exclusion between profiling tools.
- */
-enum arm_pmu_type {
-	ARM_PMU_DEVICE_CPU	= 0,
-	ARM_NUM_PMU_DEVICES,
-};
-
-/*
   * struct arm_pmu_platdata - ARM PMU platform data
   *
   * @handle_irq: an optional handler which will be called from the
@@ -73,7 +64,6 @@ struct pmu_hw_events {
 
  struct arm_pmu {
  	struct pmu	pmu;
-	enum arm_pmu_type type;
  	cpumask_t	active_irqs;
  	char		*name;
  	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
arch/arm/mach-bcmring/arch.c +0 -1
index 45c97b1..76e7953 100644
@@ -29,7 +29,6 @@
  #include <asm/setup.h>
  #include <asm/mach-types.h>
  #include <asm/mach/time.h>
-#include <asm/pmu.h>
 
  #include <asm/mach/arch.h>
  #include <mach/dma.h>

arch/arm/mach-bcmring/arch.c static struct resource pmu_resource = { · line 121

Quoted 8 lines
arch/arm/mach-bcmring/arch.c +1 -1
@@ -116,7 +115,7 @@ static struct resource pmu_resource = {
 
  static struct platform_device pmu_device = {
  	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
  	.resource	= &pmu_resource,
  	.num_resources	= 1,
  };

Isn't it clearer to define a meaningful name for "-1", esp. if "-1" is being checked somewhere else?

Regards,
JD

#11 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

Hi Jiandong,

Quoted 12 lines · Jiandong Zheng

arch/arm/mach-bcmring/arch.c static struct resource pmu_resource = { · line 121

Quoted 9 lines · Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>

   static struct platform_device pmu_device = {
   	.name		= "arm-pmu",
arch/arm/mach-bcmring/arch.c +1 -1
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
   	.resource	= &pmu_resource,
   	.num_resources	= 1,
   };

Isn't it clearer to define a meaningful name for "-1", esp. if "-1" is being checked somewhere else?

No platform_device->id is not being referred anywhere. ARM_PMU_DEVICE_CPU was initially assigned to id to identify different PMU types through platform_device->id variable but was never used.

Also for all new platforms that might support multiple PMUs, we can use device tree to identify them.

Regards,
Sudeep

#12 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

Quoted 16 lines · Sudeep KarkadaNagesha

Hi Jiandong,

Quoted 10 lines · Jiandong Zheng

arch/arm/mach-bcmring/arch.c static struct resource pmu_resource = { · line 121

Quoted 9 lines · Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>
static struct platform_device pmu_device = {
.name = "arm-pmu",

arch/arm/mach-bcmring/arch.c +1 -1
-    .id        = ARM_PMU_DEVICE_CPU,
+    .id        = -1,
       .resource    = &pmu_resource,
       .num_resources    = 1,
   };
Quoted 2 lines

Isn't it clearer to define a meaningful name for "-1", esp. if "-1" is being checked somewhere else?

Quoted 7 lines

No platform_device->id is not being referred anywhere. ARM_PMU_DEVICE_CPU was initially assigned to id to identify different PMU types through platform_device->id variable but was never used.

Also for all new platforms that might support multiple PMUs, we can use device tree to identify them.

Seems it is just a field not in use. Even though I still prefer something like "ARM_PMU_DEFAULT_ID" to "-1", I am OK with "-1" as well.

Thanks,
JD

#13 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

In reply to Will Deacon
Quoted 11 lines · Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>

The arm_pmu_type enumeration was initially introduced to identify different PMU types in the system, the usual one being that on the CPU (ARM_PMU_DEVICE_CPU). With the removal of the PMU reservation code and the introduction of devicetree bindings for the CPU PMU, the enumeration is no longer required.

This patch removes the enumeration and updates the various CPU PMU platform devices so that they no longer pass an .id field referring to identify the PMU type.

Cheers
Jon

#14 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

In reply to Will Deacon

Hi Will, Tony,

Quoted 11 lines · Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>

The arm_pmu_type enumeration was initially introduced to identify different PMU types in the system, the usual one being that on the CPU (ARM_PMU_DEVICE_CPU). With the removal of the PMU reservation code and the introduction of devicetree bindings for the CPU PMU, the enumeration is no longer required.

This patch removes the enumeration and updates the various CPU PMU platform devices so that they no longer pass an .id field referring to identify the PMU type.

[snip]

Quoted 13 lines
arch/arm/mach-omap2/devices.c +0 -1
index c00c689..02b9478 100644
@@ -23,7 +23,6 @@
 #include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 
 #include "iomap.h"
 #include <plat/board.h>

arch/arm/mach-omap2/devices.c static struct resource omap3_pmu_resource = { · line 452

Quoted 7 lines
arch/arm/mach-omap2/devices.c +1 -1
@@ -448,7 +447,7 @@ static struct resource omap3_pmu_resource = {
 
 static struct platform_device omap_pmu_device = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.num_resources	= 1,
 };

I know that I have already ack-ed the change and it is fine with me, however, I see a potential merge conflict here with my patch [1] (assuming that these all go into v3.7) where I am moving the above structure.

For testing I have rebased my series on top of this series and it is working well so far on OMAP4460.

I am hoping to get the next version of my series for omap out next week. However, before I did I wanted to ask how we should handle the above change. Should I submit my series as rebased on top of this?

Thanks
Jon

[1]
https://github.com/jonhunter/linux/commit/6a07e3aa21f956bea7858704c224b7f50d25e1c0

#15 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

Quoted 1 line · Jon Hunter

Hi Will, Tony,

Hi Jon [adding Arnd],

Quoted 15 lines · Will Deacon
Quoted 14 lines
arch/arm/mach-omap2/devices.c +0 -1
index c00c689..02b9478 100644
@@ -23,7 +23,6 @@
 #include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 
 #include "iomap.h"
 #include <plat/board.h>
@@ -448,7 +447,7 @@ static struct resource omap3_pmu_resource = {
 
Quoted 11 lines

arch/arm/mach-omap2/devices.c static struct resource omap3_pmu_resource = { · line 452

Quoted 6 lines
arch/arm/mach-omap2/devices.c +1 -1
 static struct platform_device omap_pmu_device = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.num_resources	= 1,
 };

I know that I have already ack-ed the change and it is fine with me, however, I see a potential merge conflict here with my patch [1] (assuming that these all go into v3.7) where I am moving the above structure.

Are your patches queued anywhere other than your tree? If not, then I could ask Arnd to pull the perf changes into their own branch in arm-soc and you could rebase onto that.

Quoted 2 lines

For testing I have rebased my series on top of this series and it is working well so far on OMAP4460.

Great, thanks. Can I add your tested-by to the patches please?

Will

#16 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

Quoted 32 lines · Will Deacon
Quoted 1 line · Jon Hunter

Hi Will, Tony,

Hi Jon [adding Arnd],

Quoted 15 lines · Will Deacon
Quoted 14 lines
arch/arm/mach-omap2/devices.c +0 -1
index c00c689..02b9478 100644
@@ -23,7 +23,6 @@
 #include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 
 #include "iomap.h"
 #include <plat/board.h>
@@ -448,7 +447,7 @@ static struct resource omap3_pmu_resource = {
 
Quoted 11 lines

arch/arm/mach-omap2/devices.c static struct resource omap3_pmu_resource = { · line 452

Quoted 6 lines
arch/arm/mach-omap2/devices.c +1 -1
 static struct platform_device omap_pmu_device = {
 	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
+	.id		= -1,
 	.num_resources	= 1,
 };

I know that I have already ack-ed the change and it is fine with me, however, I see a potential merge conflict here with my patch [1] (assuming that these all go into v3.7) where I am moving the above structure.

Quoted 3 lines

Are your patches queued anywhere other than your tree? If not, then I could ask Arnd to pull the perf changes into their own branch in arm-soc and you could rebase onto that.

No just my tree for now, so that would work for me.

Quoted 4 lines
Quoted 2 lines

For testing I have rebased my series on top of this series and it is working well so far on OMAP4460.

Great, thanks. Can I add your tested-by to the patches please?

Yes, you can add my tested-by. I will also test on omap3 and omap4430 too.

Cheers
Jon

#17 lore raw

PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration

In reply to Will Deacon
Quoted 13 lines · Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>

The arm_pmu_type enumeration was initially introduced to identify different PMU types in the system, the usual one being that on the CPU (ARM_PMU_DEVICE_CPU). With the removal of the PMU reservation code and the introduction of devicetree bindings for the CPU PMU, the enumeration is no longer required.

This patch removes the enumeration and updates the various CPU PMU platform devices so that they no longer pass an .id field referring to identify the PMU type.

Quoted 6 lines
Cc JD Zheng <[email protected]>
Cc Jon Hunter <[email protected]>
Cc Haojian Zhuang <[email protected]>
Cc Olof Johansson <[email protected]>
Cc Linus Walleij <[email protected]>
Cc Kukjin Kim <[email protected]>

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

Quoted 20 lines
Cc Pawel Moll <[email protected]>
[will: cosmetic edits and actual removal of the enum type]
---
 arch/arm/include/asm/pmu.h               |   10 ----------
 arch/arm/mach-bcmring/arch.c             |    3 +--
 arch/arm/mach-omap2/devices.c            |    3 +--
 arch/arm/mach-pxa/devices.c              |    3 +--
 arch/arm/mach-realview/realview_eb.c     |    3 +--
 arch/arm/mach-realview/realview_pb1176.c |    3 +--
 arch/arm/mach-realview/realview_pb11mp.c |    3 +--
 arch/arm/mach-realview/realview_pba8.c   |    3 +--
 arch/arm/mach-realview/realview_pbx.c    |    3 +--
 arch/arm/mach-tegra/devices.c            |    3 +--
 arch/arm/mach-ux500/cpu-db8500.c         |    3 +--
 arch/arm/mach-vexpress/ct-ca9x4.c        |    3 +--
 arch/arm/plat-iop/pmu.c                  |    3 +--
 arch/arm/plat-samsung/devs.c             |    3 +--
 14 files changed, 13 insertions(+), 36 deletions(-)
#18 lore raw

PATCH 5/9 ARM: perf: remove mysterious compiler barrier

In reply to Will Deacon

There's a rather strange compiler barrier in the PMU disabling code which was presumably placed there by aliens. There's no valid reason for the barrier and one can only suspect that it's up to no good.

This patch removes it before it has a chance to spread.

---
 arch/arm/kernel/perf_event.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
arch/arm/kernel/perf_event.c +0 -1
index 1ac1531..22ed512 100644
@@ -223,7 +223,6 @@ armpmu_stop(struct perf_event *event, int flags)
 	 */
 	if (!(hwc->state & PERF_HES_STOPPED)) {
 		armpmu->disable(hwc, hwc->idx);
-		barrier(); /* why? */
 		armpmu_event_update(event, hwc, hwc->idx);
 		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
 	}
Signature · 1 line
1.7.4.1
#19 lore raw

PATCH 6/9 ARM: perf: probe devicetree in preference to current CPU

In reply to Will Deacon

The CPU PMU is probed using the current cpuid information as part of the early_initcall initialising the architecture perf backend. For architectures without NMI (such as ARM), this does not need to be performed early and can be deferred to the driver probe callback. This also allows us to probe the devicetree in preference to parsing the current cpuid, which may be invalid on a big.LITTLE multi-cluster system.

This patch defers the PMU probing and uses the devicetree information when available.

---
 arch/arm/kernel/perf_event.c        |  175 ++++++++++++++++++-----------------
 arch/arm/kernel/perf_event_v6.c     |    8 +-
 arch/arm/kernel/perf_event_v7.c     |   22 ++--
 arch/arm/kernel/perf_event_xscale.c |    8 +-
 4 files changed, 110 insertions(+), 103 deletions(-)
arch/arm/kernel/perf_event.c +91 -84
index 22ed512..7c29914 100644
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/export.h>
+#include <linux/of.h>
 #include <linux/perf_event.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
@@ -610,9 +611,11 @@ static void __init armpmu_init(struct arm_pmu *armpmu)
 	};
 }
 
-int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type)
+int armpmu_register(struct arm_pmu *armpmu, char *name, int type)
 {
 	armpmu_init(armpmu);
+	pr_info("enabled with %s PMU driver, %d counters available\n",
+			armpmu->name, armpmu->num_events);
 	return perf_pmu_register(&armpmu->pmu, name, type);
 }
 
@@ -621,74 +624,12 @@ int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type)
 #include "perf_event_v6.c"
 #include "perf_event_v7.c"
 
-/*
- * Ensure the PMU has sane values out of reset.
- * This requires SMP to be available, so exists as a separate initcall.
- */
-static int __init
-cpu_pmu_reset(void)
-{
-	if (cpu_pmu && cpu_pmu->reset)
-		return on_each_cpu(cpu_pmu->reset, NULL, 1);
-	return 0;
-}
-arch_initcall(cpu_pmu_reset);
-
-/*
- * PMU platform driver and devicetree bindings.
- */
-static struct of_device_id armpmu_of_device_ids[] = {
-	{.compatible = "arm,cortex-a15-pmu"},
-	{.compatible = "arm,cortex-a9-pmu"},
-	{.compatible = "arm,cortex-a8-pmu"},
-	{.compatible = "arm,cortex-a7-pmu"},
-	{.compatible = "arm,cortex-a5-pmu"},
-	{.compatible = "arm,arm11mpcore-pmu"},
-	{.compatible = "arm,arm1176-pmu"},
-	{.compatible = "arm,arm1136-pmu"},
-	{},
-};
-
-static struct platform_device_id armpmu_plat_device_ids[] = {
-	{.name = "arm-pmu"},
-	{},
-};
-
-static int __devinit armpmu_device_probe(struct platform_device *pdev)
-{
-	if (!cpu_pmu)
-		return -ENODEV;
-
-	cpu_pmu->plat_device = pdev;
-	return 0;
-}
-
-static const struct dev_pm_ops armpmu_dev_pm_ops = {
-	SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
-};
-
-static struct platform_driver armpmu_driver = {
-	.driver		= {
-		.name	= "arm-pmu",
-		.pm	= &armpmu_dev_pm_ops,
-		.of_match_table = armpmu_of_device_ids,
-	},
-	.probe		= armpmu_device_probe,
-	.id_table	= armpmu_plat_device_ids,
-};
-
-static int __init register_pmu_driver(void)
-{
-	return platform_driver_register(&armpmu_driver);
-}
-device_initcall(register_pmu_driver);
-
 static struct pmu_hw_events *armpmu_get_cpu_events(void)
 {
 	return &__get_cpu_var(cpu_hw_events);
 }
 
-static void __init cpu_pmu_init(struct arm_pmu *armpmu)
+static void __devinit cpu_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	int cpu;
 	for_each_possible_cpu(cpu) {
@@ -697,7 +638,11 @@ static void __init cpu_pmu_init(struct arm_pmu *armpmu)
 		events->used_mask = per_cpu(used_mask, cpu);
 		raw_spin_lock_init(&events->pmu_lock);
 	}
-	armpmu->get_hw_events = armpmu_get_cpu_events;
+	cpu_pmu->get_hw_events = armpmu_get_cpu_events;
+
+	/* Ensure the PMU has sane values out of reset. */
+	if (cpu_pmu && cpu_pmu->reset)
+		on_each_cpu(cpu_pmu->reset, NULL, 1);
 }
 
 /*
@@ -722,41 +667,68 @@ static struct notifier_block __cpuinitdata pmu_cpu_notifier = {
 	.notifier_call = pmu_cpu_notify,
 };
 
+static const struct dev_pm_ops armpmu_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
+};
+
+/*
+ * PMU platform driver and devicetree bindings.
+ */
+static struct of_device_id __devinitdata cpu_pmu_of_device_ids[] = {
+	{.compatible = "arm,cortex-a15-pmu",	.data = armv7_a15_pmu_init},
+	{.compatible = "arm,cortex-a9-pmu",	.data = armv7_a9_pmu_init},
+	{.compatible = "arm,cortex-a8-pmu",	.data = armv7_a8_pmu_init},
+	{.compatible = "arm,cortex-a7-pmu",	.data = armv7_a7_pmu_init},
+	{.compatible = "arm,cortex-a5-pmu",	.data = armv7_a5_pmu_init},
+	{.compatible = "arm,arm11mpcore-pmu",	.data = armv6mpcore_pmu_init},
+	{.compatible = "arm,arm1176-pmu",	.data = armv6pmu_init},
+	{.compatible = "arm,arm1136-pmu",	.data = armv6pmu_init},
+	{},
+};
+
+static struct platform_device_id __devinitdata cpu_pmu_plat_device_ids[] = {
+	{.name = "arm-pmu"},
+	{},
+};
+
 /*
- * CPU PMU identification and registration.
+ * CPU PMU identification and probing.
  */
-static int __init
-init_hw_perf_events(void)
+static struct arm_pmu *__devinit probe_current_pmu(void)
 {
+	struct arm_pmu *pmu = NULL;
+	int cpu = get_cpu();
 	unsigned long cpuid = read_cpuid_id();
 	unsigned long implementor = (cpuid & 0xFF000000) >> 24;
 	unsigned long part_number = (cpuid & 0xFFF0);
 
+	pr_info("probing PMU on CPU %d\n", cpu);
+
 	/* ARM Ltd CPUs. */
 	if (0x41 == implementor) {
 		switch (part_number) {
 		case 0xB360:	/* ARM1136 */
 		case 0xB560:	/* ARM1156 */
 		case 0xB760:	/* ARM1176 */
-			cpu_pmu = armv6pmu_init();
+			pmu = armv6pmu_init();
 			break;
 		case 0xB020:	/* ARM11mpcore */
-			cpu_pmu = armv6mpcore_pmu_init();
+			pmu = armv6mpcore_pmu_init();
 			break;
 		case 0xC080:	/* Cortex-A8 */
-			cpu_pmu = armv7_a8_pmu_init();
+			pmu = armv7_a8_pmu_init();
 			break;
 		case 0xC090:	/* Cortex-A9 */
-			cpu_pmu = armv7_a9_pmu_init();
+			pmu = armv7_a9_pmu_init();
 			break;
 		case 0xC050:	/* Cortex-A5 */
-			cpu_pmu = armv7_a5_pmu_init();
+			pmu = armv7_a5_pmu_init();
 			break;
 		case 0xC0F0:	/* Cortex-A15 */
-			cpu_pmu = armv7_a15_pmu_init();
+			pmu = armv7_a15_pmu_init();
 			break;
 		case 0xC070:	/* Cortex-A7 */
-			cpu_pmu = armv7_a7_pmu_init();
+			pmu = armv7_a7_pmu_init();
 			break;
 		}
 	/* Intel CPUs [xscale]. */
@@ -764,27 +736,62 @@ init_hw_perf_events(void)
 		part_number = (cpuid >> 13) & 0x7;
 		switch (part_number) {
 		case 1:
-			cpu_pmu = xscale1pmu_init();
+			pmu = xscale1pmu_init();
 			break;
 		case 2:
-			cpu_pmu = xscale2pmu_init();
+			pmu = xscale2pmu_init();
 			break;
 		}
 	}
 
+	put_cpu();
+	return pmu;
+}
+
+static int __devinit cpu_pmu_device_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *of_id;
+	struct arm_pmu *(*init_fn)(void);
+	struct device_node *node = pdev->dev.of_node;
+
 	if (cpu_pmu) {
-		pr_info("enabled with %s PMU driver, %d counters available\n",
-			cpu_pmu->name, cpu_pmu->num_events);
-		cpu_pmu_init(cpu_pmu);
-		register_cpu_notifier(&pmu_cpu_notifier);
-		armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW);
+		pr_info("attempt to register multiple PMU devices!");
+		return -ENOSPC;
+	}
+
+	if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
+		init_fn = of_id->data;
+		cpu_pmu = init_fn();
 	} else {
-		pr_info("no hardware support available\n");
+		cpu_pmu = probe_current_pmu();
 	}
 
+	if (!cpu_pmu)
+		return -ENODEV;
+
+	cpu_pmu->plat_device = pdev;
+	cpu_pmu_init(cpu_pmu);
+	register_cpu_notifier(&pmu_cpu_notifier);
+	armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW);
+
 	return 0;
 }
-early_initcall(init_hw_perf_events);
+
+static struct platform_driver cpu_pmu_driver = {
+	.driver		= {
+		.name	= "arm-pmu",
+		.pm	= &armpmu_dev_pm_ops,
+		.of_match_table = cpu_pmu_of_device_ids,
+	},
+	.probe		= cpu_pmu_device_probe,
+	.id_table	= cpu_pmu_plat_device_ids,
+};
+
+static int __init register_pmu_driver(void)
+{
+	return platform_driver_register(&cpu_pmu_driver);
+}
+device_initcall(register_pmu_driver);
 
 /*
  * Callchain handling code.
arch/arm/kernel/perf_event_v6.c +4 -4
index c90fcb2..a4328b1 100644
@@ -664,7 +664,7 @@ static struct arm_pmu armv6pmu = {
 	.max_period		= (1LLU << 32) - 1,
 };
 
-static struct arm_pmu *__init armv6pmu_init(void)
+static struct arm_pmu *__devinit armv6pmu_init(void)
 {
 	return &armv6pmu;
 }
@@ -698,17 +698,17 @@ static struct arm_pmu armv6mpcore_pmu = {
 	.max_period		= (1LLU << 32) - 1,
 };
 
-static struct arm_pmu *__init armv6mpcore_pmu_init(void)
+static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
 {
 	return &armv6mpcore_pmu;
 }
 #else
-static struct arm_pmu *__init armv6pmu_init(void)
+static struct arm_pmu *__devinit armv6pmu_init(void)
 {
 	return NULL;
 }
 
-static struct arm_pmu *__init armv6mpcore_pmu_init(void)
+static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
 {
 	return NULL;
 }
arch/arm/kernel/perf_event_v7.c +11 -11
index f04070b..d65a1b8 100644
@@ -1245,7 +1245,7 @@ static struct arm_pmu armv7pmu = {
 	.max_period		= (1LLU << 32) - 1,
 };
 
-static u32 __init armv7_read_num_pmnc_events(void)
+static u32 __devinit armv7_read_num_pmnc_events(void)
 {
 	u32 nb_cnt;
 
@@ -1256,7 +1256,7 @@ static u32 __init armv7_read_num_pmnc_events(void)
 	return nb_cnt + 1;
 }
 
-static struct arm_pmu *__init armv7_a8_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a8_pmu_init(void)
 {
 	armv7pmu.name		= "ARMv7 Cortex-A8";
 	armv7pmu.map_event	= armv7_a8_map_event;
@@ -1264,7 +1264,7 @@ static struct arm_pmu *__init armv7_a8_pmu_init(void)
 	return &armv7pmu;
 }
 
-static struct arm_pmu *__init armv7_a9_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a9_pmu_init(void)
 {
 	armv7pmu.name		= "ARMv7 Cortex-A9";
 	armv7pmu.map_event	= armv7_a9_map_event;
@@ -1272,7 +1272,7 @@ static struct arm_pmu *__init armv7_a9_pmu_init(void)
 	return &armv7pmu;
 }
 
-static struct arm_pmu *__init armv7_a5_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a5_pmu_init(void)
 {
 	armv7pmu.name		= "ARMv7 Cortex-A5";
 	armv7pmu.map_event	= armv7_a5_map_event;
@@ -1280,7 +1280,7 @@ static struct arm_pmu *__init armv7_a5_pmu_init(void)
 	return &armv7pmu;
 }
 
-static struct arm_pmu *__init armv7_a15_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a15_pmu_init(void)
 {
 	armv7pmu.name		= "ARMv7 Cortex-A15";
 	armv7pmu.map_event	= armv7_a15_map_event;
@@ -1289,7 +1289,7 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
 	return &armv7pmu;
 }
 
-static struct arm_pmu *__init armv7_a7_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a7_pmu_init(void)
 {
 	armv7pmu.name		= "ARMv7 Cortex-A7";
 	armv7pmu.map_event	= armv7_a7_map_event;
@@ -1298,27 +1298,27 @@ static struct arm_pmu *__init armv7_a7_pmu_init(void)
 	return &armv7pmu;
 }
 #else
-static struct arm_pmu *__init armv7_a8_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a8_pmu_init(void)
 {
 	return NULL;
 }
 
-static struct arm_pmu *__init armv7_a9_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a9_pmu_init(void)
 {
 	return NULL;
 }
 
-static struct arm_pmu *__init armv7_a5_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a5_pmu_init(void)
 {
 	return NULL;
 }
 
-static struct arm_pmu *__init armv7_a15_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a15_pmu_init(void)
 {
 	return NULL;
 }
 
-static struct arm_pmu *__init armv7_a7_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a7_pmu_init(void)
 {
 	return NULL;
 }
arch/arm/kernel/perf_event_xscale.c +4 -4
index f759fe0..dcc478c 100644
@@ -449,7 +449,7 @@ static struct arm_pmu xscale1pmu = {
 	.max_period	= (1LLU << 32) - 1,
 };
 
-static struct arm_pmu *__init xscale1pmu_init(void)
+static struct arm_pmu *__devinit xscale1pmu_init(void)
 {
 	return &xscale1pmu;
 }
@@ -816,17 +816,17 @@ static struct arm_pmu xscale2pmu = {
 	.max_period	= (1LLU << 32) - 1,
 };
 
-static struct arm_pmu *__init xscale2pmu_init(void)
+static struct arm_pmu *__devinit xscale2pmu_init(void)
 {
 	return &xscale2pmu;
 }
 #else
-static struct arm_pmu *__init xscale1pmu_init(void)
+static struct arm_pmu *__devinit xscale1pmu_init(void)
 {
 	return NULL;
 }
 
-static struct arm_pmu *__init xscale2pmu_init(void)
+static struct arm_pmu *__devinit xscale2pmu_init(void)
 {
 	return NULL;
 }
Signature · 1 line
1.7.4.1
#20 lore raw

PATCH 7/9 ARM: perf: prepare for moving CPU PMU code into separate file

In reply to Will Deacon

The CPU PMU code is tightly coupled with generic ARM PMU handling code. This makes it cumbersome when trying to add support for other ARM PMUs (e.g. interconnect, L2 cache controller, bus) as the generic parts of the code are not readily reusable.

This patch cleans up perf_event.c so that reusable code is exposed via header files to other potential PMU drivers. The CPU code is consistently named to identify it as such and also to prepare for moving it into a separate file.

---
 arch/arm/include/asm/perf_event.h   |    9 ++++-
 arch/arm/include/asm/pmu.h          |   11 +++++-
 arch/arm/kernel/perf_event.c        |   69 ++++++++++++++---------------------
 arch/arm/kernel/perf_event_v6.c     |    4 +-
 arch/arm/kernel/perf_event_v7.c     |   10 +++---
 arch/arm/kernel/perf_event_xscale.c |    2 +-
 6 files changed, 53 insertions(+), 52 deletions(-)
arch/arm/include/asm/perf_event.h +8 -1
index e074948..625cd62 100644
@@ -12,6 +12,13 @@
 #ifndef __ARM_PERF_EVENT_H__
 #define __ARM_PERF_EVENT_H__
 
-/* Nothing to see here... */
+/*
+ * The ARMv7 CPU PMU supports up to 32 event counters.
+ */
+#define ARMPMU_MAX_HWEVENTS		32
+
+#define HW_OP_UNSUPPORTED		0xFFFF
+#define C(_x)				PERF_COUNT_HW_CACHE_##_x
+#define CACHE_OP_UNSUPPORTED		0xFFFF
 
 #endif /* __ARM_PERF_EVENT_H__ */
arch/arm/include/asm/pmu.h +10 -1
index fbec73a..a993ad6 100644
@@ -89,7 +89,9 @@ struct arm_pmu {
 
 #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
 
-int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type);
+extern const struct dev_pm_ops armpmu_dev_pm_ops;
+
+int armpmu_register(struct arm_pmu *armpmu, char *name, int type);
 
 u64 armpmu_event_update(struct perf_event *event,
 			struct hw_perf_event *hwc,
@@ -99,6 +101,13 @@ int armpmu_event_set_period(struct perf_event *event,
 			    struct hw_perf_event *hwc,
 			    int idx);
 
+int armpmu_map_event(struct perf_event *event,
+		     const unsigned (*event_map)[PERF_COUNT_HW_MAX],
+		     const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
+						[PERF_COUNT_HW_CACHE_OP_MAX]
+						[PERF_COUNT_HW_CACHE_RESULT_MAX],
+		     u32 raw_event_mask);
+
 #endif /* CONFIG_HW_PERF_EVENTS */
 
 #endif /* __ARM_PMU_H__ */
arch/arm/kernel/perf_event.c +27 -42

139 lines not on this page · raw message

arch/arm/kernel/perf_event_v6.c +2 -2
index a4328b1..6ccc079 100644
@@ -645,7 +645,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
 
 static int armv6_map_event(struct perf_event *event)
 {
-	return map_cpu_event(event, &armv6_perf_map,
+	return armpmu_map_event(event, &armv6_perf_map,
 				&armv6_perf_cache_map, 0xFF);
 }
 
@@ -679,7 +679,7 @@ static struct arm_pmu *__devinit armv6pmu_init(void)
 
 static int armv6mpcore_map_event(struct perf_event *event)
 {
-	return map_cpu_event(event, &armv6mpcore_perf_map,
+	return armpmu_map_event(event, &armv6mpcore_perf_map,
 				&armv6mpcore_perf_cache_map, 0xFF);
 }
 
arch/arm/kernel/perf_event_v7.c +5 -5
index d65a1b8..bd4b090 100644
@@ -1204,31 +1204,31 @@ static void armv7pmu_reset(void *info)
 
 static int armv7_a8_map_event(struct perf_event *event)
 {
-	return map_cpu_event(event, &armv7_a8_perf_map,
+	return armpmu_map_event(event, &armv7_a8_perf_map,
 				&armv7_a8_perf_cache_map, 0xFF);
 }
 
 static int armv7_a9_map_event(struct perf_event *event)
 {
-	return map_cpu_event(event, &armv7_a9_perf_map,
+	return armpmu_map_event(event, &armv7_a9_perf_map,
 				&armv7_a9_perf_cache_map, 0xFF);
 }
 
 static int armv7_a5_map_event(struct perf_event *event)
 {
-	return map_cpu_event(event, &armv7_a5_perf_map,
+	return armpmu_map_event(event, &armv7_a5_perf_map,
 				&armv7_a5_perf_cache_map, 0xFF);
 }
 
 static int armv7_a15_map_event(struct perf_event *event)
 {
-	return map_cpu_event(event, &armv7_a15_perf_map,
+	return armpmu_map_event(event, &armv7_a15_perf_map,
 				&armv7_a15_perf_cache_map, 0xFF);
 }
 
 static int armv7_a7_map_event(struct perf_event *event)
 {
-	return map_cpu_event(event, &armv7_a7_perf_map,
+	return armpmu_map_event(event, &armv7_a7_perf_map,
 				&armv7_a7_perf_cache_map, 0xFF);
 }
 
arch/arm/kernel/perf_event_xscale.c +1 -1
index dcc478c..426e19f 100644
@@ -430,7 +430,7 @@ xscale1pmu_write_counter(int counter, u32 val)
 
 static int xscale_map_event(struct perf_event *event)
 {
-	return map_cpu_event(event, &xscale_perf_map,
+	return armpmu_map_event(event, &xscale_perf_map,
 				&xscale_perf_cache_map, 0xFF);
 }
 
Signature · 1 line
1.7.4.1
#21 lore raw

PATCH 8/9 ARM: perf: move CPU-specific PMU handling code into separate file

In reply to Will Deacon

This patch moves the CPU-specific PMU handling code out of perf_event.c and into perf_event_cpu.c.

---
 arch/arm/kernel/Makefile         |    2 +-
 arch/arm/kernel/perf_event.c     |  211 +----------------------------------
 arch/arm/kernel/perf_event_cpu.c |  231 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 233 insertions(+), 211 deletions(-)
 create mode 100644 arch/arm/kernel/perf_event_cpu.c
arch/arm/kernel/Makefile +1 -1
index cfbe3b4..1c43214 100644
@@ -69,7 +69,7 @@ obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
+obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o perf_event_cpu.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
 obj-$(CONFIG_ARM_CPU_TOPOLOGY)  += topology.o
 
arch/arm/kernel/perf_event.c +1 -210

231 lines not on this page · raw message

arch/arm/kernel/perf_event_cpu.c new file +231 -0

231 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#22 lore raw

PATCH 9/9 ARM: perf: move irq registration into pmu implementation

In reply to Will Deacon

From: Sudeep KarkadaNagesha <[email protected]>

This patch moves the CPU-specific IRQ registration and parsing code into the CPU PMU backend. This is required because a PMU may have more than one interrupt, which in turn can be either PPI (per-cpu) or SPI (requiring strict affinity setting at the interrupt distributor).

[will: cosmetic edits and reworked interrupt dispatching]
---
 arch/arm/include/asm/pmu.h       |    2 +
 arch/arm/kernel/perf_event.c     |   72 ++++++-------------------------------
 arch/arm/kernel/perf_event_cpu.c |   66 ++++++++++++++++++++++++++++++++++-
 3 files changed, 79 insertions(+), 61 deletions(-)
arch/arm/include/asm/pmu.h +2 -0
index a993ad6..a26170d 100644
@@ -78,6 +78,8 @@ struct arm_pmu {
 	void		(*start)(void);
 	void		(*stop)(void);
 	void		(*reset)(void *);
+	int		(*request_irq)(irq_handler_t handler);
+	void		(*free_irq)(void);
 	int		(*map_event)(struct perf_event *event);
 	int		num_events;
 	atomic_t	active_events;
arch/arm/kernel/perf_event.c +12 -60

99 lines not on this page · raw message

arch/arm/kernel/perf_event_cpu.c +65 -1

78 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#23 lore raw

cover ARM perf updates for 3.7

In reply to Will Deacon

Hi Will Deacon,

For SMP platforms, each CPU core has an independent PMU, and each PMU has a dedicated irq (SPI or PPI). Current perf subsystem framework only supports each PMU to have a dedicated SPI irq, and it will support each PMU to have a PPI irq (i have seen someone has sent out the patches), but there is a situation the subsystem doesn't support yet, the situation is multi PMUs share one same SPI irq, e.g. the i.MX6Quad CPU has 4 cortex-a9 cores, each core has a PMU, all PMU irqs are routed (ORed) to one SPI irq, do you know how to support this situation?

Regards,
Hui.

Quoted 64 lines · Will Deacon

Hello,

This patch series contains the ARM perf updates I'd like to push for 3.7 Most of the code is cleanup in preparation for big.LITTLE PMU support, where we will need to support different types of CPU PMU on the same SoC.

The PMU probing has changed so that we try to identify the PMU using its DT binding before falling back to probing the current core. The unused PMU registration mechanism is also removed and platforms registering the device have been updated accordingly.

Given that this touches a few platforms, I anticipate sending it via arm-soc.

All feedback welcome,

Will

Jon Hunter (1):
ARM: PMU: Add runtime PM Support

Sudeep KarkadaNagesha (2):
ARM: pmu: remove arm_pmu_type enumeration
ARM: perf: move irq registration into pmu implementation

Will Deacon (6):
ARM: perf: add devicetree bindings for 11MPcore, A5, A7 and A15 PMUs
ARM: pmu: remove unused reservation mechanism
ARM: perf: remove mysterious compiler barrier
ARM: perf: probe devicetree in preference to current CPU
ARM: perf: prepare for moving CPU PMU code into separate file
ARM: perf: move CPU-specific PMU handling code into separate file

 Documentation/devicetree/bindings/arm/pmu.txt |    4 +
 MAINTAINERS                                   |    1 -
 arch/arm/Kconfig                              |    8 +-
 arch/arm/include/asm/perf_event.h             |    9 +-
 arch/arm/include/asm/pmu.h                    |   77 ++----
 arch/arm/kernel/Makefile                      |    3 +-
 arch/arm/kernel/perf_event.c                  |  347 ++++---------------------
 arch/arm/kernel/perf_event_cpu.c              |  295 +++++++++++++++++++++
 arch/arm/kernel/perf_event_v6.c               |   12 +-
 arch/arm/kernel/perf_event_v7.c               |   32 ++--
 arch/arm/kernel/perf_event_xscale.c           |   10 +-
 arch/arm/kernel/pmu.c                         |   36 ---
 arch/arm/mach-bcmring/arch.c                  |    3 +-
 arch/arm/mach-omap2/devices.c                 |    3 +-
 arch/arm/mach-pxa/devices.c                   |    3 +-
 arch/arm/mach-realview/realview_eb.c          |    3 +-
 arch/arm/mach-realview/realview_pb1176.c      |    3 +-
 arch/arm/mach-realview/realview_pb11mp.c      |    3 +-
 arch/arm/mach-realview/realview_pba8.c        |    3 +-
 arch/arm/mach-realview/realview_pbx.c         |    3 +-
 arch/arm/mach-tegra/devices.c                 |    3 +-
 arch/arm/mach-ux500/cpu-db8500.c              |    3 +-
 arch/arm/mach-vexpress/ct-ca9x4.c             |    3 +-
 arch/arm/plat-iop/pmu.c                       |    3 +-
 arch/arm/plat-samsung/devs.c                  |    3 +-
 25 files changed, 424 insertions(+), 449 deletions(-)
 create mode 100644 arch/arm/kernel/perf_event_cpu.c
 delete mode 100644 arch/arm/kernel/pmu.c
#24 lore raw

cover ARM perf updates for 3.7

Quoted 1 line · Hui Wang

Hi Will Deacon,

Hello,

Quoted 8 lines

For SMP platforms, each CPU core has an independent PMU, and each PMU has a dedicated irq (SPI or PPI). Current perf subsystem framework only supports each PMU to have a dedicated SPI irq, and it will support each PMU to have a PPI irq (i have seen someone has sent out the patches), but there is a situation the subsystem doesn't support yet, the situation is multi PMUs share one same SPI irq, e.g. the i.MX6Quad CPU has 4 cortex-a9 cores, each core has a PMU, all PMU irqs are routed (ORed) to one SPI irq, do you know how to support this situation?

That's what I like to call a braindead, broken system. Seriously, CPU PMU interrupts *can only* be handled on the CPU which raised them -- ORing these things together means ping-ponging the interrupt affinity around until we find the right guy. There's also the fun case where multiple PMUs assert simultaneously and I've even heard about platforms where they OR in the bloody L2 PMU interrupt as well for good measure!

If you have to support such a device, take a look at the ux500 code (db8500_pmu_handler), but please take all of your profiling numbers with a pinch of salt. For a quad-core processor, the numbers will probably be even less accurate.

Also, please go ahead and inflict sufficient injuries to your hardware guys that they stop this madness!

Will

#25 lore raw

cover ARM perf updates for 3.7

Quoted 25 lines · Will Deacon
Quoted 2 lines · Hui Wang

Hi Will Deacon,

Hello,

Quoted 9 lines

For SMP platforms, each CPU core has an independent PMU, and each PMU has a dedicated irq (SPI or PPI). Current perf subsystem framework only supports each PMU to have a dedicated SPI irq, and it will support each PMU to have a PPI irq (i have seen someone has sent out the patches), but there is a situation the subsystem doesn't support yet, the situation is multi PMUs share one same SPI irq, e.g. the i.MX6Quad CPU has 4 cortex-a9 cores, each core has a PMU, all PMU irqs are routed (ORed) to one SPI irq, do you know how to support this situation?

That's what I like to call a braindead, broken system. Seriously, CPU PMU interrupts *can only* be handled on the CPU which raised them -- ORing these things together means ping-ponging the interrupt affinity around until we find the right guy. There's also the fun case where multiple PMUs assert simultaneously and I've even heard about platforms where they OR in the bloody L2 PMU interrupt as well for good measure!

Quoted 8 lines

If you have to support such a device, take a look at the ux500 code (db8500_pmu_handler), but please take all of your profiling numbers with a pinch of salt. For a quad-core processor, the numbers will probably be even less accurate.

Also, please go ahead and inflict sufficient injuries to your hardware guys that they stop this madness!

Got it, thanks for the information, it is very useful.

Regards,
Hui.

Quoted 3 lines

Will

#26 lore raw

i.MX6Quad PMU irq handling (was: Re: [PATCH 0/9] ARM perf updates for 3.7)

Hi Hui,

Quoted 29 lines · Hui Wang
Quoted 28 lines · Will Deacon
Quoted 2 lines · Hui Wang

Hi Will Deacon,

Hello,

Quoted 9 lines

For SMP platforms, each CPU core has an independent PMU, and each PMU has a dedicated irq (SPI or PPI). Current perf subsystem framework only supports each PMU to have a dedicated SPI irq, and it will support each PMU to have a PPI irq (i have seen someone has sent out the patches), but there is a situation the subsystem doesn't support yet, the situation is multi PMUs share one same SPI irq, e.g. the i.MX6Quad CPU has 4 cortex-a9 cores, each core has a PMU, all PMU irqs are routed (ORed) to one SPI irq, do you know how to support this situation?

That's what I like to call a braindead, broken system. Seriously, CPU PMU interrupts *can only* be handled on the CPU which raised them -- ORing these things together means ping-ponging the interrupt affinity around until we find the right guy. There's also the fun case where multiple PMUs assert simultaneously and I've even heard about platforms where they OR in the bloody L2 PMU interrupt as well for good measure!

If you have to support such a device, take a look at the ux500 code (db8500_pmu_handler), but please take all of your profiling numbers with a pinch of salt. For a quad-core processor, the numbers will probably be even less accurate.

Quoted 4 lines
Quoted 3 lines

Also, please go ahead and inflict sufficient injuries to your hardware guys that they stop this madness!

Got it, thanks for the information, it is very useful.

Above you mention the the i.MX6Quad CPU.

Have you done any work/patches for the i.MX6Quad PMU to work with the ORed PMU irq?

Have you talked with the Freescale hardware guys "that they stop this madness"?

We are facing some issues using perf top on the i.MX6Quad:

http://www.spinics.net/lists/arm-kernel/msg227042.html

Many thanks and best regards

dirk

#27 lore raw

i.MX6Quad PMU irq handling (was: Re: [PATCH 0/9] ARM perf updates for 3.7)

Quoted 2 lines · Dirk Behme

Have you talked with the Freescale hardware guys "that they stop this madness"?

The feedback had gone to Freescale design team, and will be fixed in the future project.

Shawn

#28 lore raw

i.MX6Quad PMU irq handling

In reply to Dirk Behme
Quoted 43 lines · Dirk Behme

Hi Hui,

Quoted 40 lines · Hui Wang
Quoted 39 lines · Will Deacon
Quoted 2 lines · Hui Wang

Hi Will Deacon,

Hello,

Quoted 10 lines

For SMP platforms, each CPU core has an independent PMU, and each PMU has a dedicated irq (SPI or PPI). Current perf subsystem framework only supports each PMU to have a dedicated SPI irq, and it will support each PMU to have a PPI irq (i have seen someone has sent out the patches), but there is a situation the subsystem doesn't support yet, the situation is multi PMUs share one same SPI irq, e.g. the i.MX6Quad CPU has 4 cortex-a9 cores, each core has a PMU, all PMU irqs are routed (ORed) to one SPI irq, do you know how to support this situation?

That's what I like to call a braindead, broken system. Seriously, CPU PMU
interrupts *can only* be handled on the CPU which raised them -- ORing these
things together means ping-ponging the interrupt affinity around until we
find the right guy. There's also the fun case where multiple PMUs assert
simultaneously and I've even heard about platforms where they OR in the bloody L2 PMU interrupt as well for good measure!

If you have to support such a device, take a look at the ux500 code (db8500_pmu_handler), but please take all of your profiling numbers with a
pinch of salt. For a quad-core processor, the numbers will probably be even
less accurate.

Also, please go ahead and inflict sufficient injuries to your hardware guys
that they stop this madness!

Quoted 6 lines
Quoted 1 line

Got it, thanks for the information, it is very useful.

Above you mention the the i.MX6Quad CPU.

Have you done any work/patches for the i.MX6Quad PMU to work with the ORed PMU irq?

Not yet. i implement a pmu_handler similar to db8500_pmu_handler, but it can't work stable on the imx6q. With the increasing number of cpu cores, the situation is worse.

Quoted 3 lines

Have you talked with the Freescale hardware guys "that they stop this madness"?

As Shawn said, this issue has been reported to FSL.

Regards,
Hui.

Quoted 9 lines

We are facing some issues using perf top on the i.MX6Quad:

http://www.spinics.net/lists/arm-kernel/msg227042.html

Many thanks and best regards

dirk