From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753620AbbIJQVz (ORCPT ); Thu, 10 Sep 2015 12:21:55 -0400 Received: from casper.infradead.org ([85.118.1.10]:41331 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752209AbbIJQVx (ORCPT ); Thu, 10 Sep 2015 12:21:53 -0400 Message-Id: <20150910162008.028400851@infradead.org> User-Agent: quilt/0.61-1 Date: Thu, 10 Sep 2015 18:16:24 +0200 From: Peter Zijlstra To: mingo@kernel.org Cc: linux-kernel@vger.kernel.org, vincent.weaver@maine.edu, acme@kernel.org, eranian@google.com, jolsa@redhat.com, alexander.shishkin@linux.intel.com, peterz@infradead.org Subject: [RFC][PATCH 3/3] perf: Fix races in computing the header sizes References: <20150910161621.363774906@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline; filename=peterz-perf-fix-size-compute.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There are two races with the current code: - Another event can join the group and compute a larger header_size concurrently, if the smaller store wins we'll have an incorrect header_size set. - We compute the header_size after the event becomes active, therefore its possible to use the size before its computed. Remedy the first by moving the computation inside the ctx::mutex lock, and the second by placing it _before_ perf_install_in_context(). Cc: Arnaldo Carvalho de Melo Signed-off-by: Peter Zijlstra (Intel) --- kernel/events/core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8349,6 +8349,15 @@ SYSCALL_DEFINE5(perf_event_open, put_ctx(gctx); } + /* + * Precalculate sample_data sizes; do while holding ctx::mutex such + * that we're serialized against further additions and before + * perf_install_in_context() which is the point the event is active and + * can use these values. + */ + perf_event__header_size(event); + perf_event__id_header_size(event); + perf_install_in_context(ctx, event, event->cpu); perf_unpin_context(ctx); @@ -8365,12 +8374,6 @@ SYSCALL_DEFINE5(perf_event_open, mutex_unlock(¤t->perf_event_mutex); /* - * Precalculate sample_data sizes - */ - perf_event__header_size(event); - perf_event__id_header_size(event); - - /* * Drop the reference on the group_event after placing the * new event on the sibling_list. This ensures destruction * of the group leader will find the pointer to itself in