Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 11/15] perf: simplify __perf_event_read

0 views
Skip to first unread message

Peter Zijlstra

unread,
Nov 20, 2009, 4:28:44 PM11/20/09
to Paul Mackerras, Ingo Molnar, Peter Zijlstra, linux-...@vger.kernel.org
perf-time-4.patch

Peter Zijlstra

unread,
Nov 20, 2009, 4:28:48 PM11/20/09
to Paul Mackerras, Ingo Molnar, Peter Zijlstra, linux-...@vger.kernel.org
perf-time-5.patch

Peter Zijlstra

unread,
Nov 20, 2009, 4:28:52 PM11/20/09
to Paul Mackerras, Ingo Molnar, Peter Zijlstra, linux-...@vger.kernel.org
perf-time-3.patch

Peter Zijlstra

unread,
Nov 20, 2009, 4:29:00 PM11/20/09
to Paul Mackerras, Ingo Molnar, Peter Zijlstra, linux-...@vger.kernel.org
perf-event-4.patch

Peter Zijlstra

unread,
Nov 20, 2009, 4:30:19 PM11/20/09
to Paul Mackerras, Ingo Molnar, Peter Zijlstra, linux-...@vger.kernel.org
perf-time-2.patch

Peter Zijlstra

unread,
Nov 20, 2009, 4:30:39 PM11/20/09
to Paul Mackerras, Ingo Molnar, Peter Zijlstra, linux-...@vger.kernel.org
perf-overflow.patch

Peter Zijlstra

unread,
Nov 20, 2009, 4:31:08 PM11/20/09
to Paul Mackerras, Ingo Molnar, Peter Zijlstra, linux-...@vger.kernel.org, Stephane Eranian
stephane_perf_events-fix_default_watermark_calculation.patch

tip-bot for Peter Zijlstra

unread,
Nov 21, 2009, 8:42:04 AM11/21/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: 453f19eea7dbad837425e9b07d84568d14898794
Gitweb: http://git.kernel.org/tip/453f19eea7dbad837425e9b07d84568d14898794
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Fri, 20 Nov 2009 22:19:43 +0100
Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Sat, 21 Nov 2009 14:11:35 +0100

perf: Allow for custom overflow handlers

