From: tip-bot for Peter Zijlstra <a.p.zijlstra@chello.nl>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, hpa@zytor.com, mingo@redhat.com,
kay.sievers@vrfy.org, a.p.zijlstra@chello.nl, gregkh@suse.de,
tglx@linutronix.de, mingo@elte.hu
Subject: [tip:perf/core] perf: Sysfs enumeration
Date: Thu, 16 Dec 2010 12:33:13 GMT [thread overview]
Message-ID: <tip-abe43400579d5de0078c2d3a760e6598e183f871@git.kernel.org> (raw)
In-Reply-To: <20101117222056.316982569@chello.nl>
Commit-ID: abe43400579d5de0078c2d3a760e6598e183f871
Gitweb: http://git.kernel.org/tip/abe43400579d5de0078c2d3a760e6598e183f871
Author: Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Wed, 17 Nov 2010 23:17:37 +0100
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 16 Dec 2010 11:36:43 +0100
perf: Sysfs enumeration
Simple sysfs emumeration of the PMUs.
Use a "event_source" bus, and add PMU devices using their name.
Each PMU device has a type attribute which contrains the value needed
for perf_event_attr::type to identify this PMU.
This is the minimal stub needed to start using this interface,
we'll consider extending the sysfs usage later.
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Greg KH <gregkh@suse.de>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <20101117222056.316982569@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
include/linux/perf_event.h | 1 +
kernel/perf_event.c | 95 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 95 insertions(+), 1 deletions(-)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 21206d2..dda5b0a 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -588,6 +588,7 @@ struct perf_event;
struct pmu {
struct list_head entry;
+ struct device *dev;
char *name;
int type;
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 8f09bc8..11847bf 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -24,6 +24,7 @@
#include <linux/ptrace.h>
#include <linux/reboot.h>
#include <linux/vmstat.h>
+#include <linux/device.h>
#include <linux/vmalloc.h>
#include <linux/hardirq.h>
#include <linux/rculist.h>
@@ -5308,6 +5309,58 @@ out:
}
static struct idr pmu_idr;
+static ssize_t
+type_show(struct device *dev, struct device_attribute *attr, char *page)
+{
+ struct pmu *pmu = dev_get_drvdata(dev);
+
+ return snprintf(page, PAGE_SIZE-1, "%d\n", pmu->type);
+}
+
+static struct device_attribute pmu_dev_attrs[] = {
+ __ATTR_RO(type),
+ __ATTR_NULL,
+};
+
+static int pmu_bus_running;
+static struct bus_type pmu_bus = {
+ .name = "event_source",
+ .dev_attrs = pmu_dev_attrs,
+};
+
+static void pmu_dev_release(struct device *dev)
+{
+ kfree(dev);
+}
+
+static int pmu_dev_alloc(struct pmu *pmu)
+{
+ int ret = -ENOMEM;
+
+ pmu->dev = kzalloc(sizeof(struct device), GFP_KERNEL);
+ if (!pmu->dev)
+ goto out;
+
+ device_initialize(pmu->dev);
+ ret = dev_set_name(pmu->dev, "%s", pmu->name);
+ if (ret)
+ goto free_dev;
+
+ dev_set_drvdata(pmu->dev, pmu);
+ pmu->dev->bus = &pmu_bus;
+ pmu->dev->release = pmu_dev_release;
+ ret = device_add(pmu->dev);
+ if (ret)
+ goto free_dev;
+
+out:
+ return ret;
+
+free_dev:
+ put_device(pmu->dev);
+ goto out;
+}
+
int perf_pmu_register(struct pmu *pmu, char *name, int type)
{
int cpu, ret;
@@ -5336,6 +5389,12 @@ int perf_pmu_register(struct pmu *pmu, char *name, int type)
}
pmu->type = type;
+ if (pmu_bus_running) {
+ ret = pmu_dev_alloc(pmu);
+ if (ret)
+ goto free_idr;
+ }
+
skip_type:
pmu->pmu_cpu_context = find_pmu_context(pmu->task_ctx_nr);
if (pmu->pmu_cpu_context)
@@ -5343,7 +5402,7 @@ skip_type:
pmu->pmu_cpu_context = alloc_percpu(struct perf_cpu_context);
if (!pmu->pmu_cpu_context)
- goto free_ird;
+ goto free_dev;
for_each_possible_cpu(cpu) {
struct perf_cpu_context *cpuctx;
@@ -5387,6 +5446,10 @@ unlock:
return ret;
+free_dev:
+ device_del(pmu->dev);
+ put_device(pmu->dev);
+
free_idr:
if (pmu->type >= PERF_TYPE_MAX)
idr_remove(&pmu_idr, pmu->type);
@@ -5412,6 +5475,8 @@ void perf_pmu_unregister(struct pmu *pmu)
free_percpu(pmu->pmu_disable_count);
if (pmu->type >= PERF_TYPE_MAX)
idr_remove(&pmu_idr, pmu->type);
+ device_del(pmu->dev);
+ put_device(pmu->dev);
free_pmu_context(pmu);
}
@@ -6603,3 +6668,31 @@ void __init perf_event_init(void)
ret = init_hw_breakpoint();
WARN(ret, "hw_breakpoint initialization failed with: %d", ret);
}
+
+static int __init perf_event_sysfs_init(void)
+{
+ struct pmu *pmu;
+ int ret;
+
+ mutex_lock(&pmus_lock);
+
+ ret = bus_register(&pmu_bus);
+ if (ret)
+ goto unlock;
+
+ list_for_each_entry(pmu, &pmus, entry) {
+ if (!pmu->name || pmu->type < 0)
+ continue;
+
+ ret = pmu_dev_alloc(pmu);
+ WARN(ret, "Failed to register pmu: %s, reason %d\n", pmu->name, ret);
+ }
+ pmu_bus_running = 1;
+ ret = 0;
+
+unlock:
+ mutex_unlock(&pmus_lock);
+
+ return ret;
+}
+device_initcall(perf_event_sysfs_init);
next prev parent reply other threads:[~2010-12-16 12:33 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-17 22:17 [RFC][PATCH 0/8] perf sysfs bits Peter Zijlstra
2010-11-17 22:17 ` [RFC][PATCH 1/8] perf, x86: Fixup Kconfig deps Peter Zijlstra
2010-11-26 15:01 ` [tip:perf/core] " tip-bot for Peter Zijlstra
2010-11-17 22:17 ` [RFC][PATCH 2/8] perf, arch: Use early_initcall() for all arch pmu implementations Peter Zijlstra
2010-11-25 10:25 ` Peter Zijlstra
2010-11-25 14:47 ` Peter Zijlstra
2010-11-25 16:22 ` Will Deacon
2010-11-25 16:34 ` Peter Zijlstra
2010-11-25 17:55 ` Peter Zijlstra
2010-11-26 7:13 ` Paul Mundt
2010-11-26 9:41 ` Will Deacon
2010-11-26 15:05 ` [tip:perf/core] perf, arch: Cleanup perf-pmu init vs lockup-detector tip-bot for Peter Zijlstra
2010-11-17 22:17 ` [RFC][PATCH 3/8] perf: Move perf_event_init() into main.c Peter Zijlstra
2010-12-16 12:32 ` [tip:perf/core] " tip-bot for Peter Zijlstra
2010-11-17 22:17 ` [RFC][PATCH 4/8] perf: Use early_initcall() for tracepoint and breakpoint init Peter Zijlstra
2010-11-17 22:17 ` [RFC][PATCH 5/8] init: Initialized IRD earlier Peter Zijlstra
2010-12-16 12:32 ` [tip:perf/core] init: Initialized IDR earlier tip-bot for Peter Zijlstra
2010-11-17 22:17 ` [RFC][PATCH 6/8] perf: Dynamic pmu types Peter Zijlstra
2010-12-16 12:32 ` [tip:perf/core] " tip-bot for Peter Zijlstra
2010-11-17 22:17 ` [RFC][PATCH 7/8] perf: Sysfs enumeration Peter Zijlstra
2010-12-16 12:33 ` tip-bot for Peter Zijlstra [this message]
2010-11-17 22:17 ` [RFC][PATCH 8/8] perf: Sysfs events Peter Zijlstra
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=tip-abe43400579d5de0078c2d3a760e6598e183f871@git.kernel.org \
--to=a.p.zijlstra@chello.nl \
--cc=gregkh@suse.de \
--cc=hpa@zytor.com \
--cc=kay.sievers@vrfy.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.