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

[PATCH 7/8] perf: undo some recursion damage

0 views
Skip to first unread message

Peter Zijlstra

unread,
Nov 23, 2009, 5:41:13 AM11/23/09
to Ingo Molnar, Paul Mackerras, linux-...@vger.kernel.org, Peter Zijlstra, Frederic Weisbecker
perf-foo-7.patch

Peter Zijlstra

unread,
Nov 23, 2009, 5:41:17 AM11/23/09
to Ingo Molnar, Paul Mackerras, linux-...@vger.kernel.org, Peter Zijlstra
perf-foo-2.patch

Peter Zijlstra

unread,
Nov 23, 2009, 5:41:20 AM11/23/09
to Ingo Molnar, Paul Mackerras, linux-...@vger.kernel.org, Peter Zijlstra
perf-foo-8.patch

Peter Zijlstra

unread,
Nov 23, 2009, 5:41:24 AM11/23/09
to Ingo Molnar, Paul Mackerras, linux-...@vger.kernel.org, Peter Zijlstra
perf-foo-1.patch

Peter Zijlstra

unread,
Nov 23, 2009, 5:41:45 AM11/23/09
to Ingo Molnar, Paul Mackerras, linux-...@vger.kernel.org, Peter Zijlstra
perf-foo-6.patch

Peter Zijlstra

unread,
Nov 23, 2009, 5:41:57 AM11/23/09
to Ingo Molnar, Paul Mackerras, linux-...@vger.kernel.org, Peter Zijlstra
perf-foo-3.patch

tip-bot for Peter Zijlstra

unread,
Nov 23, 2009, 6:54:49 AM11/23/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, ac...@redhat.com, pau...@samba.org, h...@zytor.com, mi...@redhat.com, a.p.zi...@chello.nl, efa...@gmx.de, fwei...@gmail.com, tg...@linutronix.de, mi...@elte.hu
Commit-ID: a66a3052e2d4c5815d7ad26887b1d4193206e691
Gitweb: http://git.kernel.org/tip/a66a3052e2d4c5815d7ad26887b1d4193206e691
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Mon, 23 Nov 2009 11:37:23 +0100
Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Mon, 23 Nov 2009 11:49:55 +0100

perf_events: Undo copy/paste damage

We had two almost identical functions, avoid the duplication.

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
LKML-Reference: <200911231038...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---
kernel/perf_event.c | 31 +++++++++----------------------
1 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 20df8ab..e2daa10 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1704,16 +1704,10 @@ static void free_event(struct perf_event *event)
call_rcu(&event->rcu_head, free_event_rcu);
}

-/*
- * Called when the last reference to the file is gone.
- */
-static int perf_release(struct inode *inode, struct file *file)
+int perf_event_release_kernel(struct perf_event *event)
{
- struct perf_event *event = file->private_data;
struct perf_event_context *ctx = event->ctx;

- file->private_data = NULL;
-
WARN_ON_ONCE(ctx->parent_ctx);
mutex_lock(&ctx->mutex);
perf_event_remove_from_context(event);
@@ -1728,26 +1722,19 @@ static int perf_release(struct inode *inode, struct file *file)

return 0;
}
+EXPORT_SYMBOL_GPL(perf_event_release_kernel);

-int perf_event_release_kernel(struct perf_event *event)
+/*
+ * Called when the last reference to the file is gone.
+ */
+static int perf_release(struct inode *inode, struct file *file)
{
- struct perf_event_context *ctx = event->ctx;
-
- WARN_ON_ONCE(ctx->parent_ctx);
- mutex_lock(&ctx->mutex);
- perf_event_remove_from_context(event);
- mutex_unlock(&ctx->mutex);
-
- mutex_lock(&event->owner->perf_event_mutex);
- list_del_init(&event->owner_entry);
- mutex_unlock(&event->owner->perf_event_mutex);
- put_task_struct(event->owner);
+ struct perf_event *event = file->private_data;

- free_event(event);
+ file->private_data = NULL;

- return 0;
+ return perf_event_release_kernel(event);
}
-EXPORT_SYMBOL_GPL(perf_event_release_kernel);