in-kernel perf users might wish to have custom actions on the
sample interrupt.

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
LKML-Reference: <200911202125...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---
include/linux/perf_event.h | 6 ++++++
kernel/perf_event.c | 8 +++++++-
2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index b5cdac0..a430ac3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -567,6 +567,8 @@ struct perf_pending_entry {

typedef void (*perf_callback_t)(struct perf_event *, void *);

+struct perf_sample_data;
+
/**
* struct perf_event - performance event kernel representation:
*/
@@ -658,6 +660,10 @@ struct perf_event {
struct pid_namespace *ns;
u64 id;

+ void (*overflow_handler)(struct perf_event *event,
+ int nmi, struct perf_sample_data *data,
+ struct pt_regs *regs);
+
#ifdef CONFIG_EVENT_PROFILE
struct event_filter *filter;
#endif
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 3852e26..1dfb6cc 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -3710,7 +3710,11 @@ static int __perf_event_overflow(struct perf_event *event, int nmi,
perf_event_disable(event);
}

- perf_event_output(event, nmi, data, regs);
+ if (event->overflow_handler)
+ event->overflow_handler(event, nmi, data, regs);
+ else
+ perf_event_output(event, nmi, data, regs);
+
return ret;
}

@@ -4836,6 +4840,8 @@ inherit_event(struct perf_event *parent_event,
if (parent_event->attr.freq)
child_event->hw.sample_period = parent_event->hw.sample_period;

+ child_event->overflow_handler = parent_event->overflow_handler;
+
/*
* Link it up in the child's context:
*/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

tip-bot for Peter Zijlstra

unread,
Nov 21, 2009, 8:42:44 AM11/21/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: f6595f3a9680c86b6332f881a7ae2cbbcfdc8619
Gitweb: http://git.kernel.org/tip/f6595f3a9680c86b6332f881a7ae2cbbcfdc8619
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Fri, 20 Nov 2009 22:19:47 +0100
Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Sat, 21 Nov 2009 14:11:36 +0100

perf: Optimize perf_event_comm_ctx()

Remove a rcu_read_{,un}lock() pair and a few conditionals.

We can remove the rcu_read_lock() by increasing the scope of one
in the calling function.

We can do away with the system_state check if the machine still
boots after this patch (seems to be the case).

We can do away with the list_empty() check because the bare
list_for_each_entry_rcu() reduces to that now that we've removed
everything else.

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
LKML-Reference: <200911202125...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---

kernel/perf_event.c | 7 +------
1 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 2afb305..4deefaa 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -3374,15 +3374,10 @@ static void perf_event_comm_ctx(struct perf_event_context *ctx,
{
struct perf_event *event;

- if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
- return;
-
- rcu_read_lock();
list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
if (perf_event_comm_match(event))
perf_event_comm_output(event, comm_event);
}
- rcu_read_unlock();
}

static void perf_event_comm_event(struct perf_comm_event *comm_event)
@@ -3401,11 +3396,11 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)

comm_event->event_id.header.size = sizeof(comm_event->event_id) + size;

+ rcu_read_lock();
cpuctx = &get_cpu_var(perf_cpu_context);
perf_event_comm_ctx(&cpuctx->ctx, comm_event);
put_cpu_var(perf_cpu_context);

- rcu_read_lock();
/*
* doesn't really matter which of the child contexts the
* events ends up in.

tip-bot for Peter Zijlstra

unread,
Nov 21, 2009, 8:43:52 AM11/21/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: f6f83785222b0ee037f7be90731f62a649292b5e
Gitweb: http://git.kernel.org/tip/f6f83785222b0ee037f7be90731f62a649292b5e
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Fri, 20 Nov 2009 22:19:51 +0100
Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Sat, 21 Nov 2009 14:11:38 +0100

perf: Optimize __perf_event_read()

Both callers actually have IRQs disabled, no need doing so
again.

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
LKML-Reference: <200911202125...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---

kernel/perf_event.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 65f4dab..e66f6c4 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1517,7 +1517,6 @@ static void __perf_event_read(void *info)
struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
struct perf_event *event = info;
struct perf_event_context *ctx = event->ctx;
- unsigned long flags;

/*
* If this is a task context, we need to check whether it is
@@ -1529,12 +1528,10 @@ static void __perf_event_read(void *info)
if (ctx->task && cpuctx->task_ctx != ctx)
return;

- local_irq_save(flags);
if (ctx->is_active)
update_context_time(ctx);
event->pmu->read(event);
update_event_times(event);
- local_irq_restore(flags);
}

static u64 perf_event_read(struct perf_event *event)

tip-bot for Peter Zijlstra

unread,
Nov 21, 2009, 8:44:05 AM11/21/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: 58e5ad1de3d6ad931c84f0cc8ef0655c922f30ad
Gitweb: http://git.kernel.org/tip/58e5ad1de3d6ad931c84f0cc8ef0655c922f30ad
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Fri, 20 Nov 2009 22:19:53 +0100
Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Sat, 21 Nov 2009 14:11:39 +0100

perf: Simplify __perf_event_read

cpuctx is always active, task context is always active for
current

the previous condition verifies that if its a task context its
for current, hence we can assume ctx->is_active.

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
LKML-Reference: <200911202125...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---

kernel/perf_event.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index af150bb..028619d 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1526,10 +1526,9 @@ static void __perf_event_read(void *info)


if (ctx->task && cpuctx->task_ctx != ctx)
return;

- if (ctx->is_active)
- update_context_time(ctx);
- event->pmu->read(event);
+ update_context_time(ctx);
update_event_times(event);
+ event->pmu->read(event);

tip-bot for Peter Zijlstra

unread,
Nov 21, 2009, 8:44:15 AM11/21/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: 3dbebf15c5d3e265f751eec72c1538a00da4be27
Gitweb: http://git.kernel.org/tip/3dbebf15c5d3e265f751eec72c1538a00da4be27
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Fri, 20 Nov 2009 22:19:52 +0100

Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Sat, 21 Nov 2009 14:11:39 +0100

perf: Simplify __perf_event_sync_stat

Removes constraints from __perf_event_read() by leaving it with
a single callsite; this callsite had ctx->lock held, the other
one does not.

Removes some superfluous code from __perf_event_sync_stat().

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
LKML-Reference: <200911202125...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---

kernel/perf_event.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index e66f6c4..af150bb 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1061,8 +1061,6 @@ static int context_equiv(struct perf_event_context *ctx1,
&& !ctx1->pin_count && !ctx2->pin_count;
}

-static void __perf_event_read(void *event);
-
static void __perf_event_sync_stat(struct perf_event *event,
struct perf_event *next_event)
{
@@ -1080,8 +1078,8 @@ static void __perf_event_sync_stat(struct perf_event *event,
*/
switch (event->state) {
case PERF_EVENT_STATE_ACTIVE:
- __perf_event_read(event);
- break;
+ event->pmu->read(event);
+ /* fall-through */

case PERF_EVENT_STATE_INACTIVE:
update_event_times(event);

tip-bot for Peter Zijlstra

unread,
Nov 21, 2009, 8:44:37 AM11/21/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: 2b8988c9f7defe319cffe0cd362a7cd356c86f62
Gitweb: http://git.kernel.org/tip/2b8988c9f7defe319cffe0cd362a7cd356c86f62
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Fri, 20 Nov 2009 22:19:54 +0100

Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Sat, 21 Nov 2009 14:11:39 +0100

perf: Fix time locking

Most sites updating ctx->time and event times do so under
ctx->lock, make sure they all do.

This was made possible by removing the __perf_event_read() call
from __perf_event_sync_stat(), which already had this lock
taken.

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
LKML-Reference: <200911202125...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---

kernel/perf_event.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 028619d..fdfae88 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1526,8 +1526,11 @@ static void __perf_event_read(void *info)


if (ctx->task && cpuctx->task_ctx != ctx)
return;

+ spin_lock(&ctx->lock);
update_context_time(ctx);
update_event_times(event);
+ spin_unlock(&ctx->lock);
+
event->pmu->read(event);
}

@@ -1541,7 +1544,13 @@ static u64 perf_event_read(struct perf_event *event)
smp_call_function_single(event->oncpu,
__perf_event_read, event, 1);
} else if (event->state == PERF_EVENT_STATE_INACTIVE) {
+ struct perf_event_context *ctx = event->ctx;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->lock, flags);
+ update_context_time(ctx);
update_event_times(event);
+ spin_unlock_irqrestore(&ctx->lock, flags);
}

return atomic64_read(&event->count);

0 new messages