Patch "perf/core: Fix event_function_local()" has been added to the 4.7-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
perf/core: Fix event_function_local()
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
perf-core-fix-event_function_local.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
cca2094605efe6ccf43ff2876dd5bccc799202d8Mon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Tue, 16 Aug 2016 13:33:26 +0200
Subject: perf/core: Fix event_function_local()
From: Peter Zijlstra <[email protected]>
commit cca2094605efe6ccf43ff2876dd5bccc799202d8 upstream.
Vincent reported triggering the WARN_ON_ONCE() in event_function_local().
While thinking through cases I noticed that by using event_function() directly, we miss the inactive case usually handled by event_function_call().
Therefore construct a blend of event_function_call() and event_function() that handles the cases relevant to event_function_local().
--- kernel/events/core.c | 60 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 12 deletions(-)
kernel/events/core.c +48 -12
@@ -242,18 +242,6 @@ unlock:return ret; } -static void event_function_local (struct perf_event *event,event_f func,void *data) -{ -struct event_function_struct efs = { - .event = event, - .func = func, - .data = data, - }; - -int ret =event_function (&efs); -WARN_ON_ONCE (ret); -} -static void event_function_call (struct perf_event *event,event_f func,void *data) {struct perf_event_context *ctx = event->ctx;
@@ -303,6 +291,54 @@ again:raw_spin_unlock_irq (&ctx->lock); } +/* +* Similar to event_function_call() + event_function(), but hard assumes IRQs +* are already disabled and we're on the right CPU. +*/ +static void event_function_local (struct perf_event *event,event_f func,void *data) +{ +struct perf_event_context *ctx = event->ctx; +struct perf_cpu_context *cpuctx =__get_cpu_context (ctx); +struct task_struct *task =READ_ONCE (ctx->task); +struct perf_event_context *task_ctx =NULL ; + +WARN_ON_ONCE (!irqs_disabled ()); + +if (task) { +if (task ==TASK_TOMBSTONE ) +return ; + + task_ctx = ctx; + } + +perf_ctx_lock (cpuctx, task_ctx); + + task = ctx->task; +if (task ==TASK_TOMBSTONE ) + goto unlock; + +if (task) { +/* +* We must be either inactive or active and the right task, +* otherwise we're screwed, since we cannot IPI to somewhere +* else. +*/ +if (ctx->is_active) { +if (WARN_ON_ONCE (task != current)) + goto unlock; + +if (WARN_ON_ONCE (cpuctx->task_ctx != ctx)) + goto unlock; + } + }else { +WARN_ON_ONCE (&cpuctx->ctx != ctx); + } + +func (event, cpuctx, ctx, data); +unlock: +perf_ctx_unlock (cpuctx, task_ctx); +} +#define PERF_FLAG_ALL (PERF_FLAG_FD_NO_GROUP |\ PERF_FLAG_FD_OUTPUT |\ PERF_FLAG_PID_CGROUP |\
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/x86-mm-disable-preemption-during-cr3-read-write.patch queue-4.7/uprobes-fix-the-memcg-accounting.patch queue-4.7/uprobes-x86-fix-rip-relative-handling-of-evex-encoded-instructions.patch queue-4.7/sched-cputime-fix-no_hz_full-getrusage-monotonicity-regression.patch queue-4.7/x86-platform-uv-skip-uv-runtime-services-mapping-in-the-efi_runtime_disabled-case.patch queue-4.7/perf-core-fix-event_function_local.patch queue-4.7/perf-symbols-fix-annotation-of-objects-with-debuginfo-files.patch queue-4.7/efi-capsule-allocate-whole-capsule-into-virtual-memory.patch