From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752913AbbFRWUP (ORCPT ); Thu, 18 Jun 2015 18:20:15 -0400 Received: from terminus.zytor.com ([198.137.202.10]:38164 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750911AbbFRWUI (ORCPT ); Thu, 18 Jun 2015 18:20:08 -0400 Date: Thu, 18 Jun 2015 15:19:27 -0700 From: tip-bot for Peter Zijlstra Message-ID: Cc: torvalds@linux-foundation.org, tglx@linutronix.de, viro@ZenIV.linux.org.uk, linux-kernel@vger.kernel.org, hpa@zytor.com, oleg@redhat.com, peterz@infradead.org, mingo@kernel.org, paulmck@linux.vnet.ibm.com Reply-To: torvalds@linux-foundation.org, linux-kernel@vger.kernel.org, hpa@zytor.com, viro@ZenIV.linux.org.uk, tglx@linutronix.de, mingo@kernel.org, peterz@infradead.org, oleg@redhat.com, paulmck@linux.vnet.ibm.com In-Reply-To: <20150617122924.GP3644@twins.programming.kicks-ass.net> References: <20150617122924.GP3644@twins.programming.kicks-ass.net> To: linux-tip-commits@vger.kernel.org Subject: [tip:timers/core] seqcount: Introduce raw_write_seqcount_barrier( ) Git-Commit-ID: c4bfa3f5f906aee2e084c5b1fb15caf876338ef8 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: c4bfa3f5f906aee2e084c5b1fb15caf876338ef8 Gitweb: http://git.kernel.org/tip/c4bfa3f5f906aee2e084c5b1fb15caf876338ef8 Author: Peter Zijlstra AuthorDate: Wed, 17 Jun 2015 14:29:24 +0200 Committer: Thomas Gleixner CommitDate: Fri, 19 Jun 2015 00:09:56 +0200 seqcount: Introduce raw_write_seqcount_barrier() Introduce raw_write_seqcount_barrier(), a new construct that can be used to provide write barrier semantics in seqcount read loops instead of the usual consistency guarantee. raw_write_seqcount_barier() is equivalent to: raw_write_seqcount_begin(); raw_write_seqcount_end(); But avoids issueing two back-to-back smp_wmb() instructions. This construct works because the read side will 'stall' when observing odd values. This means that -- referring to the example in the comment below -- even though there is no (matching) read barrier between the loads of X and Y, we cannot observe !x && !y, because: - if we observe Y == false we must observe the first sequence increment, which makes us loop, until - we observe !(seq & 1) -- the second sequence increment -- at which time we must also observe T == true. Suggested-by: Oleg Nesterov Signed-off-by: Peter Zijlstra (Intel) Cc: umgwanakikbuti@gmail.com Cc: ktkhai@parallels.com Cc: rostedt@goodmis.org Cc: juri.lelli@gmail.com Cc: pang.xunlei@linaro.org Cc: oleg@redhat.com Cc: wanpeng.li@linux.intel.com Cc: Al Viro Cc: Linus Torvalds Cc: Paul E. McKenney Link: http://lkml.kernel.org/r/20150617122924.GP3644@twins.programming.kicks-ass.net Signed-off-by: Thomas Gleixner --- include/linux/seqlock.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index c07e3a5..486e685 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h @@ -233,6 +233,47 @@ static inline void raw_write_seqcount_end(seqcount_t *s) s->sequence++; } +/** + * raw_write_seqcount_barrier - do a seq write barrier + * @s: pointer to seqcount_t + * + * This can be used to provide an ordering guarantee instead of the + * usual consistency guarantee. It is one wmb cheaper, because we can + * collapse the two back-to-back wmb()s. + * + * seqcount_t seq; + * bool X = true, Y = false; + * + * void read(void) + * { + * bool x, y; + * + * do { + * int s = read_seqcount_begin(&seq); + * + * x = X; y = Y; + * + * } while (read_seqcount_retry(&seq, s)); + * + * BUG_ON(!x && !y); + * } + * + * void write(void) + * { + * Y = true; + * + * raw_write_seqcount_barrier(seq); + * + * X = false; + * } + */ +static inline void raw_write_seqcount_barrier(seqcount_t *s) +{ + s->sequence++; + smp_wmb(); + s->sequence++; +} + /* * raw_write_seqcount_latch - redirect readers to even/odd copy * @s: pointer to seqcount_t