All of lore.kernel.org
 help / color / mirror / Atom feed
From: Waiman Long <waiman.long@hp.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	Arnd Bergmann <arnd@arndb.de>,
	linux-arch@vger.kernel.org, x86@kernel.org,
	linux-kernel@vger.kernel.org,
	Steven Rostedt <rostedt@goodmis.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Michel Lespinasse <walken@google.com>,
	Andi Kleen <andi@firstfloor.org>, Rik van Riel <riel@redhat.com>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>,
	George Spelvin <linux@horizon.com>,
	Tim Chen <tim.c.chen@linux.intel.com>,
	aswin@hp.com, Scott J Norton <scott.norton@hp.com>
Subject: Re: [PATCH v9 4/5] qrwlock: Use smp_store_release() in write_unlock()
Date: Tue, 21 Jan 2014 10:45:42 -0500	[thread overview]
Message-ID: <52DE9626.3030806@hp.com> (raw)
In-Reply-To: <20140120151855.GH30183@twins.programming.kicks-ass.net>

On 01/20/2014 10:18 AM, Peter Zijlstra wrote:
> On Tue, Jan 14, 2014 at 11:44:06PM -0500, Waiman Long wrote:
>> This patch modifies the queue_write_unlock() function to use the new
>> smp_store_release() function (currently in tip). It also removes the
>> temporary implementation of smp_load_acquire() and smp_store_release()
>> function in qrwlock.c.
>>
>> This patch will use atomic subtraction instead if the writer field is
>> not atomic.
>>
>> Signed-off-by: Waiman Long<Waiman.Long@hp.com>
>> ---
>>   include/asm-generic/qrwlock.h |   10 ++++++----
>>   kernel/locking/qrwlock.c      |   34 ----------------------------------
>>   2 files changed, 6 insertions(+), 38 deletions(-)
>>
>> diff --git a/include/asm-generic/qrwlock.h b/include/asm-generic/qrwlock.h
>> index 5abb6ca..68f488b 100644
>> --- a/include/asm-generic/qrwlock.h
>> +++ b/include/asm-generic/qrwlock.h
>> @@ -181,11 +181,13 @@ static inline void queue_read_unlock(struct qrwlock *lock)
>>   static inline void queue_write_unlock(struct qrwlock *lock)
>>   {
>>   	/*
>> -	 * Make sure that none of the critical section will be leaked out.
>> +	 * If the writer field is atomic, it can be cleared directly.
>> +	 * Otherwise, an atomic subtraction will be used to clear it.
>>   	 */
>> -	smp_mb__before_clear_bit();
>> -	ACCESS_ONCE(lock->cnts.writer) = 0;
>> -	smp_mb__after_clear_bit();
>> +	if (__native_word(lock->cnts.writer))
>> +		smp_store_release(&lock->cnts.writer, 0);
>> +	else
>> +		atomic_sub(_QW_LOCKED,&lock->cnts.rwa);
>>   }
> If we're a writer, read-count must be zero. The only way for that not to
> be zero is a concurrent read-(try)lock. If you move all the
> read-(try)locks over to cmpxchg() you can avoid this afaict:

That is not true. A reader may transiently set the reader count to a 
non-zero value in the fast path. Also, a reader in interrupt context 
will force a non-zero reader count to take the read lock as soon as the 
writer is done.

>
> static inline void queue_read_trylock(struct qrwlock *lock)
> {
> 	union qrwcnts cnts
>
> 	cnts = ACCESS_ONCE(lock->cnts);
> 	if (!cnts.writer) {
> 		if (cmpxchg(&lock->cnts.rwc, cnts.rwc, cnts.rwc + _QR_BIAS) == cnts.rwc)
> 			return 1;
> 	}
>
> 	return 0;
> }
>
> static inline void queue_read_lock(struct qrwlock *lock)
> {
> 	if (!queue_read_trylock(lock))
> 		queue_read_lock_slowpath(); // XXX do not assume extra _QR_BIAS
> }
>
> At which point you have the guarantee that read-count == 0, and you can
> write:
>
> static inline void queue_write_unlock(struct qrwlock *lock)
> {
> 	smp_store_release(&lock->cnts.rwc, 0);
> }
>
> No?
>

