Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756848AbdDRAdq (ORCPT ); Mon, 17 Apr 2017 20:33:46 -0400 Received: from relay8-d.mail.gandi.net ([217.70.183.201]:42254 "EHLO relay8-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753367AbdDRAdm (ORCPT ); Mon, 17 Apr 2017 20:33:42 -0400 X-Originating-IP: 50.39.160.18 Date: Mon, 17 Apr 2017 17:33:32 -0700 From: Josh Triplett To: "Paul E. McKenney" Cc: linux-kernel@vger.kernel.org, mingo@kernel.org, jiangshanlai@gmail.com, dipankar@in.ibm.com, akpm@linux-foundation.org, mathieu.desnoyers@efficios.com, tglx@linutronix.de, peterz@infradead.org, rostedt@goodmis.org, dhowells@redhat.com, edumazet@google.com, fweisbec@gmail.com, oleg@redhat.com, bobby.prani@gmail.com Subject: Re: [PATCH v2 tip/core/rcu 04/39] srcu: Check for tardy grace-period activity in cleanup_srcu_struct() Message-ID: <20170418003332.7ocpffvkr3okbhr7@x> References: <20170417234452.GB19013@linux.vnet.ibm.com> <1492472726-3841-4-git-send-email-paulmck@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1492472726-3841-4-git-send-email-paulmck@linux.vnet.ibm.com> User-Agent: NeoMutt/20170306 (1.8.0) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2892 Lines: 69 On Mon, Apr 17, 2017 at 04:44:51PM -0700, Paul E. McKenney wrote: > Users of SRCU are obliged to complete all grace-period activity before > invoking cleanup_srcu_struct(). This means that all calls to either > synchronize_srcu() or synchronize_srcu_expedited() must have returned, > and all calls to call_srcu() must have returned, and the last call to > call_srcu() must have been followed by a call to srcu_barrier(). > Furthermore, the caller must have done something to prevent any > further calls to synchronize_srcu(), synchronize_srcu_expedited(), > and call_srcu(). > > Therefore, if there has ever been an invocation of call_srcu() on > the srcu_struct in question, the sequence of events must be as > follows: > > 1. Prevent any further calls to call_srcu(). > 2. Wait for any pre-existing call_srcu() invocations to return. > 3. Invoke srcu_barrier(). > 4. It is now safe to invoke cleanup_srcu_struct(). > > On the other hand, if there has ever been a call to synchronize_srcu() > or synchronize_srcu_expedited(), the sequence of events must be as > follows: > > 1. Prevent any further calls to synchronize_srcu() or > synchronize_srcu_expedited(). > 2. Wait for any pre-existing synchronize_srcu() or > synchronize_srcu_expedited() invocations to return. > 3. It is now safe to invoke cleanup_srcu_struct(). > > If there have been calls to all both types of functions (call_srcu() > and either of synchronize_srcu() and synchronize_srcu_expedited()), then > the caller must do the first three steps of the call_srcu() procedure > above and the first two steps of the synchronize_s*() procedure above, > and only then invoke cleanup_srcu_struct(). This commit message clearly explains the correct sequence for the client, but not which aspects of this the change now enforces. Some of the steps above remain the responsibility of the caller, while the callee now checks more of them. Could you add something at the end explaining the change and what it enforces? > Reported-by: Paolo Bonzini > Signed-off-by: Paul E. McKenney With the above change: Reviewed-by: Josh Triplett > kernel/rcu/srcu.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/kernel/rcu/srcu.c b/kernel/rcu/srcu.c > index ba41a5d04b49..6beeba7b0b67 100644 > --- a/kernel/rcu/srcu.c > +++ b/kernel/rcu/srcu.c > @@ -261,6 +261,11 @@ void cleanup_srcu_struct(struct srcu_struct *sp) > { > if (WARN_ON(srcu_readers_active(sp))) > return; /* Leakage unless caller handles error. */ > + if (WARN_ON(!rcu_all_batches_empty(sp))) > + return; /* Leakage unless caller handles error. */ > + flush_delayed_work(&sp->work); > + if (WARN_ON(sp->running)) > + return; /* Caller forgot to stop doing call_srcu()? */ > free_percpu(sp->per_cpu_ref); > sp->per_cpu_ref = NULL; > } > -- > 2.5.2 >