static int perf_event_read_size(struct perf_event *event)
{
--
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 23, 2009, 6:54:59 AM11/23/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, fwei...@gmail.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: 6c2bfcbe58e0dd39554be88940149f5aa11e17d1
Gitweb: http://git.kernel.org/tip/6c2bfcbe58e0dd39554be88940149f5aa11e17d1
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Mon, 23 Nov 2009 11:37:24 +0100

Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Mon, 23 Nov 2009 11:49:55 +0100

perf_events: Fix style nits

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>

LKML-Reference: <200911231038...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---

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

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index e2daa10..1f14481 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -447,9 +447,8 @@ retry:
* can remove the event safely, if the call above did not
* succeed.
*/
- if (!list_empty(&event->group_entry)) {
+ if (!list_empty(&event->group_entry))
list_del_event(event, ctx);
- }
spin_unlock_irq(&ctx->lock);
}

@@ -1033,10 +1032,10 @@ void __perf_event_sched_out(struct perf_event_context *ctx,
update_context_time(ctx);

perf_disable();
- if (ctx->nr_active)
+ if (ctx->nr_active) {
list_for_each_entry(event, &ctx->group_list, group_entry)
group_sched_out(event, cpuctx, ctx);
-
+ }
perf_enable();
out:
spin_unlock(&ctx->lock);

tip-bot for Peter Zijlstra

unread,
Nov 23, 2009, 6:55:32 AM11/23/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, fwei...@gmail.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: 5e942bb33371254a474653123cd9e13a4c89ee44
Gitweb: http://git.kernel.org/tip/5e942bb33371254a474653123cd9e13a4c89ee44
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Mon, 23 Nov 2009 11:37:26 +0100
Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Mon, 23 Nov 2009 11:49:56 +0100

perf_events: Update the context time on exit

It appeared we did call update_event_times() on exit, but we
failed to update the context time, which renders the former
moot.

Locking is a bit iffy, we call update_event_times under
ctx->mutex instead of ctx->lock - the next patch fixes this.

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

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

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index fb851ec..8be2574 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -4983,6 +4983,7 @@ void perf_event_exit_task(struct task_struct *child)
* the events from it.
*/
unclone_ctx(child_ctx);
+ update_context_time(child_ctx);
spin_unlock_irqrestore(&child_ctx->lock, flags);

/*

tip-bot for Peter Zijlstra

unread,
Nov 23, 2009, 6:55:53 AM11/23/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, fwei...@gmail.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: 4ed7c92d68a5387ba5f7030dc76eab03558e27f5
Gitweb: http://git.kernel.org/tip/4ed7c92d68a5387ba5f7030dc76eab03558e27f5
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Mon, 23 Nov 2009 11:37:29 +0100
Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Mon, 23 Nov 2009 11:49:57 +0100

perf_events: Undo some recursion damage

Make perf_swevent_get_recursion_context return a context number
and disable preemption.

This could be used to remove the IRQ disable from the trace bit
and index the per-cpu buffer with.

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Frederic Weisbecker <fwei...@gmail.com>
Cc: Paul Mackerras <pau...@samba.org>


LKML-Reference: <200911231038...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---

include/linux/perf_event.h | 8 ++--
include/trace/ftrace.h | 17 +++++-----
kernel/perf_event.c | 71 ++++++++++++++++++----------------------
kernel/trace/trace_kprobe.c | 14 +++++---
kernel/trace/trace_syscalls.c | 14 +++++---
5 files changed, 61 insertions(+), 63 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 74e98b1..43adbd7 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -874,8 +874,8 @@ extern int perf_output_begin(struct perf_output_handle *handle,
extern void perf_output_end(struct perf_output_handle *handle);
extern void perf_output_copy(struct perf_output_handle *handle,
const void *buf, unsigned int len);
-extern int perf_swevent_get_recursion_context(int **recursion);
-extern void perf_swevent_put_recursion_context(int *recursion);
+extern int perf_swevent_get_recursion_context(void);
+extern void perf_swevent_put_recursion_context(int rctx);
#else
static inline void
perf_event_task_sched_in(struct task_struct *task, int cpu) { }
@@ -904,8 +904,8 @@ static inline void perf_event_mmap(struct vm_area_struct *vma) { }
static inline void perf_event_comm(struct task_struct *tsk) { }
static inline void perf_event_fork(struct task_struct *tsk) { }
static inline void perf_event_init(void) { }
-static int perf_swevent_get_recursion_context(int **recursion) { return -1; }
-static void perf_swevent_put_recursion_context(int *recursion) { }
+static inline int perf_swevent_get_recursion_context(void) { return -1; }
+static inline void perf_swevent_put_recursion_context(int rctx) { }

#endif

diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index c222ef5..c3417c1 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -724,8 +724,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
static void ftrace_profile_##call(proto) \
{ \
struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
- extern int perf_swevent_get_recursion_context(int **recursion); \
- extern void perf_swevent_put_recursion_context(int *recursion); \
+ extern int perf_swevent_get_recursion_context(void); \
+ extern void perf_swevent_put_recursion_context(int rctx); \
struct ftrace_event_call *event_call = &event_##call; \
extern void perf_tp_event(int, u64, u64, void *, int); \
struct ftrace_raw_##call *entry; \
@@ -736,8 +736,8 @@ static void ftrace_profile_##call(proto) \
int __data_size; \
char *trace_buf; \
char *raw_data; \
- int *recursion; \
int __cpu; \
+ int rctx; \
int pc; \
\
pc = preempt_count(); \
@@ -753,8 +753,9 @@ static void ftrace_profile_##call(proto) \
\
local_irq_save(irq_flags); \
\
- if (perf_swevent_get_recursion_context(&recursion)) \
- goto end_recursion; \
+ rctx = perf_swevent_get_recursion_context(); \
+ if (rctx < 0) \
+ goto end_recursion; \
\
__cpu = smp_processor_id(); \
\
@@ -781,9 +782,9 @@ static void ftrace_profile_##call(proto) \
perf_tp_event(event_call->id, __addr, __count, entry, \
__entry_size); \
\
-end: \
- perf_swevent_put_recursion_context(recursion); \
-end_recursion: \
+end: \
+ perf_swevent_put_recursion_context(rctx); \
+end_recursion: \
local_irq_restore(irq_flags); \
\
}
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 50f11b5..0b0d5f7 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -3869,45 +3869,50 @@ static void perf_swevent_ctx_event(struct perf_event_context *ctx,
}
}

-/*
- * Must be called with preemption disabled
- */
-int perf_swevent_get_recursion_context(int **recursion)
+int perf_swevent_get_recursion_context(void)
{
- struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+ struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context);
+ int rctx;

if (in_nmi())
- *recursion = &cpuctx->recursion[3];
+ rctx = 3;
else if (in_irq())
- *recursion = &cpuctx->recursion[2];
+ rctx = 2;
else if (in_softirq())
- *recursion = &cpuctx->recursion[1];
+ rctx = 1;
else
- *recursion = &cpuctx->recursion[0];
+ rctx = 0;

- if (**recursion)
+ if (cpuctx->recursion[rctx]) {
+ put_cpu_var(perf_cpu_context);
return -1;
+ }

- (**recursion)++;
+ cpuctx->recursion[rctx]++;
+ barrier();

- return 0;
+ return rctx;
}
EXPORT_SYMBOL_GPL(perf_swevent_get_recursion_context);

