* Re: using long instead of atomic_t when only set/read is required (was Re: [Bug 10030] Suspend doesn't work when SD card is inserted)
[not found] <20080225090316.GA420@elf.ucw.cz>
@ 2008-02-25 14:46 ` Alan Stern
[not found] ` <Pine.LNX.4.44L0.0802250943410.3549-100000@iolanthe.rowland.org>
1 sibling, 0 replies; 20+ messages in thread
From: Alan Stern @ 2008-02-25 14:46 UTC (permalink / raw)
To: Pavel Machek
Cc: Kernel development list, Zdenek Kabelac, pm list, davem,
Pierre Ossman
On Mon, 25 Feb 2008, Pavel Machek wrote:
> Hi!
>
> Alan thinks that `subj` is correct...
More precisely, reads and writes of pointers are always atomic. That
is, if a write and a read occur concurrently, it is guaranteed that the
read will obtain either the old or the new value of the pointer, never
a mish-mash of the two. If this were not so then RCU wouldn't work.
> I guess it only works as long as longs are aligned? Should it be
> written down to atomic_ops.txt?
Forget it, I'm going to withdraw the entire thing. The whole approach
is wrong. More details in a new email thread, to follow soon.
Alan Stern
^ permalink raw reply [flat|nested] 20+ messages in thread
* [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <Pine.LNX.4.44L0.0802250943410.3549-100000@iolanthe.rowland.org>
@ 2008-03-03 12:08 ` Pavel Machek
[not found] ` <20080303120842.GA28369@elf.ucw.cz>
1 sibling, 0 replies; 20+ messages in thread
From: Pavel Machek @ 2008-03-03 12:08 UTC (permalink / raw)
To: Alan Stern, Linus Torvalds, Andrew Morton
Cc: Kernel development list, Zdenek Kabelac, pm list, davem,
Pierre Ossman
Hi!
> > Alan thinks that `subj` is correct...
>
> More precisely, reads and writes of pointers are always atomic. That
> is, if a write and a read occur concurrently, it is guaranteed that the
> read will obtain either the old or the new value of the pointer, never
> a mish-mash of the two. If this were not so then RCU wouldn't work.
Ok, so linux actually atomicity of long?
If so, this should probably be applied...
Signed-off-by: Pavel Machek <pavel@suse.cz>
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
index 4ef2450..0a7d180 100644
--- a/Documentation/atomic_ops.txt
+++ b/Documentation/atomic_ops.txt
@@ -21,6 +21,9 @@ local_t is very similar to atomic_t. If
updated by one CPU, local_t is probably more appropriate. Please see
Documentation/local_ops.txt for the semantics of local_t.
+long (and int and void *) can be used instead of atomic_t, if all you
+need is atomic setting and atomic reading.
+
The first operations to implement for atomic_t's are the initializers and
plain reads.
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <20080303120842.GA28369@elf.ucw.cz>
@ 2008-03-03 15:42 ` Alan Stern
2008-03-03 15:48 ` Alan Cox
` (2 subsequent siblings)
3 siblings, 0 replies; 20+ messages in thread
From: Alan Stern @ 2008-03-03 15:42 UTC (permalink / raw)
To: Pavel Machek
Cc: Andrew Morton, Kernel development list, Zdenek Kabelac, pm list,
Paul E. McKenney, Linus Torvalds, davem, Pierre Ossman
On Mon, 3 Mar 2008, Pavel Machek wrote:
> Hi!
>
> > > Alan thinks that `subj` is correct...
> >
> > More precisely, reads and writes of pointers are always atomic. That
> > is, if a write and a read occur concurrently, it is guaranteed that the
> > read will obtain either the old or the new value of the pointer, never
> > a mish-mash of the two. If this were not so then RCU wouldn't work.
Right, Paul?
> Ok, so linux actually atomicity of long?
>
> If so, this should probably be applied...
>
> Signed-off-by: Pavel Machek <pavel@suse.cz>
>
> diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
> index 4ef2450..0a7d180 100644
> --- a/Documentation/atomic_ops.txt
> +++ b/Documentation/atomic_ops.txt
> @@ -21,6 +21,9 @@ local_t is very similar to atomic_t. If
> updated by one CPU, local_t is probably more appropriate. Please see
> Documentation/local_ops.txt for the semantics of local_t.
>
> +long (and int and void *) can be used instead of atomic_t, if all you
> +need is atomic setting and atomic reading.
> +
> The first operations to implement for atomic_t's are the initializers and
> plain reads.
Yes indeed. This fact doesn't seem to be documented anywhere, but it
is clearly a requirement of the kernel. I would make the text a little
more explicit, see below.
Alan Stern
-------------------------------------------------------
Atomicity of reads of write for pointers and integral types (other than
long long) should be documented.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
---
Index: usb-2.6/Documentation/atomic_ops.txt
===================================================================
--- usb-2.6.orig/Documentation/atomic_ops.txt
+++ usb-2.6/Documentation/atomic_ops.txt
@@ -21,6 +21,21 @@ local_t is very similar to atomic_t. If
updated by one CPU, local_t is probably more appropriate. Please see
Documentation/local_ops.txt for the semantics of local_t.
+For all properly-aligned pointer and integral types other than long
+long, the kernel requires simple reads and writes to be atomic with
+respect to each other. That is, if one CPU reads a pointer value at
+the same time as another CPU overwrites the pointer, it is guaranteed
+that the reader will obtain either the old or the new value of the
+pointer, never some mish-mash combination of the two. Likewise, if
+one CPU writes a long value at the same time as another CPU does, it
+is guaranteed that one or the other of the values will end up stored
+in memory, not some mish-mash combination of bits.
+
+Thus, if all you need is atomicity of reading and writing then you can
+use plain old ints, longs, or pointers; you don't need to use
+atomic_t. (But note: This guarantee emphatically does not apply to
+long long values or unaligned values!)
+
The first operations to implement for atomic_t's are the initializers and
plain reads.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <20080303120842.GA28369@elf.ucw.cz>
2008-03-03 15:42 ` Alan Stern
@ 2008-03-03 15:48 ` Alan Cox
[not found] ` <Pine.LNX.4.44L0.0803031023550.3611-100000@iolanthe.rowland.org>
[not found] ` <20080303154831.22a4eb14@core>
3 siblings, 0 replies; 20+ messages in thread
From: Alan Cox @ 2008-03-03 15:48 UTC (permalink / raw)
To: Pavel Machek
Cc: Andrew Morton, Kernel, Zdenek, development list, Kabelac, pm list,
Linus Torvalds, davem, Pierre Ossman
> Ok, so linux actually atomicity of long?
No it doesn't. And even if it did you couldn't use long for this because
atomic_t also ensures the points operations complete are defined. You
might just about get away with volatile long * objects on x86 for simple
assignments but for anything else gcc can and will generate code to
update values whichever way it feels best - which includes turning
long *x = a + b;
into
*x = a;
*x += b;
Alan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <Pine.LNX.4.44L0.0803031023550.3611-100000@iolanthe.rowland.org>
@ 2008-03-03 15:53 ` Alan Cox
[not found] ` <20080303155330.39e45ad4@core>
2008-03-03 17:22 ` Paul E. McKenney
2 siblings, 0 replies; 20+ messages in thread
From: Alan Cox @ 2008-03-03 15:53 UTC (permalink / raw)
To: Alan Stern
Cc: Andrew Morton, Kernel, Zdenek, development list, Kabelac, pm list,
Paul E. McKenney, Linus Torvalds, davem, Pierre Ossman
> Atomicity of reads of write for pointers and integral types (other than
> long long) should be documented.
NAK.
Atomicity of reads or writes for pointers and integral types is NOT
guaranteed. Gcc doesn't believe in your guarantee.
Alan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <20080303155330.39e45ad4@core>
@ 2008-03-03 17:11 ` Alan Stern
2008-03-03 17:16 ` Nick Piggin
1 sibling, 0 replies; 20+ messages in thread
From: Alan Stern @ 2008-03-03 17:11 UTC (permalink / raw)
To: Alan Cox
Cc: Andrew Morton, Kernel development list, Zdenek Kabelac, pm list,
Paul E. McKenney, Linus Torvalds, davem, Pierre Ossman
On Mon, 3 Mar 2008, Alan Cox wrote:
> > Atomicity of reads of write for pointers and integral types (other than
> > long long) should be documented.
>
> NAK.
>
> Atomicity of reads or writes for pointers and integral types is NOT
> guaranteed. Gcc doesn't believe in your guarantee.
Miscommunication and lack of clarity. CPU reads and writes _are_
guaranteed to be atomic. What is not guaranteed is that the compiler
will generate a single read or write instruction corresponding to a
particular expression in C.
Consider a routine like the following:
static task_struct *the_task;
void store_task(void)
{
the_task = current;
}
Is it possible to say whether readers examining "the_task" are
guaranteed to see a coherent value?
Alan Stern
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <20080303155330.39e45ad4@core>
2008-03-03 17:11 ` Alan Stern
@ 2008-03-03 17:16 ` Nick Piggin
2008-03-03 17:31 ` Paul E. McKenney
2008-03-03 17:33 ` Alan Cox
1 sibling, 2 replies; 20+ messages in thread
From: Nick Piggin @ 2008-03-03 17:16 UTC (permalink / raw)
To: Alan Cox
Cc: Andrew Morton, Kernel development list, Zdenek Kabelac, pm list,
Paul E. McKenney, Linus Torvalds, davem, Pierre Ossman
On Tuesday 04 March 2008 02:53, Alan Cox wrote:
> > Atomicity of reads of write for pointers and integral types (other than
> > long long) should be documented.
>
> NAK.
>
> Atomicity of reads or writes for pointers and integral types is NOT
> guaranteed. Gcc doesn't believe in your guarantee.
Are you sure gcc doesn't? Or is it just "C"?
Linux wouldn't work today if gcc did something non-atomic there
(presuming you're talking about naturally aligned pointers/ints).
It is widely used and accepted.
RCU users are far from the only places to rely on this, although
I guess they are the main ones when it comes to assigning pointers
atomically.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <Pine.LNX.4.44L0.0803031023550.3611-100000@iolanthe.rowland.org>
2008-03-03 15:53 ` Alan Cox
[not found] ` <20080303155330.39e45ad4@core>
@ 2008-03-03 17:22 ` Paul E. McKenney
2 siblings, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2008-03-03 17:22 UTC (permalink / raw)
To: Alan Stern
Cc: Andrew Morton, Kernel development list, Zdenek Kabelac, pm list,
Linus Torvalds, davem, Pierre Ossman
On Mon, Mar 03, 2008 at 10:42:35AM -0500, Alan Stern wrote:
> On Mon, 3 Mar 2008, Pavel Machek wrote:
>
> > Hi!
> >
> > > > Alan thinks that `subj` is correct...
> > >
> > > More precisely, reads and writes of pointers are always atomic. That
> > > is, if a write and a read occur concurrently, it is guaranteed that the
> > > read will obtain either the old or the new value of the pointer, never
> > > a mish-mash of the two. If this were not so then RCU wouldn't work.
>
> Right, Paul?
Yep, as long as they aligned naturally, e.g., 32-bit pointers to a
four-byte boundary, 64-bit pointers to an eight-byte boundary.
Note that this is a backdoor agreement between the Linux kernel and gcc.
The C/C++ standard does -not- require atomic reads or writes for anything
other than a volatile sig_atomic_t. In fact, there are a lot of things
that C/C++ doesn't guarantee, which is why Linux makes use of so many
of gcc's non-standard extensions. ;-)
> > Ok, so linux actually atomicity of long?
Yep, same alignment rules as pointers. Ah, and the alignment is
covered below. Very good!
> > If so, this should probably be applied...
> >
> > Signed-off-by: Pavel Machek <pavel@suse.cz>
> >
> > diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
> > index 4ef2450..0a7d180 100644
> > --- a/Documentation/atomic_ops.txt
> > +++ b/Documentation/atomic_ops.txt
> > @@ -21,6 +21,9 @@ local_t is very similar to atomic_t. If
> > updated by one CPU, local_t is probably more appropriate. Please see
> > Documentation/local_ops.txt for the semantics of local_t.
> >
> > +long (and int and void *) can be used instead of atomic_t, if all you
> > +need is atomic setting and atomic reading.
> > +
> > The first operations to implement for atomic_t's are the initializers and
> > plain reads.
>
> Yes indeed. This fact doesn't seem to be documented anywhere, but it
> is clearly a requirement of the kernel. I would make the text a little
> more explicit, see below.
>
> Alan Stern
>
> -------------------------------------------------------
>
>
> Atomicity of reads of write for pointers and integral types (other than
> long long) should be documented.
>
> Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
>
> ---
>
> Index: usb-2.6/Documentation/atomic_ops.txt
> ===================================================================
> --- usb-2.6.orig/Documentation/atomic_ops.txt
> +++ usb-2.6/Documentation/atomic_ops.txt
> @@ -21,6 +21,21 @@ local_t is very similar to atomic_t. If
> updated by one CPU, local_t is probably more appropriate. Please see
> Documentation/local_ops.txt for the semantics of local_t.
>
> +For all properly-aligned pointer and integral types other than long
> +long, the kernel requires simple reads and writes to be atomic with
> +respect to each other. That is, if one CPU reads a pointer value at
> +the same time as another CPU overwrites the pointer, it is guaranteed
> +that the reader will obtain either the old or the new value of the
> +pointer, never some mish-mash combination of the two. Likewise, if
> +one CPU writes a long value at the same time as another CPU does, it
> +is guaranteed that one or the other of the values will end up stored
> +in memory, not some mish-mash combination of bits.
> +
> +Thus, if all you need is atomicity of reading and writing then you can
> +use plain old ints, longs, or pointers; you don't need to use
> +atomic_t. (But note: This guarantee emphatically does not apply to
> +long long values or unaligned values!)
> +
> The first operations to implement for atomic_t's are the initializers and
> plain reads.
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <20080303154831.22a4eb14@core>
@ 2008-03-03 17:24 ` Pavel Machek
2008-03-03 20:27 ` Rafael J. Wysocki
[not found] ` <200803032127.30761.rjw@sisk.pl>
0 siblings, 2 replies; 20+ messages in thread
From: Pavel Machek @ 2008-03-03 17:24 UTC (permalink / raw)
To: Alan Cox
Cc: Andrew Morton, Kernel development list, Zdenek Kabelac, pm list,
Linus Torvalds, davem, Pierre Ossman
Hi!
> > Ok, so linux actually atomicity of long?
^~-- assumes should be here.
> No it doesn't. And even if it did you couldn't use long for this because
> atomic_t also ensures the points operations complete are defined. You
> might just about get away with volatile long * objects on x86 for simple
> assignments but for anything else gcc can and will generate code to
> update values whichever way it feels best - which includes turning
>
> long *x = a + b;
>
> into
>
> *x = a;
> *x += b;
Ok, I can understand the gcc side. But do we actually run on an
architecture where
long *x;
*x = 0;
racing with
*x = 0x12345678;
can produce
*x == 0x12340000;
or something like that? I'm told RCU relies on architectures not doing
this, and I'd like to get this clarified.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] <Pine.LNX.4.44L0.0803031207120.3611-100000@iolanthe.rowland.org>
@ 2008-03-03 17:26 ` Linus Torvalds
2008-03-03 17:44 ` Pavel Machek
` (2 more replies)
0 siblings, 3 replies; 20+ messages in thread
From: Linus Torvalds @ 2008-03-03 17:26 UTC (permalink / raw)
To: Alan Stern
Cc: Kernel development list, Zdenek Kabelac, pm list, Andrew Morton,
Paul E. McKenney, davem, Alan Cox, Pierre Ossman
On Mon, 3 Mar 2008, Alan Stern wrote:
>
> Consider a routine like the following:
>
> static task_struct *the_task;
>
> void store_task(void)
> {
> the_task = current;
> }
>
> Is it possible to say whether readers examining "the_task" are
> guaranteed to see a coherent value?
Yes, we do depend on this. All the RCU stuff (and in general *anything*
that depends on memory ordering as opposed to full locking, and we have
quite a lot of it) is very fundamentally dependent on the fact that things
like pointers get read and written atomically.
HOWEVER, it is worth pointing out that it's generally true in a
"different" sense than the actual atomic accesses. For example, if you
test a single bit of a word, it's still quite possible that gcc will have
turned that "atomic" read into a single byte read, so it's not necessarily
the case that we'll actually even read the whole word.
(Writes are different: if you do things like bitwise updates they simply
*will*not* be atomic, but that's simply not what we depend on anyway).
So in that sense, the atomicity guarantees are a lot weaker than the ones
we do for IO accesses, but that's all fine. Memory isn't IO, and doesn't
have side effects.
Linus
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
2008-03-03 17:16 ` Nick Piggin
@ 2008-03-03 17:31 ` Paul E. McKenney
2008-03-03 17:33 ` Alan Cox
1 sibling, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2008-03-03 17:31 UTC (permalink / raw)
To: Nick Piggin
Cc: Andrew Morton, Kernel development list, Zdenek Kabelac, pm list,
Linus Torvalds, davem, Alan Cox, Pierre Ossman
On Tue, Mar 04, 2008 at 04:16:33AM +1100, Nick Piggin wrote:
> On Tuesday 04 March 2008 02:53, Alan Cox wrote:
> > > Atomicity of reads of write for pointers and integral types (other than
> > > long long) should be documented.
> >
> > NAK.
> >
> > Atomicity of reads or writes for pointers and integral types is NOT
> > guaranteed. Gcc doesn't believe in your guarantee.
>
> Are you sure gcc doesn't? Or is it just "C"?
>
> Linux wouldn't work today if gcc did something non-atomic there
> (presuming you're talking about naturally aligned pointers/ints).
> It is widely used and accepted.
>
> RCU users are far from the only places to rely on this, although
> I guess they are the main ones when it comes to assigning pointers
> atomically.
It is true that gcc can refetch pointers/ints if it runs out of registers,
which is why rcu_dereference() recently had an ACCESS_ONCE() added to it.
But such refetching cannot result in a mish-mash of two different
pointer values, confusing though it might be to the affected code.
Thanx, Paul
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
2008-03-03 17:16 ` Nick Piggin
2008-03-03 17:31 ` Paul E. McKenney
@ 2008-03-03 17:33 ` Alan Cox
1 sibling, 0 replies; 20+ messages in thread
From: Alan Cox @ 2008-03-03 17:33 UTC (permalink / raw)
To: Nick Piggin
Cc: Andrew Morton, Kernel, Zdenek, development list, Kabelac, pm list,
Paul E. McKenney, Linus Torvalds, davem, Pierre Ossman
> Are you sure gcc doesn't? Or is it just "C"?
gcc doesn't
> Linux wouldn't work today if gcc did something non-atomic there
> (presuming you're talking about naturally aligned pointers/ints).
> It is widely used and accepted.
Yes and we've had tty layer traces in the past clearly showing it isn't
always safe, especially if any math is involved anywhere near the
assignment. That may be why pointer flipping happens to work.
Alan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
2008-03-03 17:26 ` Linus Torvalds
@ 2008-03-03 17:44 ` Pavel Machek
2008-03-06 15:58 ` Mark Lord
[not found] ` <47D014A6.9090300@rtr.ca>
2 siblings, 0 replies; 20+ messages in thread
From: Pavel Machek @ 2008-03-03 17:44 UTC (permalink / raw)
To: Linus Torvalds
Cc: Kernel development list, Zdenek Kabelac, pm list, Andrew Morton,
Paul E. McKenney, davem, Alan Cox, Pierre Ossman
Hi!
> > Consider a routine like the following:
> >
> > static task_struct *the_task;
> >
> > void store_task(void)
> > {
> > the_task = current;
> > }
> >
> > Is it possible to say whether readers examining "the_task" are
> > guaranteed to see a coherent value?
>
> Yes, we do depend on this. All the RCU stuff (and in general *anything*
> that depends on memory ordering as opposed to full locking, and we have
> quite a lot of it) is very fundamentally dependent on the fact that things
> like pointers get read and written atomically.
>
> HOWEVER, it is worth pointing out that it's generally true in a
> "different" sense than the actual atomic accesses. For example, if you
> test a single bit of a word, it's still quite possible that gcc will have
> turned that "atomic" read into a single byte read, so it's not necessarily
> the case that we'll actually even read the whole word.
>
> (Writes are different: if you do things like bitwise updates they simply
> *will*not* be atomic, but that's simply not what we depend on anyway).
Ok... can we get Alan Stern's patch into Documentation/atomic_ops.txt
, then? I was not aware of this, and there seems to be lot of
confusion around...
Plus... I really don't think we can "just access" this as normal
pointers... due to the compiler issues Alan Cox mentioned, and due to
the ACCESS_ONCE() issue.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] <20080303174422.GB13869@elf.ucw.cz>
@ 2008-03-03 19:27 ` Alan Stern
0 siblings, 0 replies; 20+ messages in thread
From: Alan Stern @ 2008-03-03 19:27 UTC (permalink / raw)
To: Pavel Machek
Cc: Kernel development list, Zdenek Kabelac, pm list, Andrew Morton,
Paul E. McKenney, Linus Torvalds, davem, Alan Cox, Pierre Ossman
On Mon, 3 Mar 2008, Pavel Machek wrote:
> Ok... can we get Alan Stern's patch into Documentation/atomic_ops.txt
> , then? I was not aware of this, and there seems to be lot of
> confusion around...
>
> Plus... I really don't think we can "just access" this as normal
> pointers... due to the compiler issues Alan Cox mentioned, and due to
> the ACCESS_ONCE() issue.
Here's an updated version of the patch, including the issue Alan Cox
brought up.
Alan Stern
-----------------------------------------------------------------
Atomicity of reads of write for pointers and integral types (other than
long long) should be documented, along with the limitations imposed by
the compiler.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
---
Index: usb-2.6/Documentation/atomic_ops.txt
===================================================================
--- usb-2.6.orig/Documentation/atomic_ops.txt
+++ usb-2.6/Documentation/atomic_ops.txt
@@ -21,6 +21,24 @@ local_t is very similar to atomic_t. If
updated by one CPU, local_t is probably more appropriate. Please see
Documentation/local_ops.txt for the semantics of local_t.
+For all properly-aligned pointer and integral types other than long
+long, the kernel requires simple reads and writes to be atomic with
+respect to each other. That is, if one CPU reads a pointer value at
+the same time as another CPU overwrites the pointer, it is guaranteed
+that the reader will obtain either the old or the new value of the
+pointer, never some mish-mash combination of the two. Likewise, if
+one CPU writes a long value at the same time as another CPU does, it
+is guaranteed that one or the other of the values will end up stored
+in memory, not some mish-mash combination of bits.
+
+Thus, if all you need is atomicity of reading and writing then you can
+use plain old ints, longs, or pointers; you don't need to use
+atomic_t. But note: This guarantee emphatically does not apply to
+long long values or unaligned values! Note also that gcc does not
+guarantee to compile all C assignment expressions into simple writes.
+For example, a statement like "x = a + b" might cause gcc to emit code
+equivalent to "x = a; x += b", which is decidedly non-atomic.
+
The first operations to implement for atomic_t's are the initializers and
plain reads.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
2008-03-03 17:24 ` Pavel Machek
@ 2008-03-03 20:27 ` Rafael J. Wysocki
[not found] ` <200803032127.30761.rjw@sisk.pl>
1 sibling, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2008-03-03 20:27 UTC (permalink / raw)
To: Pavel Machek
Cc: Andrew Morton, Kernel development list, Zdenek Kabelac, pm list,
Paul E. McKenney, Linus Torvalds, davem, Alan Cox, Pierre Ossman
On Monday, 3 of March 2008, Pavel Machek wrote:
> Hi!
>
> > > Ok, so linux actually atomicity of long?
> ^~-- assumes should be here.
>
> > No it doesn't. And even if it did you couldn't use long for this because
> > atomic_t also ensures the points operations complete are defined. You
> > might just about get away with volatile long * objects on x86 for simple
> > assignments but for anything else gcc can and will generate code to
> > update values whichever way it feels best - which includes turning
> >
> > long *x = a + b;
> >
> > into
> >
> > *x = a;
> > *x += b;
>
> Ok, I can understand the gcc side. But do we actually run on an
> architecture where
>
> long *x;
>
> *x = 0;
>
> racing with
>
> *x = 0x12345678;
>
> can produce
>
> *x == 0x12340000;
>
> or something like that?
Well something like this could happen, in theory, on a "32-bit" architecture
with a 16-bit bus. In that case, one can imagine, the first word of the
first write may be sent through the bus immediately followed by the first
word of the second write, followed by the second word of the second
write and by the second word of the first write, in this order.
> I'm told RCU relies on architectures not doing this, and I'd like to get this
> clarified.
Yes, it would be good to know that for sure.
Rafael
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <200803032127.30761.rjw@sisk.pl>
@ 2008-03-03 21:12 ` Paul E. McKenney
2008-03-03 22:23 ` Linus Torvalds
1 sibling, 0 replies; 20+ messages in thread
From: Paul E. McKenney @ 2008-03-03 21:12 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Andrew Morton, Kernel development list, Zdenek Kabelac, pm list,
Linus Torvalds, davem, Alan Cox, Pierre Ossman
On Mon, Mar 03, 2008 at 09:27:29PM +0100, Rafael J. Wysocki wrote:
> On Monday, 3 of March 2008, Pavel Machek wrote:
> > Hi!
> >
> > > > Ok, so linux actually atomicity of long?
> > ^~-- assumes should be here.
> >
> > > No it doesn't. And even if it did you couldn't use long for this because
> > > atomic_t also ensures the points operations complete are defined. You
> > > might just about get away with volatile long * objects on x86 for simple
> > > assignments but for anything else gcc can and will generate code to
> > > update values whichever way it feels best - which includes turning
> > >
> > > long *x = a + b;
> > >
> > > into
> > >
> > > *x = a;
> > > *x += b;
> >
> > Ok, I can understand the gcc side. But do we actually run on an
> > architecture where
> >
> > long *x;
> >
> > *x = 0;
> >
> > racing with
> >
> > *x = 0x12345678;
> >
> > can produce
> >
> > *x == 0x12340000;
> >
> > or something like that?
>
> Well something like this could happen, in theory, on a "32-bit" architecture
> with a 16-bit bus. In that case, one can imagine, the first word of the
> first write may be sent through the bus immediately followed by the first
> word of the second write, followed by the second word of the second
> write and by the second word of the first write, in this order.
>
> > I'm told RCU relies on architectures not doing this, and I'd like to get this
> > clarified.
>
> Yes, it would be good to know that for sure.
Most rcu_assign_pointer() calls are protected by locks, but there might
be a few that are not. However, the case that concerns me most would be
the following:
o Task 0 writes the lower 16 bits of the pointer.
o Task 1 reads the lower 16 bits of the pointer.
o Task 1 reads the upper 16 bits of the pointer.
o Task 0 writes the upper 16 bits of the pointer.
This would result in task 1 getting a mish-mash of the old and new
versions of the pointer. Very bad!!! RCU heavily relies on the reader
seeing either the initial value of the pointer or on the value written
by some single write.
But doesn't this require a -multi-CPU- system with a 16-bit data path
from the ALU to the L0 cache? This seems a bit unlikely. Or am I being
naive about embedded CPUs?
On the other hand, if you have a 32-bit single-CPU system with a 16-bit
path to memory, all we need is that interrupts be restricted to happening
at instruction boundaries rather than in the middle of instructions.
Thanx, Paul
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <200803032127.30761.rjw@sisk.pl>
2008-03-03 21:12 ` Paul E. McKenney
@ 2008-03-03 22:23 ` Linus Torvalds
1 sibling, 0 replies; 20+ messages in thread
From: Linus Torvalds @ 2008-03-03 22:23 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Kernel development list, Zdenek Kabelac, pm list, Andrew Morton,
Paul E. McKenney, davem, Alan Cox, Pierre Ossman
On Mon, 3 Mar 2008, Rafael J. Wysocki wrote:
>
> Well something like this could happen, in theory, on a "32-bit" architecture
> with a 16-bit bus.
No it couldn't.
That would only be true if there is no cache, and no cache coherency.
Basically, Linux requires a cache-coherent architecture to work in SMP.
Anything else is insane (except as a cluster).
So there is no way we can see partial updates, except with terminally
broken hardware that we would never support anyway for tons of other
reasons.
Linus
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
2008-03-03 17:26 ` Linus Torvalds
2008-03-03 17:44 ` Pavel Machek
@ 2008-03-06 15:58 ` Mark Lord
[not found] ` <47D014A6.9090300@rtr.ca>
2 siblings, 0 replies; 20+ messages in thread
From: Mark Lord @ 2008-03-06 15:58 UTC (permalink / raw)
To: Linus Torvalds
Cc: Kernel development list, Zdenek Kabelac, pm list, Andrew Morton,
Paul E. McKenney, davem, Alan Cox, Pierre Ossman
Linus Torvalds wrote:
>
> On Mon, 3 Mar 2008, Alan Stern wrote:
>> Consider a routine like the following:
>>
>> static task_struct *the_task;
>>
>> void store_task(void)
>> {
>> the_task = current;
>> }
>>
>> Is it possible to say whether readers examining "the_task" are
>> guaranteed to see a coherent value?
>
> Yes, we do depend on this. All the RCU stuff (and in general *anything*
> that depends on memory ordering as opposed to full locking, and we have
> quite a lot of it) is very fundamentally dependent on the fact that things
> like pointers get read and written atomically.
..
But also consider something like this:
void store_task(void)
{
*the_task = current;
}
In this case, there is no guarantee that the assignment
can be done atomically on all CPU types. Some RISC archs
(eg. MIPS R2xxx) require an (interruptible) instruction pair
to store values to a potentially unaligned address.
This was a BIG issue on a different system that I once worked on.
Cheers
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <47D014A6.9090300@rtr.ca>
@ 2008-03-06 16:11 ` Linus Torvalds
[not found] ` <alpine.LFD.1.00.0803060807120.12253@woody.linux-foundation.org>
1 sibling, 0 replies; 20+ messages in thread
From: Linus Torvalds @ 2008-03-06 16:11 UTC (permalink / raw)
To: Mark Lord
Cc: Kernel development list, Zdenek Kabelac, pm list, Andrew Morton,
Paul E. McKenney, davem, Alan Cox, Pierre Ossman
On Thu, 6 Mar 2008, Mark Lord wrote:
>
> But also consider something like this:
>
> void store_task(void)
> {
> *the_task = current;
> }
>
> In this case, there is no guarantee that the assignment
> can be done atomically on all CPU types. Some RISC archs
> (eg. MIPS R2xxx) require an (interruptible) instruction pair
> to store values to a potentially unaligned address.
You'd better not be using unaligned accesses for memory-ordering-sensitive
things (I think x86 happens get even that right for most cases, but I
don't think the architecture specification guarantees it, and I'm pretty
sure that you might find problems on cache crossing writes, for example)
But quite frankly, if you have an architecture that can't do the above as
a single write when it's a pointer, then you have a totally broken
architecture. It's not worth supporting.
(There are data structures that are harder than native words: bytes and
shorts can require load-modify-write cycles, and "u64" and friends can
obviously be multiple words, so you shouldn't depend on things for those
"complex" cases. But we *definitely* depend on atomicity for regular word
accesses).
Linus
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required
[not found] ` <alpine.LFD.1.00.0803060807120.12253@woody.linux-foundation.org>
@ 2008-03-06 16:27 ` Mark Lord
0 siblings, 0 replies; 20+ messages in thread
From: Mark Lord @ 2008-03-06 16:27 UTC (permalink / raw)
To: Linus Torvalds
Cc: Kernel development list, Zdenek Kabelac, pm list, Andrew Morton,
Paul E. McKenney, davem, Alan Cox, Pierre Ossman
Linus Torvalds wrote:
>
> On Thu, 6 Mar 2008, Mark Lord wrote:
>> But also consider something like this:
>>
>> void store_task(void)
>> {
>> *the_task = current;
>> }
>>
>> In this case, there is no guarantee that the assignment
>> can be done atomically on all CPU types. Some RISC archs
>> (eg. MIPS R2xxx) require an (interruptible) instruction pair
>> to store values to a potentially unaligned address.
>
> You'd better not be using unaligned accesses for memory-ordering-sensitive
> things (I think x86 happens get even that right for most cases, but I
> don't think the architecture specification guarantees it, and I'm pretty
> sure that you might find problems on cache crossing writes, for example)
..
Yeah. For the MIPS R2xxx CPU, the question was whether the compiler
could guarantee the alignment of the things the pointer could point at.
In cases where it could not, it would emit the interruptable instruction
pair instead of a single load instruction.
I don't know what gcc does on MIPS for this. Perhaps it simply always
assumes an aligned access? In that case, there's no issue unless some
putz actually creates/uses a pointer to an unaligned data object.
What about other architectures like ARM ? Probably also assumes aligned,
in which case all is well.
> But quite frankly, if you have an architecture that can't do the above as
> a single write when it's a pointer, then you have a totally broken
> architecture. It's not worth supporting.
>
> (There are data structures that are harder than native words: bytes and
> shorts can require load-modify-write cycles, and "u64" and friends can
> obviously be multiple words, so you shouldn't depend on things for those
> "complex" cases. But we *definitely* depend on atomicity for regular word
> accesses).
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2008-03-06 16:27 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20080225090316.GA420@elf.ucw.cz>
2008-02-25 14:46 ` using long instead of atomic_t when only set/read is required (was Re: [Bug 10030] Suspend doesn't work when SD card is inserted) Alan Stern
[not found] ` <Pine.LNX.4.44L0.0802250943410.3549-100000@iolanthe.rowland.org>
2008-03-03 12:08 ` [patch] Re: using long instead of atomic_t when only set/read is required Pavel Machek
[not found] ` <20080303120842.GA28369@elf.ucw.cz>
2008-03-03 15:42 ` Alan Stern
2008-03-03 15:48 ` Alan Cox
[not found] ` <Pine.LNX.4.44L0.0803031023550.3611-100000@iolanthe.rowland.org>
2008-03-03 15:53 ` Alan Cox
[not found] ` <20080303155330.39e45ad4@core>
2008-03-03 17:11 ` Alan Stern
2008-03-03 17:16 ` Nick Piggin
2008-03-03 17:31 ` Paul E. McKenney
2008-03-03 17:33 ` Alan Cox
2008-03-03 17:22 ` Paul E. McKenney
[not found] ` <20080303154831.22a4eb14@core>
2008-03-03 17:24 ` Pavel Machek
2008-03-03 20:27 ` Rafael J. Wysocki
[not found] ` <200803032127.30761.rjw@sisk.pl>
2008-03-03 21:12 ` Paul E. McKenney
2008-03-03 22:23 ` Linus Torvalds
[not found] <Pine.LNX.4.44L0.0803031207120.3611-100000@iolanthe.rowland.org>
2008-03-03 17:26 ` Linus Torvalds
2008-03-03 17:44 ` Pavel Machek
2008-03-06 15:58 ` Mark Lord
[not found] ` <47D014A6.9090300@rtr.ca>
2008-03-06 16:11 ` Linus Torvalds
[not found] ` <alpine.LFD.1.00.0803060807120.12253@woody.linux-foundation.org>
2008-03-06 16:27 ` Mark Lord
[not found] <20080303174422.GB13869@elf.ucw.cz>
2008-03-03 19:27 ` Alan Stern
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox