[PATCH 05/12] perf: move perf_event_task_sched_in() next to fire_sched_notifiers_in()

Tejun Heo
2010-05-04T12:41:22Z

Move perf_event_task_sched_in() after finish_lock_switch() right
before fire_sched_notifiers_in(). This costs an extra pair of irq
enable/disable when switching in a perf task context but allows
unifying event functions in a more flexible position (irq enabled, rq
lock released).

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
---
kernel/perf_event.c | 9 +++++++--
kernel/sched.c | 8 +-------
2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 73e2c1c..295699f 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1369,14 +1369,17 @@ static void task_ctx_sched_in(struct task_struct *task,
*/
void perf_event_task_sched_in(struct task_struct *task)
{
- struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
struct perf_event_context *ctx = task->perf_event_ctxp;
+ struct perf_cpu_context *cpuctx;

if (likely(!ctx))
return;

+ local_irq_disable();
+
+ cpuctx = &__get_cpu_var(perf_cpu_context);
if (cpuctx->task_ctx == ctx)
- return;
+ goto out_enable;

/*
* We want to keep the following priority order:
@@ -1390,6 +1393,8 @@ void perf_event_task_sched_in(struct task_struct *task)
ctx_sched_in(ctx, cpuctx, EVENT_FLEXIBLE);

cpuctx->task_ctx = ctx;
+out_enable:
+ local_irq_enable();
}

#define MAX_INTERRUPTS (~0ULL)
diff --git a/kernel/sched.c b/kernel/sched.c
index 4c5e4c9..df6e0af 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2794,15 +2794,9 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
*/
prev_state = prev->state;
finish_arch_switch(prev);
-#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
- local_irq_disable();
-#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
- perf_event_task_sched_in(current);
-#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
- local_irq_enable();
-#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
finish_lock_switch(rq, prev);

+ perf_event_task_sched_in(current);
fire_sched_notifiers_in(current);
if (mm)
mmdrop(mm);
--
1.6.4.2