-void perf_swevent_put_recursion_context(int *recursion)
+void perf_swevent_put_recursion_context(int rctx)
{
- (*recursion)--;
+ struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+ barrier();
+ cpuctx->recursion[rctx]++;
+ put_cpu_var(perf_cpu_context);
}
EXPORT_SYMBOL_GPL(perf_swevent_put_recursion_context);

-static void __do_perf_sw_event(enum perf_type_id type, u32 event_id,
- u64 nr, int nmi,
- struct perf_sample_data *data,
- struct pt_regs *regs)
+static void do_perf_sw_event(enum perf_type_id type, u32 event_id,
+ u64 nr, int nmi,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
{
+ struct perf_cpu_context *cpuctx;
struct perf_event_context *ctx;
- struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);

+ cpuctx = &__get_cpu_var(perf_cpu_context);
rcu_read_lock();
perf_swevent_ctx_event(&cpuctx->ctx, type, event_id,
nr, nmi, data, regs);
@@ -3921,34 +3926,22 @@ static void __do_perf_sw_event(enum perf_type_id type, u32 event_id,
rcu_read_unlock();
}

-static void do_perf_sw_event(enum perf_type_id type, u32 event_id,
- u64 nr, int nmi,
- struct perf_sample_data *data,
- struct pt_regs *regs)
-{
- int *recursion;
-
- preempt_disable();
-
- if (perf_swevent_get_recursion_context(&recursion))
- goto out;
-
- __do_perf_sw_event(type, event_id, nr, nmi, data, regs);
-
- perf_swevent_put_recursion_context(recursion);
-out:
- preempt_enable();
-}
-
void __perf_sw_event(u32 event_id, u64 nr, int nmi,
struct pt_regs *regs, u64 addr)
{
struct perf_sample_data data;
+ int rctx;
+
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
+ return;

data.addr = addr;
data.raw = NULL;

do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi, &data, regs);
+
+ perf_swevent_put_recursion_context(rctx);
}

