LKML Archive on
 help / color / Atom feed
From: Jiri Olsa <>
To: Peter Zijlstra <>
Cc: lkml <>,
	Ingo Molnar <>, Andi Kleen <>,
	Alexander Shishkin <>
Subject: [PATCH] perf: Fix locking for children siblings group read
Date: Thu, 20 Jul 2017 16:14:55 +0200
Message-ID: <> (raw)

We're missing ctx lock when iterating children siblings
within the perf_read path for group reading. Following
race and crash can happen:

User space doing read syscall on event group leader:

    lock event->ctx->mutex
      lock leader->child_mutex
        list_for_each_entry(sub, &leader->sibling_list, group_entry)

---->   sub might be invalid at this point, because it could
        get removed via perf_event_exit_task_context in T2

Child exiting and cleaning up its events:

    lock ctx->mutex
    list_for_each_entry_safe(child_event, next, &child_ctx->event_list,...
        lock ctx->lock
        unlock ctx->lock

---->   child is removed from sibling_list without any sync
        with T1 path above


Before the child is removed from the leader's child_list,
(and thus is omitted from perf_read_group processing), we
need to ensure that perf_read_group touches child's
siblings under its ctx->lock.

Tested-by: Andi Kleen <>
Signed-off-by: Jiri Olsa <>
 kernel/events/core.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 9747e422ab20..585955b41489 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4365,7 +4365,9 @@ EXPORT_SYMBOL_GPL(perf_event_read_value);
 static int __perf_read_group_add(struct perf_event *leader,
 					u64 read_format, u64 *values)
+	struct perf_event_context *ctx = leader->ctx;
 	struct perf_event *sub;
+	unsigned long flags;
 	int n = 1; /* skip @nr */
 	int ret;
@@ -4395,12 +4397,15 @@ static int __perf_read_group_add(struct perf_event *leader,
 	if (read_format & PERF_FORMAT_ID)
 		values[n++] = primary_event_id(leader);
+	raw_spin_lock_irqsave(&ctx->lock, flags);
 	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
 		values[n++] += perf_event_count(sub);
 		if (read_format & PERF_FORMAT_ID)
 			values[n++] = primary_event_id(sub);
+	raw_spin_unlock_irqrestore(&ctx->lock, flags);
 	return 0;

             reply index

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-20 14:14 Jiri Olsa [this message]
2017-07-20 14:41 ` Peter Zijlstra
2017-07-21  9:37 ` [tip:perf/urgent] perf/core: " tip-bot for Jiri Olsa

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:

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

  git send-email \ \ \ \ \ \ \ \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

LKML Archive on

Archives are clonable:
	git clone --mirror lkml/git/0.git
	git clone --mirror lkml/git/1.git
	git clone --mirror lkml/git/2.git
	git clone --mirror lkml/git/3.git
	git clone --mirror lkml/git/4.git
	git clone --mirror lkml/git/5.git
	git clone --mirror lkml/git/6.git
	git clone --mirror lkml/git/7.git
	git clone --mirror lkml/git/8.git
	git clone --mirror lkml/git/9.git
	git clone --mirror lkml/git/10.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ \
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:

AGPL code for this site: git clone