From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754751AbbFVM1H (ORCPT ); Mon, 22 Jun 2015 08:27:07 -0400 Received: from bombadil.infradead.org ([198.137.202.9]:37085 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754364AbbFVMYk (ORCPT ); Mon, 22 Jun 2015 08:24:40 -0400 Message-Id: <20150622122255.977917138@infradead.org> User-Agent: quilt/0.61-1 Date: Mon, 22 Jun 2015 14:16:27 +0200 From: Peter Zijlstra To: oleg@redhat.com, paulmck@linux.vnet.ibm.com Cc: tj@kernel.org, mingo@redhat.com, linux-kernel@vger.kernel.org, der.herr@hofr.at, peterz@infradead.org, dave@stgolabs.net, riel@redhat.com, viro@ZenIV.linux.org.uk, torvalds@linux-foundation.org Subject: [RFC][PATCH 04/13] rcusync: Introduce rcu_sync_dtor() References: <20150622121623.291363374@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline; filename=oleg_nesterov-6_rcusync-introduce_rcu_sync_dtor.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add the new rcu_sync_ops->wait() method and the new helper, rcu_sync_dtor(). It is needed if you are going to, say, kfree(rcu_sync_object). It simply calls ops->wait() to "flush" the potentially pending rcu callback. Reviewed-by: Paul E. McKenney Signed-off-by: Oleg Nesterov Signed-off-by: Peter Zijlstra (Intel) --- include/linux/rcusync.h | 1 + kernel/rcu/sync.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) --- a/include/linux/rcusync.h +++ b/include/linux/rcusync.h @@ -31,6 +31,7 @@ static inline bool rcu_sync_is_idle(stru extern void rcu_sync_init(struct rcu_sync_struct *, enum rcu_sync_type); extern void rcu_sync_enter(struct rcu_sync_struct *); extern void rcu_sync_exit(struct rcu_sync_struct *); +extern void rcu_sync_dtor(struct rcu_sync_struct *); #define __RCU_SYNC_INITIALIZER(name, type) { \ .gp_state = 0, \ --- a/kernel/rcu/sync.c +++ b/kernel/rcu/sync.c @@ -10,6 +10,7 @@ static const struct { void (*sync)(void); void (*call)(struct rcu_head *, void (*)(struct rcu_head *)); + void (*wait)(void); #ifdef CONFIG_PROVE_RCU int (*held)(void); #endif @@ -17,16 +18,19 @@ static const struct { [RCU_SYNC] = { .sync = synchronize_rcu, .call = call_rcu, + .wait = rcu_barrier, __INIT_HELD(rcu_read_lock_held) }, [RCU_SCHED_SYNC] = { .sync = synchronize_sched, .call = call_rcu_sched, + .wait = rcu_barrier_sched, __INIT_HELD(rcu_read_lock_sched_held) }, [RCU_BH_SYNC] = { .sync = synchronize_rcu_bh, .call = call_rcu_bh, + .wait = rcu_barrier_bh, __INIT_HELD(rcu_read_lock_bh_held) }, }; @@ -128,3 +132,21 @@ void rcu_sync_exit(struct rcu_sync_struc } spin_unlock_irq(&rss->rss_lock); } + +void rcu_sync_dtor(struct rcu_sync_struct *rss) +{ + int cb_state; + + BUG_ON(rss->gp_count); + + spin_lock_irq(&rss->rss_lock); + if (rss->cb_state == CB_REPLAY) + rss->cb_state = CB_PENDING; + cb_state = rss->cb_state; + spin_unlock_irq(&rss->rss_lock); + + if (cb_state != CB_IDLE) { + gp_ops[rss->gp_type].wait(); + BUG_ON(rss->cb_state != CB_IDLE); + } +} -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in Please read the FAQ at http://www.tux.org/lkml/