From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752611AbcEaJxZ (ORCPT ); Tue, 31 May 2016 05:53:25 -0400 Received: from merlin.infradead.org ([205.233.59.134]:48166 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752255AbcEaJxV (ORCPT ); Tue, 31 May 2016 05:53:21 -0400 Message-Id: <20160531094843.976191553@infradead.org> User-Agent: quilt/0.61-1 Date: Tue, 31 May 2016 11:41:36 +0200 From: Peter Zijlstra To: linux-kernel@vger.kernel.org, torvalds@linux-foundation.org, manfred@colorfullife.com, dave@stgolabs.net, paulmck@linux.vnet.ibm.com, will.deacon@arm.com Cc: boqun.feng@gmail.com, Waiman.Long@hpe.com, tj@kernel.org, pablo@netfilter.org, kaber@trash.net, davem@davemloft.net, oleg@redhat.com, netfilter-devel@vger.kernel.org, sasha.levin@oracle.com, hofrat@osadl.org, peterz@infradead.org Subject: [PATCH -v3 2/8] locking: Introduce cmpwait() References: <20160531094134.606249808@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline; filename=peterz-locking-cmp_and_wait.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Provide the cmpwait() primitive, which will 'spin' wait for a variable to change and use it to implement smp_cond_load_acquire(). This primitive can be implemented with hardware assist on some platforms (ARM64, x86). Suggested-by: Will Deacon Signed-off-by: Peter Zijlstra (Intel) --- include/linux/compiler.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -305,6 +305,23 @@ static __always_inline void __write_once }) /** + * cmpwait - compare and wait for a variable to change + * @ptr: pointer to the variable to wait on + * @val: the value it should change from + * + * A simple constuct that waits for a variable to change from a known + * value; some architectures can do this in hardware. + */ +#ifndef cmpwait +#define cmpwait(ptr, val) do { \ + typeof (ptr) __ptr = (ptr); \ + typeof (val) __val = (val); \ + while (READ_ONCE(*__ptr) == __val) \ + cpu_relax(); \ +} while (0) +#endif + +/** * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering * @ptr: pointer to the variable to wait on * @cond: boolean expression to wait for @@ -327,7 +344,7 @@ static __always_inline void __write_once VAL = READ_ONCE(*__PTR); \ if (cond_expr) \ break; \ - cpu_relax(); \ + cmpwait(__PTR, VAL); \ } \ smp_rmb(); /* ctrl + rmb := acquire */ \ VAL; \