static void perf_swevent_read(struct perf_event *event)
@@ -4172,7 +4165,7 @@ void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
regs = task_pt_regs(current);

/* Trace events already protected against recursion */
- __do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1,
+ do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1,
&data, regs);
}
EXPORT_SYMBOL_GPL(perf_tp_event);
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 22e6f68..79ce6a2 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1213,7 +1213,7 @@ static __kprobes int kprobe_profile_func(struct kprobe *kp,
unsigned long irq_flags;
char *trace_buf;
char *raw_data;
- int *recursion;
+ int rctx;

pc = preempt_count();
__size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args);
@@ -1229,7 +1229,8 @@ static __kprobes int kprobe_profile_func(struct kprobe *kp,
*/
local_irq_save(irq_flags);

- if (perf_swevent_get_recursion_context(&recursion))
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
goto end_recursion;

__cpu = smp_processor_id();
@@ -1258,7 +1259,7 @@ static __kprobes int kprobe_profile_func(struct kprobe *kp,
perf_tp_event(call->id, entry->ip, 1, entry, size);

end:
- perf_swevent_put_recursion_context(recursion);
+ perf_swevent_put_recursion_context(rctx);
end_recursion:
local_irq_restore(irq_flags);

@@ -1276,8 +1277,8 @@ static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri,
int size, __size, i, pc, __cpu;
unsigned long irq_flags;
char *trace_buf;
- int *recursion;
char *raw_data;
+ int rctx;

pc = preempt_count();
__size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args);
@@ -1293,7 +1294,8 @@ static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri,
*/
local_irq_save(irq_flags);

- if (perf_swevent_get_recursion_context(&recursion))
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
goto end_recursion;

__cpu = smp_processor_id();
@@ -1323,7 +1325,7 @@ static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri,
perf_tp_event(call->id, entry->ret_ip, 1, entry, size);

end:
- perf_swevent_put_recursion_context(recursion);
+ perf_swevent_put_recursion_context(rctx);
end_recursion:
local_irq_restore(irq_flags);

diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 41b6dd9..9189cbe 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -481,8 +481,8 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
unsigned long flags;
char *trace_buf;
char *raw_data;
- int *recursion;
int syscall_nr;
+ int rctx;
int size;
int cpu;

@@ -506,7 +506,8 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
/* Protect the per cpu buffer, begin the rcu read side */
local_irq_save(flags);

- if (perf_swevent_get_recursion_context(&recursion))
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
goto end_recursion;

cpu = smp_processor_id();
@@ -530,7 +531,7 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
perf_tp_event(sys_data->enter_id, 0, 1, rec, size);

end:
- perf_swevent_put_recursion_context(recursion);
+ perf_swevent_put_recursion_context(rctx);
end_recursion:
local_irq_restore(flags);
}
@@ -582,7 +583,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
int syscall_nr;
char *trace_buf;
char *raw_data;
- int *recursion;
+ int rctx;
int size;
int cpu;

