From: Song Liu Date: Tue, 6 Mar 2018 05:55:04 +0000 (-0800) Subject: perf/core: Fix ctx_event_type in ctx_resched() X-Git-Tag: v4.14.31~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=227e2f91f0c93e867086f3dfeaafd0d7a44554d1;p=platform%2Fkernel%2Flinux-rpi.git perf/core: Fix ctx_event_type in ctx_resched() commit bd903afeb504db5655a45bb4cf86f38be5b1bf62 upstream. In ctx_resched(), EVENT_FLEXIBLE should be sched_out when EVENT_PINNED is added. However, ctx_resched() calculates ctx_event_type before checking this condition. As a result, pinned events will NOT get higher priority than flexible events. The following shows this issue on an Intel CPU (where ref-cycles can only use one hardware counter). 1. First start: perf stat -C 0 -e ref-cycles -I 1000 2. Then, in the second console, run: perf stat -C 0 -e ref-cycles:D -I 1000 The second perf uses pinned events, which is expected to have higher priority. However, because it failed in ctx_resched(). It is never run. This patch fixes this by calculating ctx_event_type after re-evaluating event_type. Reported-by: Ephraim Park Signed-off-by: Song Liu Signed-off-by: Peter Zijlstra (Intel) Cc: Cc: Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Fixes: 487f05e18aa4 ("perf/core: Optimize event rescheduling on active contexts") Link: http://lkml.kernel.org/r/20180306055504.3283731-1-songliubraving@fb.com Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- diff --git a/kernel/events/core.c b/kernel/events/core.c index f42f7c7..cecd72e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -2322,7 +2322,7 @@ static void ctx_resched(struct perf_cpu_context *cpuctx, struct perf_event_context *task_ctx, enum event_type_t event_type) { - enum event_type_t ctx_event_type = event_type & EVENT_ALL; + enum event_type_t ctx_event_type; bool cpu_event = !!(event_type & EVENT_CPU); /* @@ -2332,6 +2332,8 @@ static void ctx_resched(struct perf_cpu_context *cpuctx, if (event_type & EVENT_PINNED) event_type |= EVENT_FLEXIBLE; + ctx_event_type = event_type & EVENT_ALL; + perf_pmu_disable(cpuctx->ctx.pmu); if (task_ctx) task_ctx_sched_out(cpuctx, task_ctx, event_type);