[RFC][PATCH 4/7] perf: Fix scaling vs enable_on_exec

From: Peter Zijlstra
Date: Fri Feb 19 2016 - 09:52:22 EST


Oleg reported that enable_on_exec results in weird scale factors.

The recent commit 3e349507d12d ("perf: Fix perf_enable_on_exec() event
scheduling") caused this by moving task_ctx_sched_out() from before
__perf_event_mask_enable() to after it.

The overlooked concequence of that change is that task_ctx_sched_out()
would update the ctx time fields, and now __perf_event_mask_enable()
uses stale time.

Fix this by adding an explicit time update.

While looking at this, I also found that we need an ctx->is_active
check in perf_install_in_context().

XXX: does this actually fix the reported issue? I'm not sure what the
reproduction case is. Also an earlier version made Jiri's machine
explode -- something I've not managed to reproduce either.

Fixes: 3e349507d12d ("perf: Fix perf_enable_on_exec() event scheduling")
Reported-by: Oleg Nesterov <oleg@xxxxxxxxxx>
Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
---
kernel/events/core.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)

--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -2170,12 +2170,12 @@ perf_install_in_context(struct perf_even
raw_spin_unlock_irq(&ctx->lock);
return;
}
- update_context_time(ctx);
- /*
- * Update cgrp time only if current cgrp matches event->cgrp.
- * Must be done before calling add_event_to_ctx().
- */
- update_cgrp_time_from_event(event);
+
+ if (ctx->is_active) {
+ update_context_time(ctx);
+ update_cgrp_time_from_event(event);
+ }
+
add_event_to_ctx(event, ctx);
raw_spin_unlock_irq(&ctx->lock);

@@ -3122,6 +3122,12 @@ static void perf_event_enable_on_exec(in

cpuctx = __get_cpu_context(ctx);
perf_ctx_lock(cpuctx, ctx);
+
+ if (ctx->is_active) {
+ update_context_time(ctx);
+ update_cgrp_time_from_cpuctx(cpuctx);
+ }
+
list_for_each_entry(event, &ctx->event_list, event_entry)
enabled |= event_enable_on_exec(event, ctx);