devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
	will.deacon-5wv7dgnIgG8@public.gmane.org,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org
Subject: [RFC PATCH 10/11] arm: perf: allow multiple CPU PMUs to be registered
Date: Thu, 11 Apr 2013 10:12:41 +0100	[thread overview]
Message-ID: <1365671562-2403-11-git-send-email-mark.rutland@arm.com> (raw)
In-Reply-To: <1365671562-2403-1-git-send-email-mark.rutland-5wv7dgnIgG8@public.gmane.org>

In systems with multiple clusters, the CPUs may be different in each
cluster, and their PMUs may not be entirely compatible. As they cannot
be managed as one logical homogeneous unit, we will have to support each
set of compatible PMUs separately. To do so, we need to be able to
register and use multiple PMUs simultaneously.

This patch replaces the global cpu_pmu pointer with a list of cpu_pmus,
enabling multiple PMUs to be registered and used simultaneously.

Signed-off-by: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
---
 arch/arm/kernel/perf_event_cpu.c | 61 +++++++++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 23 deletions(-)

diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
index 6d8cbb1..4d6bfbb 100644
--- a/arch/arm/kernel/perf_event_cpu.c
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -37,7 +37,7 @@ struct cpu_pmu_irq {
 };
 
 /* Set at runtime when we know what CPU type we are. */
-static struct arm_pmu *cpu_pmu;
+static LIST_HEAD(pmus_list);
 
 /*
  * All of the dynamically sized pmu_hw data for the number of events supported
@@ -57,20 +57,28 @@ struct cpu_pmu {
 	struct cpu_pmu_hw __percpu *cpu_hw;
 	struct cpu_pmu_irq *interrupts;
 	int nr_irqs;
+	struct list_head list;
 };
 
 #define to_cpu_pmu(p) (container_of(p, struct cpu_pmu, armpmu))
 
+static void cpu_pmu_add(struct cpu_pmu *pmu)
+{
+	list_add_tail(&pmu->list, &pmus_list);
+}
+
 /*
  * Despite the names, these two functions are CPU-specific and are used
  * by the OProfile/perf code.
  */
 const char *perf_pmu_name(void)
 {
-	if (!cpu_pmu)
+	struct cpu_pmu *pmu = list_first_entry(&pmus_list,
+					       struct cpu_pmu, list);
+	if (!pmu)
 		return NULL;
 
-	return cpu_pmu->name;
+	return pmu->armpmu.name;
 }
 EXPORT_SYMBOL_GPL(perf_pmu_name);
 
@@ -78,8 +86,10 @@ int perf_num_counters(void)
 {
 	int max_events = 0;
 
-	if (cpu_pmu != NULL)
-		max_events = cpu_pmu->num_events;
+	struct cpu_pmu *pmu = list_first_entry(&pmus_list,
+					       struct cpu_pmu, list);
+	if (pmu != NULL)
+		max_events = pmu->armpmu.num_events;
 
 	return max_events;
 }
