* Re: [patch] Re: using long instead of atomic_t when only set/read is required
@ 2008-03-05 17:07 Matti Linnanvuori
0 siblings, 0 replies; 23+ messages in thread
From: Matti Linnanvuori @ 2008-03-05 17:07 UTC (permalink / raw)
To: linux-kernel
On Mon, 2008-03-03 at 18:24 +0100, Pavel Machek wrote:
> "For all properly-aligned pointer and integral types other than short or
> long long..."
As far as I know, Linux kernel supports Alpha that does not have atomic
updates of integral types with less than 32 bits.
____________________________________________________________________________________
Looking for last minute shopping deals?
Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping
^ permalink raw reply [flat|nested] 23+ messages in thread* 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)
@ 2008-02-25 9:03 Pavel Machek
2008-02-25 14:46 ` Alan Stern
0 siblings, 1 reply; 23+ messages in thread
From: Pavel Machek @ 2008-02-25 9:03 UTC (permalink / raw)
To: Alan Stern, zdenek.kabelac, davem
Cc: Rafael J. Wysocki, Pierre Ossman, Zdenek Kabelac,
Kernel development list, pm list
Hi!
Alan thinks that `subj` is correct...
> > > > At the very least, you'd need rmb() before reading it and wmb() after
> > > > writing to it, but I'm not sure if that's enough on every obscure
> > > > architecture out there.
> > >
> > > No, neither one is needed because of the way suspending_task is used.
> > >
> > > It's not necessary for a reader R to see the variable's actual value;
> > > all R needs to know is whether or not suspending_task is equal to R.
> > > Since the only process which can set suspending_task to R is R itself,
> > > and since R will set suspending_task back to NULL before releasing the
> > > write lock on pm_sleep_rwsem, there's never any ambiguity.
> >
> > Subtle.
> >
> > Very subtly wrong ;-).
> >
> > imagine suspending_task == 0xabcdef01. Now task "R" with current ==
> > 0xabcd0000 reads suspending_task while the other cpu is writing to it,
> > and sees 0xabcd0000 (0xef01 was not yet written) -- and mistakenly
> > believes that "R" == suspending_task.
>
> I always thought that reads and writes of pointers are atomic, just
> like reads and writes of longs. Is that wrong?
...but I'm not that sure. Can someone clarify?
I guess it only works as long as longs are aligned? Should it be
written down to atomic_ops.txt?
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] 23+ messages in thread* 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) 2008-02-25 9:03 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) Pavel Machek @ 2008-02-25 14:46 ` Alan Stern 2008-03-03 12:08 ` [patch] Re: using long instead of atomic_t when only set/read is required Pavel Machek 0 siblings, 1 reply; 23+ messages in thread From: Alan Stern @ 2008-02-25 14:46 UTC (permalink / raw) To: Pavel Machek Cc: Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* [patch] Re: using long instead of atomic_t when only set/read is required 2008-02-25 14:46 ` Alan Stern @ 2008-03-03 12:08 ` Pavel Machek 2008-03-03 15:42 ` Alan Stern 2008-03-03 15:48 ` Alan Cox 0 siblings, 2 replies; 23+ messages in thread From: Pavel Machek @ 2008-03-03 12:08 UTC (permalink / raw) To: Alan Stern, Linus Torvalds, Andrew Morton Cc: Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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 [flat|nested] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 12:08 ` [patch] Re: using long instead of atomic_t when only set/read is required Pavel Machek @ 2008-03-03 15:42 ` Alan Stern 2008-03-03 15:53 ` Alan Cox 2008-03-03 17:22 ` Paul E. McKenney 2008-03-03 15:48 ` Alan Cox 1 sibling, 2 replies; 23+ messages in thread From: Alan Stern @ 2008-03-03 15:42 UTC (permalink / raw) To: Pavel Machek Cc: Paul E. McKenney, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 15:42 ` Alan Stern @ 2008-03-03 15:53 ` Alan Cox 2008-03-03 17:11 ` Alan Stern 2008-03-03 17:16 ` Nick Piggin 2008-03-03 17:22 ` Paul E. McKenney 1 sibling, 2 replies; 23+ messages in thread From: Alan Cox @ 2008-03-03 15:53 UTC (permalink / raw) To: Alan Stern Cc: Pavel Machek, Paul E. McKenney, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list > 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 15:53 ` Alan Cox @ 2008-03-03 17:11 ` Alan Stern 2008-03-03 17:26 ` Linus Torvalds 2008-03-03 17:16 ` Nick Piggin 1 sibling, 1 reply; 23+ messages in thread From: Alan Stern @ 2008-03-03 17:11 UTC (permalink / raw) To: Alan Cox Cc: Pavel Machek, Paul E. McKenney, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 17:11 ` Alan Stern @ 2008-03-03 17:26 ` Linus Torvalds 2008-03-03 17:44 ` Pavel Machek 2008-03-06 15:58 ` Mark Lord 0 siblings, 2 replies; 23+ messages in thread From: Linus Torvalds @ 2008-03-03 17:26 UTC (permalink / raw) To: Alan Stern Cc: Alan Cox, Pavel Machek, Paul E. McKenney, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ 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-03 19:27 ` Alan Stern 2008-03-06 15:58 ` Mark Lord 1 sibling, 1 reply; 23+ messages in thread From: Pavel Machek @ 2008-03-03 17:44 UTC (permalink / raw) To: Linus Torvalds Cc: Alan Stern, Alan Cox, Paul E. McKenney, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 17:44 ` Pavel Machek @ 2008-03-03 19:27 ` Alan Stern 0 siblings, 0 replies; 23+ messages in thread From: Alan Stern @ 2008-03-03 19:27 UTC (permalink / raw) To: Pavel Machek Cc: Linus Torvalds, Alan Cox, Paul E. McKenney, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ 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 2008-03-06 16:11 ` Linus Torvalds 1 sibling, 1 reply; 23+ messages in thread From: Mark Lord @ 2008-03-06 15:58 UTC (permalink / raw) To: Linus Torvalds Cc: Alan Stern, Alan Cox, Pavel Machek, Paul E. McKenney, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-06 15:58 ` Mark Lord @ 2008-03-06 16:11 ` Linus Torvalds 2008-03-06 16:27 ` Mark Lord 0 siblings, 1 reply; 23+ messages in thread From: Linus Torvalds @ 2008-03-06 16:11 UTC (permalink / raw) To: Mark Lord Cc: Alan Stern, Alan Cox, Pavel Machek, Paul E. McKenney, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-06 16:11 ` Linus Torvalds @ 2008-03-06 16:27 ` Mark Lord 0 siblings, 0 replies; 23+ messages in thread From: Mark Lord @ 2008-03-06 16:27 UTC (permalink / raw) To: Linus Torvalds Cc: Alan Stern, Alan Cox, Pavel Machek, Paul E. McKenney, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 15:53 ` Alan Cox 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; 23+ messages in thread From: Nick Piggin @ 2008-03-03 17:16 UTC (permalink / raw) To: Alan Cox Cc: Alan Stern, Pavel Machek, Paul E. McKenney, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ 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; 23+ messages in thread From: Paul E. McKenney @ 2008-03-03 17:31 UTC (permalink / raw) To: Nick Piggin Cc: Alan Cox, Alan Stern, Pavel Machek, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ 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; 23+ messages in thread From: Alan Cox @ 2008-03-03 17:33 UTC (permalink / raw) To: Nick Piggin Cc: Alan Stern, Pavel Machek, Paul E. McKenney, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list > 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 15:42 ` Alan Stern 2008-03-03 15:53 ` Alan Cox @ 2008-03-03 17:22 ` Paul E. McKenney 1 sibling, 0 replies; 23+ messages in thread From: Paul E. McKenney @ 2008-03-03 17:22 UTC (permalink / raw) To: Alan Stern Cc: Pavel Machek, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 12:08 ` [patch] Re: using long instead of atomic_t when only set/read is required Pavel Machek 2008-03-03 15:42 ` Alan Stern @ 2008-03-03 15:48 ` Alan Cox 2008-03-03 17:24 ` Pavel Machek 1 sibling, 1 reply; 23+ messages in thread From: Alan Cox @ 2008-03-03 15:48 UTC (permalink / raw) To: Pavel Machek Cc: Alan Stern, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list > 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 15:48 ` Alan Cox @ 2008-03-03 17:24 ` Pavel Machek 2008-03-03 20:27 ` Rafael J. Wysocki 2008-03-04 23:32 ` Peter Hartley 0 siblings, 2 replies; 23+ messages in thread From: Pavel Machek @ 2008-03-03 17:24 UTC (permalink / raw) To: Alan Cox Cc: Alan Stern, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman, Kernel development list, pm list 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] 23+ 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 2008-03-03 21:12 ` Paul E. McKenney 2008-03-03 22:23 ` Linus Torvalds 2008-03-04 23:32 ` Peter Hartley 1 sibling, 2 replies; 23+ messages in thread From: Rafael J. Wysocki @ 2008-03-03 20:27 UTC (permalink / raw) To: Pavel Machek Cc: Alan Cox, Alan Stern, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Pierre Ossman, Kernel development list, pm list, Paul E. McKenney 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 20:27 ` Rafael J. Wysocki @ 2008-03-03 21:12 ` Paul E. McKenney 2008-03-03 22:23 ` Linus Torvalds 1 sibling, 0 replies; 23+ messages in thread From: Paul E. McKenney @ 2008-03-03 21:12 UTC (permalink / raw) To: Rafael J. Wysocki Cc: Pavel Machek, Alan Cox, Alan Stern, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Pierre Ossman, Kernel development list, pm list 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] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-03 20:27 ` Rafael J. Wysocki 2008-03-03 21:12 ` Paul E. McKenney @ 2008-03-03 22:23 ` Linus Torvalds 1 sibling, 0 replies; 23+ messages in thread From: Linus Torvalds @ 2008-03-03 22:23 UTC (permalink / raw) To: Rafael J. Wysocki Cc: Pavel Machek, Alan Cox, Alan Stern, Andrew Morton, Zdenek Kabelac, davem, Pierre Ossman, Kernel development list, pm list, Paul E. McKenney 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] 23+ 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 @ 2008-03-04 23:32 ` Peter Hartley 2008-03-04 23:54 ` Rafael J. Wysocki 1 sibling, 1 reply; 23+ messages in thread From: Peter Hartley @ 2008-03-04 23:32 UTC (permalink / raw) To: linux-kernel, Pavel Machek Cc: Alan Cox, Alan Stern, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Rafael J. Wysocki, Pierre Ossman On Mon, 2008-03-03 at 18:24 +0100, Pavel Machek wrote: > 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. ARM6, ARM7500 and similar do exactly this for short (and unsigned short), although not for int, long, or pointers: > struct foo { short b; short c; }; > void baa(struct foo *f, short cc) { f->c = cc; } becomes (arm-linux-gcc -mcpu=arm6): > baa: > mov r3, r1, lsr #8 > strb r3, [r0, #3] > strb r1, [r0, #2] > mov pc, lr note the two single-byte stores, as ARM6 didn't have the "store halfword" instruction. So I think Alan Stern's "For all properly-aligned pointer and integral types other than long long..." should be amended to "For all properly-aligned pointer and integral types other than short or long long..." Peter ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-04 23:32 ` Peter Hartley @ 2008-03-04 23:54 ` Rafael J. Wysocki 2008-03-05 0:26 ` Paul E. McKenney 0 siblings, 1 reply; 23+ messages in thread From: Rafael J. Wysocki @ 2008-03-04 23:54 UTC (permalink / raw) To: Peter Hartley Cc: linux-kernel, Pavel Machek, Alan Cox, Alan Stern, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Pierre Ossman, Paul E. McKenney On Wednesday, 5 of March 2008, Peter Hartley wrote: > On Mon, 2008-03-03 at 18:24 +0100, Pavel Machek wrote: > > 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. > > ARM6, ARM7500 and similar do exactly this for short (and unsigned > short), although not for int, long, or pointers: > > > struct foo { short b; short c; }; > > void baa(struct foo *f, short cc) { f->c = cc; } > > becomes (arm-linux-gcc -mcpu=arm6): > > > baa: > > mov r3, r1, lsr #8 > > strb r3, [r0, #3] > > strb r1, [r0, #2] > > mov pc, lr > > note the two single-byte stores, as ARM6 didn't have the "store > halfword" instruction. > > So I think Alan Stern's > "For all properly-aligned pointer and integral types other than long > long..." > should be amended to > "For all properly-aligned pointer and integral types other than short or > long long..." Well, perhaps it's sufficient to document just pointers? In fact this is what RCU relies on. Thanks, Rafael ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [patch] Re: using long instead of atomic_t when only set/read is required 2008-03-04 23:54 ` Rafael J. Wysocki @ 2008-03-05 0:26 ` Paul E. McKenney 0 siblings, 0 replies; 23+ messages in thread From: Paul E. McKenney @ 2008-03-05 0:26 UTC (permalink / raw) To: Rafael J. Wysocki Cc: Peter Hartley, linux-kernel, Pavel Machek, Alan Cox, Alan Stern, Linus Torvalds, Andrew Morton, Zdenek Kabelac, davem, Pierre Ossman On Wed, Mar 05, 2008 at 12:54:03AM +0100, Rafael J. Wysocki wrote: > On Wednesday, 5 of March 2008, Peter Hartley wrote: > > On Mon, 2008-03-03 at 18:24 +0100, Pavel Machek wrote: > > > 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. > > > > ARM6, ARM7500 and similar do exactly this for short (and unsigned > > short), although not for int, long, or pointers: > > > > > struct foo { short b; short c; }; > > > void baa(struct foo *f, short cc) { f->c = cc; } > > > > becomes (arm-linux-gcc -mcpu=arm6): > > > > > baa: > > > mov r3, r1, lsr #8 > > > strb r3, [r0, #3] > > > strb r1, [r0, #2] > > > mov pc, lr > > > > note the two single-byte stores, as ARM6 didn't have the "store > > halfword" instruction. > > > > So I think Alan Stern's > > "For all properly-aligned pointer and integral types other than long > > long..." > > should be amended to > > "For all properly-aligned pointer and integral types other than short or > > long long..." > > Well, perhaps it's sufficient to document just pointers? In fact this is what > RCU relies on. One can do RCU on array indexes (ints/longs) as well as pointers, so we need to keep "integral" in there. Thanx, Paul ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2008-03-06 16:27 UTC | newest] Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-03-05 17:07 [patch] Re: using long instead of atomic_t when only set/read is required Matti Linnanvuori -- strict thread matches above, loose matches on Subject: below -- 2008-02-25 9:03 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) Pavel Machek 2008-02-25 14:46 ` Alan Stern 2008-03-03 12:08 ` [patch] Re: using long instead of atomic_t when only set/read is required Pavel Machek 2008-03-03 15:42 ` Alan Stern 2008-03-03 15:53 ` Alan Cox 2008-03-03 17:11 ` Alan Stern 2008-03-03 17:26 ` Linus Torvalds 2008-03-03 17:44 ` Pavel Machek 2008-03-03 19:27 ` Alan Stern 2008-03-06 15:58 ` Mark Lord 2008-03-06 16:11 ` Linus Torvalds 2008-03-06 16:27 ` Mark Lord 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 2008-03-03 15:48 ` Alan Cox 2008-03-03 17:24 ` Pavel Machek 2008-03-03 20:27 ` Rafael J. Wysocki 2008-03-03 21:12 ` Paul E. McKenney 2008-03-03 22:23 ` Linus Torvalds 2008-03-04 23:32 ` Peter Hartley 2008-03-04 23:54 ` Rafael J. Wysocki 2008-03-05 0:26 ` Paul E. McKenney
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®