@@ -609,7 +610,8 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
/* Protect the per cpu buffer, begin the rcu read side */
local_irq_save(flags);

- if (perf_swevent_get_recursion_context(&recursion))
+ rctx = perf_swevent_get_recursion_context();
+ if (rctx < 0)
goto end_recursion;

cpu = smp_processor_id();
@@ -634,7 +636,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
perf_tp_event(sys_data->exit_id, 0, 1, rec, size);

end:
- perf_swevent_put_recursion_context(recursion);
+ perf_swevent_put_recursion_context(rctx);
end_recursion:
local_irq_restore(flags);

tip-bot for Peter Zijlstra

unread,
Nov 23, 2009, 6:57:38 AM11/23/09
to linux-ti...@vger.kernel.org, linux-...@vger.kernel.org, pau...@samba.org, h...@zytor.com, mi...@redhat.com, fwei...@gmail.com, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu
Commit-ID: f67218c3e93abaf0f480bb94b53d234853ffe4de
Gitweb: http://git.kernel.org/tip/f67218c3e93abaf0f480bb94b53d234853ffe4de
Author: Peter Zijlstra <a.p.zi...@chello.nl>
AuthorDate: Mon, 23 Nov 2009 11:37:27 +0100

Committer: Ingo Molnar <mi...@elte.hu>
CommitDate: Mon, 23 Nov 2009 11:49:57 +0100

perf_events: Fix __perf_event_exit_task() vs. update_event_times() locking

Move the update_event_times() call in __perf_event_exit_task()
into list_del_event() because that holds the proper lock
(ctx->lock) and seems a more natural place to do the last time
update.

Signed-off-by: Peter Zijlstra <a.p.zi...@chello.nl>


Cc: Paul Mackerras <pau...@samba.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>

LKML-Reference: <200911231038...@chello.nl>
Signed-off-by: Ingo Molnar <mi...@elte.hu>
---

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

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 8be2574..50f11b5 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -246,6 +246,44 @@ static void perf_unpin_context(struct perf_event_context *ctx)
put_ctx(ctx);
}

