Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752955AbbHURqs (ORCPT ); Fri, 21 Aug 2015 13:46:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51307 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752660AbbHURpS (ORCPT ); Fri, 21 Aug 2015 13:45:18 -0400 Date: Fri, 21 Aug 2015 19:42:52 +0200 From: Oleg Nesterov To: Paul McKenney Cc: Ingo Molnar , Linus Torvalds , Peter Zijlstra , Tejun Heo , linux-kernel@vger.kernel.org Subject: [PATCH v2 4/8] rcusync: Introduce rcu_sync_dtor() Message-ID: <20150821174252.GA17900@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150821174230.GA17867@redhat.com> User-Agent: Mutt/1.5.18 (2008-05-17) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2628 Lines: 89 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(+), 0 deletions(-) diff --git a/include/linux/rcusync.h b/include/linux/rcusync.h index 631a842..50229c0 100644 --- a/include/linux/rcusync.h +++ b/include/linux/rcusync.h @@ -31,6 +31,7 @@ static inline bool rcu_sync_is_idle(struct rcu_sync_struct *rss) 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, \ diff --git a/kernel/rcu/sync.c b/kernel/rcu/sync.c index 0ab7cbd..7e2a9aa 100644 --- 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) }, }; @@ -127,3 +131,21 @@ void rcu_sync_exit(struct rcu_sync_struct *rss) } 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); + } +} -- 1.5.5.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/