ARM perf updates for 3.7
Subsystems (10)
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
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.
--- 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
@@ -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
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_irqanddisable_irqadded by Ming Lei withruntime_resumeandruntime_suspendfuntions. Ming had added theenable_irqanddisable_irqfunctions 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 byenable_irqanddisable_irqinto the runtime PM callbacksruntime_resumeandruntime_suspend.Cc Ming Lei <[email protected]>Cc Benoit Cousson <[email protected]>Cc Paul Walmsley <[email protected]>Cc Kevin Hilman <[email protected]>Signed-off-by Jon Hunter <[email protected]>Signed-off-by Will Deacon <[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@@ -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@@ -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
-4irq =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
-0release_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
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
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
PATCH 2/9 ARM: perf: add devicetree bindings for 11MPcore, A5, A7 and A15 PMUs
In reply to Will DeaconThis 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.
--- 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
@@ -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
@@ -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
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]>Signed-off-by Will Deacon <[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@@ -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@@ -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" }, {}, };
PATCH 3/9 ARM: pmu: remove unused reservation mechanism
In reply to Will DeaconThe 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration
In reply to Will DeaconFrom: 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.
--- 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration
Quoted 11 lines · Will Deacon
From: Sudeep KarkadaNagesha <[email protected]>
The
arm_pmu_typeenumeration 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
PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration
In reply to Will DeaconQuoted 81 lines · Will Deacon
From: Sudeep KarkadaNagesha <[email protected]>
The
arm_pmu_typeenumeration 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]>Signed-off-by Sudeep KarkadaNagesha <[email protected]>[will: cosmetic edits and actual removal of the enum type]Signed-off-by Will Deacon <[email protected]>--- 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@@ -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@@ -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
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
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 structplatform_devicepmu_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->idis not being referred anywhere.ARM_PMU_DEVICE_CPUwas initially assigned to id to identify different PMU types throughplatform_device->idvariable 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
PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration
In reply to Will DeaconQuoted 11 lines · Will Deacon
From: Sudeep KarkadaNagesha <[email protected]>
The
arm_pmu_typeenumeration 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
PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration
In reply to Will DeaconHi Will, Tony,
Quoted 11 lines · Will Deacon
From: Sudeep KarkadaNagesha <[email protected]>
The
arm_pmu_typeenumeration 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@@ -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
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@@ -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
-1static 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
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@@ -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
-1static 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
PATCH 4/9 ARM: pmu: remove arm_pmu_type enumeration
In reply to Will DeaconQuoted 13 lines · Will Deacon
From: Sudeep KarkadaNagesha <[email protected]>
The
arm_pmu_typeenumeration 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]>Signed-off-by Sudeep KarkadaNagesha <[email protected]>[will: cosmetic edits and actual removal of the enum type]Signed-off-by Will Deacon <[email protected]>--- 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(-)
PATCH 5/9 ARM: perf: remove mysterious compiler barrier
In reply to Will DeaconThere'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
@@ -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
PATCH 6/9 ARM: perf: probe devicetree in preference to current CPU
In reply to Will DeaconThe 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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 7/9 ARM: perf: prepare for moving CPU PMU code into separate file
In reply to Will DeaconThe 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 8/9 ARM: perf: move CPU-specific PMU handling code into separate file
In reply to Will DeaconThis 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
@@ -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
PATCH 9/9 ARM: perf: move irq registration into pmu implementation
In reply to Will DeaconFrom: 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).
--- 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
@@ -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
cover ARM perf updates for 3.7
In reply to Will DeaconHi 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 SupportSudeep KarkadaNagesha (2):
ARM: pmu: removearm_pmu_typeenumeration
ARM: perf: move irq registration into pmu implementationWill 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 fileDocumentation/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
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
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
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
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
i.MX6Quad PMU irq handling
In reply to Dirk BehmeQuoted 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