mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Nicolas Pitre <nico@cam.org>
To: Linus Torvalds <torvalds@osdl.org>
Cc: David Howells <dhowells@redhat.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	linux-arch@vger.kernel.org, lkml <linux-kernel@vger.kernel.org>,
	mingo@redhat.com, Andrew Morton <akpm@osdl.org>
Subject: Re: [PATCH 1/12]: MUTEX: Implement mutexes
Date: Sat, 17 Dec 2005 23:07:49 -0500 (EST)	[thread overview]
Message-ID: <Pine.LNX.4.64.0512172150260.26663@localhost.localdomain> (raw)
In-Reply-To: <Pine.LNX.4.64.0512171803580.3698@g5.osdl.org>

On Sat, 17 Dec 2005, Linus Torvalds wrote:

> On Sat, 17 Dec 2005, Nicolas Pitre wrote:
> > 
> > Well, if you really want to be honest, you have to consider that the 
> > ldrex/strex instructions are available only on ARM architecture level 6 
> > and above, or in other words with only about 1% of all ARM deployments 
> > out there.  The other 99% of actual ARM processors in the field only 
> > have the atomic swap (swp) instruction which is insufficient for 
> > implementing a counting semaphore (we therefore have to disable 
> > interrupts, do the semaphore update and enable interrupts again which is 
> > much slower than a swp-based mutex).
> 
> Ehh.. Have you seen any SMP arm machines with the old ones?

No.  I never saw any SMP on ARM yet.  About only RMK did.

> As far as I can tell from the Linux arm assembly (which I admittedly don't 
> read very well at all), the non-ARMv6 semaphore code just disables 
> interrupts and does the semaphore without any atomic instructions at all. 

Exact, and that's because on pre-ARMv6 you have UP only, and the only 
atomic instruction on pre-ARMv6 is the swp instruction which doesn't cut 
it for semaphores.

> Which is fine for UP (in fact, I'm not even convinced you need to disable 
> interrupts, since any interrupts - even if they do a "trylock+up" - should 
> always leave the counter in the same state it was before).

I don't think I follow you here.  The down() implementation goes like 
this:

	1) disable interrupts
	2) load semaphore count into register
	3) decrement register value (remember if it goes negative)
	4) store register value to semaphore count location
	5) enable interrupts
	6) if the count went negative go to sleep

The up() goes like this:

	1) disable interrupts
	2) load semaphore count into register
	3) increment register value (remember if it remains < 1)
	4) store register value to semaphore count location
	5) enable interrupts
	6) if the sem count is still < 1 then wake up someone

Now if you don't disable interrupts then nothing prevents an interrupt 
handler, or another thread if kernel preemption is allowed, to come 
along right between (2) and (4) to call up() or down() which will 
make the sem count inconsistent as soon as the interrupted down() or 
up() is resumed.