The current code is optimized for the reader-heavy case. So I used xadd 
for incrementing reader count to reduce the chance of retry due to 
concurrent reader count updates. The downside is the need to back out if 
a writer is here.

I can change the logic to use only cmpxchg for readers, but I don't see 
a compelling reason to do so.

-Longman

WARNING: multiple messages have this Message-ID (diff)
From: Waiman Long <waiman.long@hp.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	Arnd Bergmann <arnd@arndb.de>,
	linux-arch@vger.kernel.org, x86@kernel.org,
	linux-kernel@vger.kernel.org,
	Steven Rostedt <rostedt@goodmis.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Michel Lespinasse <walken@google.com>,
	Andi Kleen <andi@firstfloor.org>, Rik van Riel <riel@redhat.com>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>,
	George Spelvin <linux@horizon.com>,
	Tim Chen <tim.c.chen@linux.intel.com>, "" <aswin@hp.com>,
	Scott J Norton <scott.norton@hp.com>
Subject: Re: [PATCH v9 4/5] qrwlock: Use smp_store_release() in write_unlock()
Date: Tue, 21 Jan 2014 10:45:42 -0500	[thread overview]
Message-ID: <52DE9626.3030806@hp.com> (raw)
In-Reply-To: <20140120151855.GH30183@twins.programming.kicks-ass.net>

On 01/20/2014 10:18 AM, Peter Zijlstra wrote:
> On Tue, Jan 14, 2014 at 11:44:06PM -0500, Waiman Long wrote:
>> This patch modifies the queue_write_unlock() function to use the new
>> smp_store_release() function (currently in tip). It also removes the
>> temporary implementation of smp_load_acquire() and smp_store_release()
>> function in qrwlock.c.
>>
>> This patch will use atomic subtraction instead if the writer field is
>> not atomic.
>>
>> Signed-off-by: Waiman Long<Waiman.Long@hp.com>
>> ---
>>   include/asm-generic/qrwlock.h |   10 ++++++----
>>   kernel/locking/qrwlock.c      |   34 ----------------------------------
>>   2 files changed, 6 insertions(+), 38 deletions(-)
>>
>> diff --git a/include/asm-generic/qrwlock.h b/include/asm-generic/qrwlock.h
>> index 5abb6ca..68f488b 100644
>> --- a/include/asm-generic/qrwlock.h
>> +++ b/include/asm-generic/qrwlock.h
>> @@ -181,11 +181,13 @@ static inline void queue_read_unlock(struct qrwlock *lock)
>>   static inline void queue_write_unlock(struct qrwlock *lock)
>>   {
>>   	/*
>> -	 * Make sure that none of the critical section will be leaked out.
>> +	 * If the writer field is atomic, it can be cleared directly.
>> +	 * Otherwise, an atomic subtraction will be used to clear it.
>>   	 */
>> -	smp_mb__before_clear_bit();
>> -	ACCESS_ONCE(lock->cnts.writer) = 0;
>> -	smp_mb__after_clear_bit();
>> +	if (__native_word(lock->cnts.writer))
>> +		smp_store_release(&lock->cnts.writer, 0);
>> +	else
>> +		atomic_sub(_QW_LOCKED,&lock->cnts.rwa);
>>   }
> If we're a writer, read-count must be zero. The only way for that not to
> be zero is a concurrent read-(try)lock. If you move all the
> read-(try)locks over to cmpxchg() you can avoid this afaict:

That is not true. A reader may transiently set the reader count to a 
non-zero value in the fast path. Also, a reader in interrupt context 
will force a non-zero reader count to take the read lock as soon as the 
writer is done.

