Re: [RFC v2] perf: Rewrite core context handling

Ravi Bangoria
2022-08-22T14:38:51Z

[...]

> You mentioned trouble with cpc->task_epc, there's one rebase mistake
> from you and an original bug from me.
>
> You lost the last hunk, I forgot to clear cpc on
> perf_remove_from_context().
>
> With these fixes I can run: 'perf test' without things going
> insta-splat.
>
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -2311,6 +2311,7 @@ __perf_remove_from_context(struct perf_e
> struct perf_event_context *ctx,
> void *info)
> {
> + struct perf_event_pmu_context *pmu_ctx = event->pmu_ctx;
> unsigned long flags = (unsigned long)info;
>
> if (ctx->is_active & EVENT_TIME) {
> @@ -2325,8 +2326,17 @@ __perf_remove_from_context(struct perf_e
> perf_child_detach(event);
> list_del_event(event, ctx);
>
> - if (!event->pmu_ctx->nr_events)
> - event->pmu_ctx->rotate_necessary = 0;
> + if (!pmu_ctx->nr_events) {
> + pmu_ctx->rotate_necessary = 0;
> +
> + if (ctx->task) {

IIUC, this should also check for ctx->is_active? i.e.

if (ctx->task && ctx->is_active) {
...

> + struct perf_cpu_pmu_context *cpc;
> +
> + cpc = this_cpu_ptr(pmu_ctx->pmu->cpu_pmu_context);
> + WARN_ON_ONCE(cpc->task_epc && cpc->task_epc != pmu_ctx);
> + cpc->task_epc = NULL;
> + }
> + }

Thanks,
Ravi