+static inline u64 perf_clock(void)
+{
+ return cpu_clock(smp_processor_id());
+}
+
+/*
+ * Update the record of the current time in a context.
+ */
+static void update_context_time(struct perf_event_context *ctx)
+{
+ u64 now = perf_clock();
+
+ ctx->time += now - ctx->timestamp;
+ ctx->timestamp = now;
+}
+
+/*
+ * Update the total_time_enabled and total_time_running fields for a event.
+ */
+static void update_event_times(struct perf_event *event)
+{
+ struct perf_event_context *ctx = event->ctx;
+ u64 run_end;
+
+ if (event->state < PERF_EVENT_STATE_INACTIVE ||
+ event->group_leader->state < PERF_EVENT_STATE_INACTIVE)
+ return;
+
+ event->total_time_enabled = ctx->time - event->tstamp_enabled;
+
+ if (event->state == PERF_EVENT_STATE_INACTIVE)
+ run_end = event->tstamp_stopped;
+ else
+ run_end = ctx->time;
+
+ event->total_time_running = run_end - event->tstamp_running;
+}
+
/*
* Add a event from the lists for its context.
* Must be called with ctx->mutex and ctx->lock held.
@@ -294,6 +332,7 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
if (event->group_leader != event)
event->group_leader->nr_siblings--;

+ update_event_times(event);
event->state = PERF_EVENT_STATE_OFF;

/*
@@ -454,44 +493,6 @@ retry:
spin_unlock_irq(&ctx->lock);
}

-static inline u64 perf_clock(void)
-{
- return cpu_clock(smp_processor_id());
-}
-
-/*
- * Update the record of the current time in a context.
- */
-static void update_context_time(struct perf_event_context *ctx)
-{
- u64 now = perf_clock();
-
- ctx->time += now - ctx->timestamp;
- ctx->timestamp = now;
-}
-
-/*
- * Update the total_time_enabled and total_time_running fields for a event.
- */
-static void update_event_times(struct perf_event *event)
-{


- struct perf_event_context *ctx = event->ctx;

- u64 run_end;
-
- if (event->state < PERF_EVENT_STATE_INACTIVE ||
- event->group_leader->state < PERF_EVENT_STATE_INACTIVE)
- return;
-
- event->total_time_enabled = ctx->time - event->tstamp_enabled;
-
- if (event->state == PERF_EVENT_STATE_INACTIVE)
- run_end = event->tstamp_stopped;
- else
- run_end = ctx->time;
-
- event->total_time_running = run_end - event->tstamp_running;
-}
-
/*
* Update total_time_enabled and total_time_running for all events in a group.
*/
@@ -4931,7 +4932,6 @@ __perf_event_exit_task(struct perf_event *child_event,
{
struct perf_event *parent_event;

- update_event_times(child_event);
perf_event_remove_from_context(child_event);

parent_event = child_event->parent;

Frederic Weisbecker

unread,
Nov 23, 2009, 7:39:49 AM11/23/09
to mi...@redhat.com, h...@zytor.com, pau...@samba.org, linux-...@vger.kernel.org, a.p.zi...@chello.nl, tg...@linutronix.de, mi...@elte.hu, linux-ti...@vger.kernel.org
On Mon, Nov 23, 2009 at 11:55:08AM +0000, tip-bot for Peter Zijlstra wrote:
> Commit-ID: 4ed7c92d68a5387ba5f7030dc76eab03558e27f5
> Gitweb: http://git.kernel.org/tip/4ed7c92d68a5387ba5f7030dc76eab03558e27f5
> Author: Peter Zijlstra <a.p.zi...@chello.nl>
> AuthorDate: Mon, 23 Nov 2009 11:37:29 +0100
> Committer: Ingo Molnar <mi...@elte.hu>
> CommitDate: Mon, 23 Nov 2009 11:49:57 +0100
>
> perf_events: Undo some recursion damage
>
> Make perf_swevent_get_recursion_context return a context number
> and disable preemption.
>
> This could be used to remove the IRQ disable from the trace bit
> and index the per-cpu buffer with.


But if I do that, it means I will lose traces once irq nest.

Peter Zijlstra

unread,
Nov 23, 2009, 7:51:10 AM11/23/09
to Frederic Weisbecker, mi...@redhat.com, h...@zytor.com, pau...@samba.org, linux-...@vger.kernel.org, tg...@linutronix.de, mi...@elte.hu, linux-ti...@vger.kernel.org
On Mon, 2009-11-23 at 13:39 +0100, Frederic Weisbecker wrote:
> On Mon, Nov 23, 2009 at 11:55:08AM +0000, tip-bot for Peter Zijlstra wrote:
> > Commit-ID: 4ed7c92d68a5387ba5f7030dc76eab03558e27f5
> > Gitweb: http://git.kernel.org/tip/4ed7c92d68a5387ba5f7030dc76eab03558e27f5
> > Author: Peter Zijlstra <a.p.zi...@chello.nl>
> > AuthorDate: Mon, 23 Nov 2009 11:37:29 +0100
> > Committer: Ingo Molnar <mi...@elte.hu>
> > CommitDate: Mon, 23 Nov 2009 11:49:57 +0100
> >
> > perf_events: Undo some recursion damage
> >
> > Make perf_swevent_get_recursion_context return a context number
> > and disable preemption.
> >
> > This could be used to remove the IRQ disable from the trace bit
> > and index the per-cpu buffer with.
>
>
> But if I do that, it means I will lose traces once irq nest.

Ah yes, that crap :-(

Maybe its about time we extend the generic irq bits to know about nested
irqs, or firmly kill the whole notion.

0 new messages