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 <o...@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org> --- 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);