@@ -186,18 +196,26 @@ static int __cpuinit cpu_pmu_notify(struct notifier_block *b,
 				    unsigned long action, void *hcpu)
 {
 	int cpu = (long)hcpu;
+	int ret = NOTIFY_DONE;
+	struct cpu_pmu *cpu_pmu;
+
 	if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
-		return NOTIFY_DONE;
+		return ret;
 
-	if (!cpumask_test_cpu(cpu, &cpu_pmu->supported_cpus))
-		return NOTIFY_DONE;
+	list_for_each_entry(cpu_pmu, &pmus_list, list) {
+		struct arm_pmu *arm_pmu = &cpu_pmu->armpmu;
 
-	if (cpu_pmu && cpu_pmu->reset)
-		cpu_pmu->reset(cpu_pmu);
-	else
-		return NOTIFY_DONE;
+		if (!arm_pmu->reset)
+			continue;
+
+		if (!cpumask_test_cpu(cpu, &arm_pmu->supported_cpus))
+			continue;
 
-	return NOTIFY_OK;
+		arm_pmu->reset(arm_pmu);
+		ret = NOTIFY_OK;
+	}
+
+	return ret;
 }
 
 static struct notifier_block __cpuinitdata cpu_pmu_hotplug_notifier = {
@@ -360,11 +378,6 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
 	struct cpu_pmu *pmu;
 	int ret = -ENODEV;
 
-	if (cpu_pmu) {
-		pr_info("attempt to register multiple PMU devices!");
-		return -ENOSPC;
-	}
-
 	pmu = kzalloc(sizeof(*pmu), GFP_KERNEL);
 	if (!pmu) {
 		pr_info("failed to allocate PMU device!");
@@ -396,13 +409,15 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
 		goto out_hw;
 	}
 
-	cpu_pmu = &pmu->armpmu;
-	cpu_pmu->plat_device = pdev;
+	pmu->armpmu.plat_device = pdev;
 	cpu_pmu_init(pmu);
-	ret = armpmu_register(cpu_pmu, -1);
 
-	if (!ret)
-		return 0;
+	ret = armpmu_register(&pmu->armpmu, -1);
+	if (ret)
+		goto out_hw;
+
+	cpu_pmu_add(pmu);
+	return 0;
 
 out_hw:
 	free_percpu(pmu->cpu_hw);
-- 
1.8.1.1

  parent reply	other threads:[~2013-04-11  9:12 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-11  9:12 [RFC PATCH 00/11] Topology bindings / Perf for big.LITTLE systems Mark Rutland
     [not found] ` <1365671562-2403-1-git-send-email-mark.rutland-5wv7dgnIgG8@public.gmane.org>
2013-04-11  9:12   ` [RFC PATCH 01/11] Documentation: DT: arm: define CPU topology bindings Mark Rutland
2013-04-11 15:00     ` Rob Herring
2013-04-11 15:50       ` Lorenzo Pieralisi
2013-04-11 17:55         ` Rob Herring
2013-04-11 18:17           ` Dave Martin
     [not found]             ` <20130411181710.GC2239-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-04-12 11:27               ` Lorenzo Pieralisi
     [not found]           ` <5166F908.9050503-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-04-12 11:16             ` Lorenzo Pieralisi
2013-04-11 18:01         ` Dave Martin
     [not found]           ` <20130411180125.GB2239-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-04-12 11:44             ` Lorenzo Pieralisi
     [not found]               ` <20130412114457.GC6637-7AyDDHkRsp3ZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
2013-04-12 14:36                 ` Dave Martin
2013-04-12 16:59                   ` Lorenzo Pieralisi
2013-04-11  9:12   ` [RFC PATCH 02/11] arm: add functions to parse cpu affinity from dt Mark Rutland
2013-04-11  9:12   ` [RFC PATCH 03/11] arm: perf: clean up PMU names Mark Rutland
2013-04-11  9:12   ` [RFC PATCH 04/11] arm: perf: use IDR types for CPU PMUs Mark Rutland
2013-04-11  9:12   ` [RFC PATCH 05/11] arm: perf: make get_hw_events take arm_pmu Mark Rutland
2013-04-11  9:12   ` [RFC PATCH 06/11] arm: perf: dynamically allocate cpu hardware data Mark Rutland
2013-04-11  9:12   ` [RFC PATCH 07/11] arm: perf: treat PMUs as CPU affine Mark Rutland
2013-04-11  9:12   ` [RFC PATCH 08/11] arm: perf: probe number of counters on affine CPUs Mark Rutland
2013-04-11  9:12   ` [RFC PATCH 09/11] arm: perf: parse cpu affinity from dt Mark Rutland
2013-04-11  9:12   ` Mark Rutland [this message]
2013-04-11  9:12   ` [RFC PATCH 11/11] arm: dts: add all PMUs for A15x2 A7x3 coretile Mark Rutland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1365671562-2403-11-git-send-email-mark.rutland@arm.com \
    --to=mark.rutland-5wv7dgnigg8@public.gmane.org \
    --cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org \
    --cc=will.deacon-5wv7dgnIgG8@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).