Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1463642

Re: perf: fuzzer WARNING event_function_local.constprop

From Peter Zijlstra <peterz@infradead.org>
Newsgroups linux.kernel
Subject Re: perf: fuzzer WARNING event_function_local.constprop
Date 2016-08-16 12:10 +0200
Message-ID <s6JtM-1KE-9@gated-at.bofh.it> (permalink)
References <s5nYm-4bK-19@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


On Fri, Aug 12, 2016 at 12:59:11PM -0400, Vince Weaver wrote:
> 
> Got this while fuzzing on the Haswell machine.  It's relatively repeatable 
> if anyone wants me to chase it down more.
> 
> It maps to
> 	int ret = event_function(&efs);
> 	WARN_ON_ONCE(ret);
> In event_function_local()

Blergh, so I've been running perf_fuzzer for almost two hours and
_nothing_ :/

In any case, while it was running I think I've figured out how this can
happen.


Could you see if the below cures things?

---
 kernel/events/core.c | 60 +++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 48 insertions(+), 12 deletions(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 7090cc734a8e..406f79a6f22f 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -242,18 +242,6 @@ static int event_function(void *info)
 	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 @@ static void event_function_call(struct perf_event *event, event_f func, void *da
 	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 |\

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

perf: fuzzer WARNING event_function_local.constprop Vince Weaver <vincent.weaver@maine.edu> - 2016-08-12 19:00 +0200
  Re: perf: fuzzer WARNING event_function_local.constprop Peter Zijlstra <peterz@infradead.org> - 2016-08-16 12:10 +0200
    Re: perf: fuzzer WARNING event_function_local.constprop Vince Weaver <vincent.weaver@maine.edu> - 2016-08-16 18:20 +0200
      Re: perf: fuzzer WARNING event_function_local.constprop Peter Zijlstra <peterz@infradead.org> - 2016-08-16 19:10 +0200

csiph-web