From: jamie@shareable.org (Jamie Lokier)
To: linux-arm-kernel@lists.infradead.org
Subject: LDREX/STREX and pre-emption on SMP hardware
Date: Mon, 14 Sep 2009 02:43:53 +0100 [thread overview]
Message-ID: <20090914014353.GA4762@shareable.org> (raw)
In-Reply-To: <1251135709.28977.40.camel@pc1117.cambridge.arm.com>
Catalin Marinas wrote:
> With interrupts (I1, I2 interrupt handlers)
>
> I1 I2
> LDREX
> LDREX
> STREX (succeeds)
> STREX (fails)
>
> In the interrupt case, they are nested so the STREX in I2 is always
> executed before STREX in I1 (you can extrapolate with several nested
> interrupts).
This assumes LDREX/STREX are always called in pairs. But this is in
fact _not_ the case. Take a look at atomic_cmpxchg:
do {
__asm__ __volatile__("@ atomic_cmpxchg\n"
"ldrex %1, [%2]\n"
"mov %0, #0\n"
"teq %1, %3\n"
"strexeq %0, %4, [%2]\n"
: "=&r" (res), "=&r" (oldval)
: "r" (&ptr->counter), "Ir" (old), "r" (new)
: "cc");
} while (res);
In the case where ptr->counter != old, STREX is not executed, and the
do{...}while loop does not loop. Thus LDREX/STREX aren't paired.
It may be that atomic_cmpxchg() is always called in a loop, but if so
I don't think that's a documented requirement for all callers.
A simple solution is to either call CLREXNE after STREXEQ, or change
STREXEQ to STREX and change the logic so that if ptr->counter != old,
the value it tries to store is what it read. The latter uses fewer
instructions - and even eliminates the do...while, making it really
compact, but may cause more cache line dirtying.
If you think I'm right and tell me what you prefer I'll prepare a
patch.
-- Jamie
next prev parent reply other threads:[~2009-09-14 1:43 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-21 15:07 LDREX/STREX and pre-emption on SMP hardware Richard Crewe
2009-08-21 15:42 ` Catalin Marinas
2009-08-21 15:50 ` Jamie Lokier
2009-08-21 15:58 ` Catalin Marinas
2009-08-21 21:29 ` David Xiao
2009-08-24 15:44 ` Catalin Marinas
2009-08-24 17:14 ` David Xiao
2009-08-24 17:41 ` Catalin Marinas
2009-08-24 18:59 ` David Xiao
2009-09-14 1:43 ` Jamie Lokier [this message]
2009-09-14 8:53 ` Catalin Marinas
2009-09-14 10:00 ` Russell King - ARM Linux
2009-09-14 10:06 ` Catalin Marinas
2009-09-14 11:47 ` Catalin Marinas
2009-09-14 12:21 ` Catalin Marinas
2009-09-14 12:43 ` Bill Gatliff
2009-09-14 12:57 ` Catalin Marinas
2009-09-14 19:30 ` Bill Gatliff
2009-09-14 14:09 ` Russell King - ARM Linux
2009-09-14 14:21 ` Russell King - ARM Linux
2009-09-14 14:26 ` Catalin Marinas
2009-09-14 15:35 ` Catalin Marinas
2009-09-14 23:16 ` Jamie Lokier
2009-09-14 14:23 ` Russell King - ARM Linux
2009-09-14 14:29 ` Catalin Marinas
2009-09-18 20:20 ` Russell King - ARM Linux
2009-09-18 22:51 ` Catalin Marinas
2009-08-24 21:12 ` Jamie Lokier
2009-08-25 8:33 ` Catalin Marinas
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=20090914014353.GA4762@shareable.org \
--to=jamie@shareable.org \
--cc=linux-arm-kernel@lists.infradead.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.