> So afaik, Linux simply doesn't support pre-ARMv6 in SMP configurations, 
> and never has (and I'd assume never will).

Indeed.

> Or am I missing something?

I understand this thread is about simple mutex (locked/unlocked) vs full 
counting semaphores.  And I'm presuming that we still care about best 
performances with pre-ARMv6 support, maybe even more than ARMv6 and 
above given the current deployment figures using Linux.

In that case, a simple mutex_lock implementation on pre-ARMv6 would look 
like this:

__lock:
	mov	r1, #1			@ 1 = lock flag
	swp	r2, r1, [r0]		@ lock the mutex, get current state
	cmp	r2, #0			@ was it unlocked?
	beq	__continue		@ if so we're done
	mov	r1, #2			@ 2 = contended lock
	swp	r2, r1, [r0]		@ upgrade the lock to contended
	cmp	r2, #0			@ was it unlocked in the mean time?
	beq	__continue		@ if so we just acquired the lock
	bl	__sleep			@ go to sleep
	b	__lock
__continue:

Here you can even have the 4 first instructions inline for the fast 
uncontended case and the rest out of line, making it much smaller than 
the counting semaphore implementation with the same inline property.

And for completeness, here's the mutex_unlock:

__unlock:
	mov	r1, #0			@ 0 = unlocked
	swp	r2, r1, [r0]		@ unlock mutex, get current state
	cmp	r2, #2			@ was it contended?
	bleq	__wake			@ if so call wake_up

And the mutex_trylock is trivial as well.

That's it.  4 inline instructions for locking, 4 inline instructions for 
unlocking, no disabling/enabling of interrupts needed any more.


Nicolas

  reply	other threads:[~2005-12-18  4:07 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-12-16 23:13 [PATCH 0/12]: MUTEX: Introduce mutex implementation David Howells
2005-12-16 23:13 ` [PATCH 1/12]: MUTEX: Implement mutexes David Howells
2005-12-17  3:58   ` Steven Rostedt
2005-12-17  7:35     ` Linus Torvalds
2005-12-17  7:55     ` Nick Piggin
2005-12-17 12:36       ` Steven Rostedt
2005-12-17 19:21     ` David Howells
2005-12-17 20:11       ` Linus Torvalds
2005-12-17 21:44         ` Russell King
2005-12-18  1:29         ` Nicolas Pitre
2005-12-18  2:34           ` Linus Torvalds
2005-12-18  4:07             ` Nicolas Pitre [this message]
2005-12-18  4:18               ` Steven Rostedt
2005-12-18  6:30               ` Linus Torvalds
2005-12-18  9:26                 ` Russell King
2005-12-18 18:42                   ` Linus Torvalds
2005-12-18 19:41                     ` James Bottomley
2005-12-18 19:54                       ` Linus Torvalds
2005-12-19  1:48                     ` Nicolas Pitre
2005-12-19  9:27                       ` Russell King
2005-12-19 13:54                         ` Matthew Wilcox
2005-12-19 15:49                           ` Nicolas Pitre
2005-12-19 15:45                         ` Nicolas Pitre
2005-12-18 17:29                 ` Nicolas Pitre
2005-12-18 13:38           ` Alan Cox
2005-12-18 17:21             ` Nicolas Pitre
2005-12-16 23:13 ` [PATCH 3/12]: MUTEX: Rename DECLARE_MUTEX for arch/ dir David Howells
2005-12-16 23:13 ` [PATCH 2/12]: MUTEX: Provide SWAP-based mutex for FRV David Howells
2005-12-16 23:13 ` [PATCH 6/12]: MUTEX: Rename DECLARE_MUTEX for fs/ dir David Howells
2005-12-16 23:13 ` [PATCH 8/12]: MUTEX: Rename DECLARE_MUTEX for kernel/ dir David Howells
2005-12-16 23:13 ` [PATCH 4/12]: MUTEX: Rename DECLARE_MUTEX for drivers/ dir, A thru M David Howells
2005-12-16 23:13 ` [PATCH 5/12]: MUTEX: Rename DECLARE_MUTEX for drivers/ dir, N thru Z David Howells
2005-12-16 23:13 ` [PATCH 11/12]: MUTEX: Rename DECLARE_MUTEX for miscellaneous directories David Howells
2005-12-16 23:13 ` [PATCH 7/12]: MUTEX: Rename DECLARE_MUTEX for include/asm-*/ dirs David Howells
2005-12-16 23:13 ` [PATCH 10/12]: MUTEX: Rename DECLARE_MUTEX for sound/ dir David Howells
2005-12-16 23:13 ` [PATCH 9/12]: MUTEX: Rename DECLARE_MUTEX for net/ dir David Howells
2005-12-16 23:13 ` [PATCH 12/12]: MUTEX: Provide synchronisation primitive testing module David Howells

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=Pine.LNX.4.64.0512172150260.26663@localhost.localdomain \
    --to=nico@cam.org \
    --cc=akpm@osdl.org \
    --cc=dhowells@redhat.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=rostedt@goodmis.org \
    --cc=torvalds@osdl.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®