From patchwork Wed Nov 2 20:30:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. McKenney" X-Patchwork-Id: 4904 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 32C3723DC3 for ; Wed, 2 Nov 2011 20:31:32 +0000 (UTC) Received: from mail-fx0-f52.google.com (mail-fx0-f52.google.com [209.85.161.52]) by fiordland.canonical.com (Postfix) with ESMTP id 218F2A18670 for ; Wed, 2 Nov 2011 20:31:32 +0000 (UTC) Received: by mail-fx0-f52.google.com with SMTP id n26so1195523faa.11 for ; Wed, 02 Nov 2011 13:31:32 -0700 (PDT) Received: by 10.223.6.129 with SMTP id 1mr238008faz.17.1320265891979; Wed, 02 Nov 2011 13:31:31 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.14.103 with SMTP id o7cs64021lac; Wed, 2 Nov 2011 13:31:31 -0700 (PDT) Received: by 10.52.33.69 with SMTP id p5mr6130317vdi.78.1320265889864; Wed, 02 Nov 2011 13:31:29 -0700 (PDT) Received: from e5.ny.us.ibm.com (e5.ny.us.ibm.com. [32.97.182.145]) by mx.google.com with ESMTPS id s10si855854vcq.34.2011.11.02.13.31.28 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 02 Nov 2011 13:31:29 -0700 (PDT) Received-SPF: pass (google.com: domain of paulmck@linux.vnet.ibm.com designates 32.97.182.145 as permitted sender) client-ip=32.97.182.145; Authentication-Results: mx.google.com; spf=pass (google.com: domain of paulmck@linux.vnet.ibm.com designates 32.97.182.145 as permitted sender) smtp.mail=paulmck@linux.vnet.ibm.com Received: from /spool/local by e5.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 2 Nov 2011 16:31:27 -0400 Received: from d01relay07.pok.ibm.com ([9.56.227.147]) by e5.ny.us.ibm.com ([192.168.1.105]) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 2 Nov 2011 16:31:05 -0400 Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay07.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id pA2KV2el2564118 for ; Wed, 2 Nov 2011 16:31:02 -0400 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id pA2KUuWT030157 for ; Wed, 2 Nov 2011 16:31:02 -0400 Received: from paulmck-ThinkPad-W500 (sig-9-49-130-61.mts.ibm.com [9.49.130.61]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id pA2KUscN030044; Wed, 2 Nov 2011 16:30:55 -0400 Received: by paulmck-ThinkPad-W500 (Postfix, from userid 1000) id 2BB4CEAA12; Wed, 2 Nov 2011 13:30:52 -0700 (PDT) From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: mingo@elte.hu, laijs@cn.fujitsu.com, dipankar@in.ibm.com, akpm@linux-foundation.org, mathieu.desnoyers@polymtl.ca, josh@joshtriplett.org, niv@us.ibm.com, tglx@linutronix.de, peterz@infradead.org, rostedt@goodmis.org, Valdis.Kletnieks@vt.edu, dhowells@redhat.com, eric.dumazet@gmail.com, darren@dvhart.com, patches@linaro.org, "Paul E. McKenney" Subject: [PATCH RFC tip/core/rcu 24/28] rcu: Introduce bulk reference count Date: Wed, 2 Nov 2011 13:30:45 -0700 Message-Id: <1320265849-5744-24-git-send-email-paulmck@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.3.2 In-Reply-To: <20111102203017.GA3830@linux.vnet.ibm.com> References: <20111102203017.GA3830@linux.vnet.ibm.com> x-cbid: 11110220-5930-0000-0000-000000D635B7 The RCU implementations, including SRCU, are designed to be used in a lock-like fashion, so that the read-side lock and unlock primitives must execute in the same context for any given read-side critical section. This constraint is enforced by lockdep-RCU. However, there is a need for something that acts more like a reference count than a lock, in order to allow (for example) the reference to be acquired within the context of an exception, while that same reference is released in the context of the task that encountered the exception. The cost of this capability is that the read-side operations incur the overhead of disabling interrupts. Some optimization is possible, and will be carried out if warranted. Note that although the current implementation allows a given reference to be acquired by one task and then released by another, all known possible implementations that allow this have scalability problems. Therefore, a given reference must be released by the same task that acquired it, though perhaps from an interrupt or exception handler running within that task's context. Requested-by: Srikar Dronamraju Signed-off-by: Paul E. McKenney Tested-by: Srikar Dronamraju --- include/linux/srcu.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/srcu.c | 3 ++- 2 files changed, 52 insertions(+), 1 deletions(-) diff --git a/include/linux/srcu.h b/include/linux/srcu.h index d4b1244..d5334d0 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -181,4 +181,54 @@ static inline void srcu_read_unlock(struct srcu_struct *sp, int idx) __srcu_read_unlock(sp, idx); } +/* Definitions for bulkref_t, currently defined in terms of SRCU. */ + +typedef struct srcu_struct bulkref_t; +int init_srcu_struct_fields(struct srcu_struct *sp); + +static inline int init_bulkref(bulkref_t *brp) +{ + return init_srcu_struct_fields(brp); +} + +static inline void cleanup_bulkref(bulkref_t *brp) +{ + cleanup_srcu_struct(brp); +} + +static inline int bulkref_get(bulkref_t *brp) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + ret = __srcu_read_lock(brp); + local_irq_restore(flags); + return ret; +} + +static inline void bulkref_put(bulkref_t *brp, int idx) +{ + unsigned long flags; + + local_irq_save(flags); + __srcu_read_unlock(brp, idx); + local_irq_restore(flags); +} + +static inline void bulkref_wait_old(bulkref_t *brp) +{ + synchronize_srcu(brp); +} + +static inline void bulkref_wait_old_expedited(bulkref_t *brp) +{ + synchronize_srcu_expedited(brp); +} + +static inline long bulkref_batches_completed(bulkref_t *brp) +{ + return srcu_batches_completed(brp); +} + #endif diff --git a/kernel/srcu.c b/kernel/srcu.c index 73ce23f..10214c8 100644 --- a/kernel/srcu.c +++ b/kernel/srcu.c @@ -34,13 +34,14 @@ #include #include -static int init_srcu_struct_fields(struct srcu_struct *sp) +int init_srcu_struct_fields(struct srcu_struct *sp) { sp->completed = 0; mutex_init(&sp->mutex); sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array); return sp->per_cpu_ref ? 0 : -ENOMEM; } +EXPORT_SYMBOL_GPL(init_srcu_struct_fields); #ifdef CONFIG_DEBUG_LOCK_ALLOC