[RFC 3/5] perf: adds a new pmu-initialization-call

Hans Rosenfeld
2011-12-16T16:12:46Z

From: Benjamin Block <benjamin.block@amd.com>

Adds a new call to the PMU-functions, which can be used by PMUs who
need information about the task and/or CPU for which the event shall
be initialized.

Signed-off-by: Benjamin Block <benjamin.block@amd.com>
Signed-off-by: Hans Rosenfeld <hans.rosenfeld@amd.com>
---
include/linux/perf_event.h | 2 ++
kernel/events/core.c | 17 +++++++++++++----
2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 81807bd..0c6fae6 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -630,6 +630,8 @@ struct pmu {
* Should return -ENOENT when the @event doesn't match this PMU.
*/
int (*event_init) (struct perf_event *event);
+ int (*event_init_for) (struct perf_event *event, int cpu,
+ struct task_struct *task);

#define PERF_EF_START 0x01 /* start the counter when adding */
#define PERF_EF_RELOAD 0x02 /* reload the counter when starting */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index faf52f7..fd18d70 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5746,7 +5746,8 @@ void perf_pmu_unregister(struct pmu *pmu)
free_pmu_context(pmu);
}

-struct pmu *perf_init_event(struct perf_event *event)
+struct pmu *perf_init_event(struct perf_event *event, int cpu,
+ struct task_struct *task)
{
struct pmu *pmu = NULL;
int idx;
@@ -5758,14 +5759,22 @@ struct pmu *perf_init_event(struct perf_event *event)
pmu = idr_find(&pmu_idr, event->attr.type);
rcu_read_unlock();
if (pmu) {
- ret = pmu->event_init(event);
+ if (pmu->event_init_for)
+ ret = pmu->event_init_for(event, cpu, task);
+ else
+ ret = pmu->event_init(event);
+
if (ret)
pmu = ERR_PTR(ret);
goto unlock;
}

list_for_each_entry_rcu(pmu, &pmus, entry) {
- ret = pmu->event_init(event);
+ if (pmu->event_init_for)
+ ret = pmu->event_init_for(event, cpu, task);
+ else
+ ret = pmu->event_init(event);
+
if (!ret)
goto unlock;

@@ -5875,7 +5884,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP))
goto done;

- pmu = perf_init_event(event);
+ pmu = perf_init_event(event, cpu, task);

done:
err = 0;
--
1.7.7