Messages in this thread | | | Subject | Re: [RFC][PATCH 5/9] perf: Simplify and fix __perf_install_in_context | From | Lin Ming <> | Date | Mon, 11 Apr 2011 16:12:31 +0800 |
| |
On Sat, 2011-04-09 at 21:17 +0200, Peter Zijlstra wrote: > plain text document attachment (perf_install_in_context.patch) > Currently __perf_install_in_context() will try and schedule in the > event irrespective of our event scheduling rules, that is, we try to > schedule CPU-pinned, TASK-pinned, CPU-flexible, TASK-flexible, but > when creating a new event we simply try and schedule it on top of > whatever is already on the PMU, this can lead to errors for pinned > events. > > Therefore, simplify things and simply schedule everything out, add the > event to the corresponding context and schedule everything back in. > > This also nicely handles the case where with > __ARCH_WANT_INTERRUPTS_ON_CTXSW the IPI can come right in the middle > of schedule, before we managed to call perf_event_task_sched_in(). > > Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> > --- > kernel/perf_event.c | 80 ++++++++++++++++++++++------------------------------ > 1 file changed, 35 insertions(+), 45 deletions(-) > > Index: linux-2.6/kernel/perf_event.c > =================================================================== > --- linux-2.6.orig/kernel/perf_event.c > +++ linux-2.6/kernel/perf_event.c > @@ -1476,8 +1476,12 @@ static void add_event_to_ctx(struct perf > event->tstamp_stopped = tstamp; > } > > -static void perf_event_context_sched_in(struct perf_event_context *ctx, > - struct task_struct *tsk); > +static void task_ctx_sched_out(struct perf_event_context *ctx); > +static void > +ctx_sched_in(struct perf_event_context *ctx, > + struct perf_cpu_context *cpuctx, > + enum event_type_t event_type, > + struct task_struct *task); > > /* > * Cross CPU call to install and enable a performance event > @@ -1488,20 +1492,31 @@ static int __perf_install_in_context(vo > { > struct perf_event *event = info; > struct perf_event_context *ctx = event->ctx; > - struct perf_event *leader = event->group_leader; > struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); > - int err; > + struct perf_event_context *task_ctx = cpuctx->task_ctx; > + struct task_struct *task = current; > + > + perf_ctx_lock(cpuctx, cpuctx->task_ctx);
perf_ctx_lock(cpuctx, task_ctx)
since task_ctx is assigned with cpuctx->task_ctx.
Lin Ming
| |