From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754942AbcARMhd (ORCPT ); Mon, 18 Jan 2016 07:37:33 -0500 Received: from mga01.intel.com ([192.55.52.88]:25256 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754758AbcARMha (ORCPT ); Mon, 18 Jan 2016 07:37:30 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,312,1449561600"; d="scan'208";a="863030619" From: Alexander Shishkin To: Peter Zijlstra Cc: Ingo Molnar , linux-kernel@vger.kernel.org, vince@deater.net, eranian@google.com, Arnaldo Carvalho de Melo , Jiri Olsa Subject: Re: [PATCH] perf: Synchronously cleanup child events In-Reply-To: <20160115175759.GL3421@worktop> References: <20160115130932.GL6357@twins.programming.kicks-ass.net> <1452866861-17680-1-git-send-email-alexander.shishkin@linux.intel.com> <20160115175759.GL3421@worktop> User-Agent: Notmuch/0.21 (http://notmuchmail.org) Emacs/24.5.1 (x86_64-pc-linux-gnu) Date: Mon, 18 Jan 2016 14:37:06 +0200 Message-ID: <8760yr83nx.fsf@ashishki-desk.ger.corp.intel.com> MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Peter Zijlstra writes: > I suspect this races against inherit_event(), like: > > inherit_event() perf_event_release_kernel() > > if (is_orphaned_event(parent_event) /* false */ > > event->owner = NULL > > mutex_lock(child_mutex); > list_splice > mutex_unlock(child_mutex); > > mutex_lock(child_mutex); > list_add_tail > mutex_unlock(child_mutex); Or how about this instead: diff --git a/kernel/events/core.c b/kernel/events/core.c index 8eb3fee429..cd9f1ac537 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3786,8 +3786,9 @@ int perf_event_release_kernel(struct perf_event *event) event->owner = NULL; +retry: /* - * event::child_mutex nests inside ctx::lock, so move children + * event::child_mutex nests inside ctx::mutex, so move children * to a safe place first and avoid inversion */ mutex_lock(&event->child_mutex); @@ -3818,8 +3819,13 @@ int perf_event_release_kernel(struct perf_event *event) put_event(event); } - /* Must be the last reference */ + /* Must be the last reference, .. */ put_event(event); + + /* .. unless we raced with inherit_event(), in which case, repeat */ + if (atomic_long_inc_not_zero(&event->refcount)) + goto retry; + return 0; } EXPORT_SYMBOL_GPL(perf_event_release_kernel);