On Fri, Feb 19, 2016 at 03:37:47PM +0100, Peter Zijlstra wrote: > 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.
Jiri, can you have a look at this and perhaps share the reproducer? > 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); > > >