>
> static inline void queue_read_trylock(struct qrwlock *lock)
> {
> 	union qrwcnts cnts
>
> 	cnts = ACCESS_ONCE(lock->cnts);
> 	if (!cnts.writer) {
> 		if (cmpxchg(&lock->cnts.rwc, cnts.rwc, cnts.rwc + _QR_BIAS) == cnts.rwc)
> 			return 1;
> 	}
>
> 	return 0;
> }
>
> static inline void queue_read_lock(struct qrwlock *lock)
> {
> 	if (!queue_read_trylock(lock))
> 		queue_read_lock_slowpath(); // XXX do not assume extra _QR_BIAS
> }
>
> At which point you have the guarantee that read-count == 0, and you can
> write:
>
> static inline void queue_write_unlock(struct qrwlock *lock)
> {
> 	smp_store_release(&lock->cnts.rwc, 0);
> }
>
> No?
>

The current code is optimized for the reader-heavy case. So I used xadd 
for incrementing reader count to reduce the chance of retry due to 
concurrent reader count updates. The downside is the need to back out if 
a writer is here.

I can change the logic to use only cmpxchg for readers, but I don't see 
a compelling reason to do so.

-Longman

  reply	other threads:[~2014-01-21 15:45 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-15  4:44 [PATCH v9 0/5] qrwlock: Introducing a queue read/write lock implementation Waiman Long
2014-01-15  4:44 ` [PATCH v9 1/5] qrwlock: A " Waiman Long
2014-01-20 15:21   ` Peter Zijlstra
2014-01-21 15:58     ` Waiman Long
2014-01-21 15:58       ` Waiman Long
2014-01-15  4:44 ` [PATCH v9 2/5] qrwlock x86: Enable x86 to use queue read/write lock Waiman Long
2014-01-20 16:08   ` Peter Zijlstra
2014-01-20 16:16     ` Steven Rostedt
2014-01-21 16:00       ` Waiman Long
2014-01-21 16:00         ` Waiman Long
2014-01-15  4:44 ` [PATCH v9 3/5] qrwlock, x86 - Treat all data type not bigger than long as atomic in x86 Waiman Long
2014-01-20 15:03   ` Peter Zijlstra
2014-01-21 15:36     ` Waiman Long
2014-01-21 15:36       ` Waiman Long
2014-01-21 15:39       ` Peter Zijlstra
2014-01-21 16:09         ` Waiman Long
2014-01-22  0:31           ` Linus Torvalds
2014-01-22  4:42             ` Waiman Long
2014-01-22  8:01             ` Peter Zijlstra
2014-01-22 12:09               ` Ingo Molnar
2014-01-22 12:13                 ` Peter Zijlstra
2014-01-22 13:09                   ` Ingo Molnar
2014-01-27 17:09                     ` Paul E. McKenney
2014-01-15  4:44 ` [PATCH v9 4/5] qrwlock: Use smp_store_release() in write_unlock() Waiman Long
2014-01-20  3:39   ` Paul E. McKenney
2014-01-20 15:18   ` Peter Zijlstra
2014-01-21 15:45     ` Waiman Long [this message]
2014-01-21 15:45       ` Waiman Long
2014-01-21 15:49       ` Peter Zijlstra
2014-01-15  4:44 ` [PATCH v9 5/5] qrwlock: Use the mcs_spinlock helper functions for MCS queuing Waiman Long

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52DE9626.3030806@hp.com \
    --to=waiman.long@hp.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=arnd@arndb.de \
    --cc=aswin@hp.com \
    --cc=hpa@zytor.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@horizon.com \
    --cc=mingo@redhat.com \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=peterz@infradead.org \
    --cc=raghavendra.kt@linux.vnet.ibm.com \
    --cc=riel@redhat.com \
    --cc=rostedt@goodmis.org \
    --cc=scott.norton@hp.com \
    --cc=tglx@linutronix.de \
    --cc=tim.c.chen@linux.intel.com \
    --cc=torvalds@linux-foundation.org \
    --cc=walken@google.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.