mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: mingo@kernel.org
Cc: linux-kernel@vger.kernel.org, acme@kernel.org,
	mathieu.desnoyers@efficios.com,
	alexander.shishkin@linux.intel.com, dvyukov@google.com,
	fweisbec@gmail.com, oleg@redhat.com, peterz@infradead.org
Subject: [PATCH 4/4] perf: Better explain the inherit magic
Date: Thu, 16 Mar 2017 13:47:51 +0100	[thread overview]
Message-ID: <20170316125823.289567442@infradead.org> (raw)
In-Reply-To: <20170316124747.804596354@infradead.org>

[-- Attachment #1: peterz-perf-comment-inherit.patch --]
[-- Type: text/plain, Size: 3784 bytes --]

While going through the event inheritance code Oleg got confused.

Add some comments to better explain the silent dissapearance of
orphaned events.

So what happens is that at perf_event_release_kernel() time; when an
event looses its connection to userspace (and ceases to exist from the
user's perspective) we can still have an arbitrary amount of inherited
copies of the event. We want to synchronously find and remove all
these child events.

Since that requires a bit of lock juggling, there is the possibility
that concurrent clone()s will create new child events. Therefore we
first mark the parent event as DEAD, which marks all the extant child
events as orphaned.

We then avoid copying orphaned events; in order to avoid getting more
of them.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 kernel/events/core.c |   36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4261,7 +4261,7 @@ int perf_event_release_kernel(struct per
 
 	raw_spin_lock_irq(&ctx->lock);
 	/*
-	 * Mark this even as STATE_DEAD, there is no external reference to it
+	 * Mark this event as STATE_DEAD, there is no external reference to it
 	 * anymore.
 	 *
 	 * Anybody acquiring event->child_mutex after the below loop _must_
@@ -10609,7 +10609,12 @@ const struct perf_event_attr *perf_event
 }
 
 /*
- * inherit a event from parent task to child task:
+ * Inherit a event from parent task to child task.
+ *
+ * Returns:
+ *  - valid pointer on success
+ *  - NULL for orphaned events
+ *  - IS_ERR() on error
  */
 static struct perf_event *
 inherit_event(struct perf_event *parent_event,
@@ -10703,6 +10708,16 @@ inherit_event(struct perf_event *parent_
 	return child_event;
 }
 
+/*
+ * Inherits an event group.
+ *
+ * This will quietly suppress orphaned events; !inherit_event() is not an error.
+ * This matches with perf_event_release_kernel() removing all child events.
+ *
+ * Returns:
+ *  - 0 on success
+ *  - <0 on error
+ */
 static int inherit_group(struct perf_event *parent_event,
 	      struct task_struct *parent,
 	      struct perf_event_context *parent_ctx,
@@ -10717,6 +10732,11 @@ static int inherit_group(struct perf_eve
 				 child, NULL, child_ctx);
 	if (IS_ERR(leader))
 		return PTR_ERR(leader);
+	/*
+	 * @leader can be NULL here because of is_orphaned_event(). In this
+	 * case inherit_event() will create individual events, similar to what
+	 * perf_group_detach() would do anyway.
+	 */
 	list_for_each_entry(sub, &parent_event->sibling_list, group_entry) {
 		child_ctr = inherit_event(sub, parent, parent_ctx,
 					    child, leader, child_ctx);
@@ -10726,6 +10746,17 @@ static int inherit_group(struct perf_eve
 	return 0;
 }
 
+/*
+ * Creates the child task context and tries to inherit the event-group.
+ *
+ * Clears @inherited_all on !attr.inherited or error. Note that we'll leave
+ * inherited_all set when we 'fail' to inherit an orphaned event; this is
+ * consistent with perf_event_release_kernel() removing all child events.
+ *
+ * Returns:
+ *  - 0 on success
+ *  - <0 on error
+ */
 static int
 inherit_task_group(struct perf_event *event, struct task_struct *parent,
 		   struct perf_event_context *parent_ctx,
@@ -10748,7 +10779,6 @@ inherit_task_group(struct perf_event *ev
 		 * First allocate and initialize a context for the
 		 * child.
 		 */
-
 		child_ctx = alloc_perf_context(parent_ctx->pmu, child);
 		if (!child_ctx)
 			return -ENOMEM;

  parent reply	other threads:[~2017-03-16 13:00 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-16 12:47 [PATCH 0/4] perf patches Peter Zijlstra
2017-03-16 12:47 ` [PATCH 1/4] perf: Fix use-after-free in perf_release() Peter Zijlstra
2017-03-16 15:19   ` [tip:perf/urgent] perf/core: " tip-bot for Peter Zijlstra
2017-03-16 12:47 ` [PATCH 2/4] perf: Fix event inheritance on fork() Peter Zijlstra
2017-03-16 15:19   ` [tip:perf/urgent] perf/core: " tip-bot for Peter Zijlstra
2017-03-16 12:47 ` [PATCH 3/4] perf: Simplify perf_event_free_task() Peter Zijlstra
2017-03-16 15:20   ` [tip:perf/urgent] perf/core: " tip-bot for Peter Zijlstra
2017-03-16 12:47 ` Peter Zijlstra [this message]
2017-03-16 15:21   ` [tip:perf/urgent] perf/core: Better explain the inherit magic tip-bot for Peter Zijlstra
2017-03-16 13:20 ` [PATCH 0/4] perf patches Ingo Molnar
  -- strict thread matches above, loose matches on Subject: below --
2017-03-06  9:57 perf: use-after-free in perf_release Dmitry Vyukov
2017-03-06 12:13 ` Peter Zijlstra
2017-03-06 12:17   ` Dmitry Vyukov
2017-03-06 12:23     ` Peter Zijlstra
2017-03-06 12:27       ` Dmitry Vyukov
2017-03-06 12:47         ` Peter Zijlstra
2017-03-06 13:14 ` Peter Zijlstra
2017-03-06 13:34   ` Dmitry Vyukov
2017-03-07  9:08     ` Peter Zijlstra
2017-03-07  9:26       ` Dmitry Vyukov
2017-03-07  9:37         ` Peter Zijlstra
2017-03-07  9:43           ` Dmitry Vyukov
2017-03-07 10:00             ` Peter Zijlstra
2017-03-07 13:16   ` Peter Zijlstra
2017-03-07 13:27     ` Peter Zijlstra
2017-03-07 14:04   ` Oleg Nesterov
2017-03-07 14:17     ` Dmitry Vyukov
2017-03-07 16:51       ` Oleg Nesterov
2017-03-07 17:29         ` Peter Zijlstra
2017-03-14 12:55         ` Peter Zijlstra
2017-03-14 13:24           ` Oleg Nesterov
2017-03-14 13:47             ` Peter Zijlstra
2017-03-14 14:03           ` Oleg Nesterov
2017-03-14 14:07             ` Peter Zijlstra
2017-03-14 14:30               ` Oleg Nesterov
2017-03-14 15:02                 ` Peter Zijlstra
2017-03-14 15:07                   ` Peter Zijlstra
2017-03-14 15:37                     ` Oleg Nesterov
2017-03-14 15:46                       ` Peter Zijlstra
2017-03-14 15:19                   ` Oleg Nesterov
2017-03-14 15:26                     ` Peter Zijlstra
2017-03-14 15:59                       ` Peter Zijlstra
2017-03-15 16:43                         ` Oleg Nesterov
2017-03-16 12:05                           ` Peter Zijlstra
2017-03-16 13:57                           ` Peter Zijlstra
2017-03-16 16:41                             ` Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170316125823.289567442@infradead.org \
    --to=peterz@infradead.org \
    --cc=acme@kernel.org \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=dvyukov@google.com \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mingo@kernel.org \
    --cc=oleg@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®