* Synchronization [was Re: The Magic Show: kernel_map() disappearing]
[not found] ` <Pine.LNX.3.96.990113130000.3632F-100000@persephone.cs.nmt.edu>
@ 1999-01-14 8:57 ` Jesper Skov
1999-01-14 9:55 ` Jes Sorensen
` (3 more replies)
0 siblings, 4 replies; 16+ messages in thread
From: Jesper Skov @ 1999-01-14 8:57 UTC (permalink / raw)
To: Cort Dougan; +Cc: linuxppc-dev, Jes Sorensen, alan, Linux/APUS mailing list
>>>>> "Cort" == Cort Dougan <cort@persephone.cs.nmt.edu> writes:
Cort> You're right, that was an oversight on my part. I'll fix the
Cort> mistake. I'll commit that to vger now. I'm going to leave the
Cort> sync in there as well, to make sure that things stall until the
Cort> writes are done.
Cort> }The reordering thing can also be achieved with 'sync', but it
Cort> stalls }the CPU until all IO has completed. 'eieio' is the
Cort> correct solution }(IMHO.. And Motos NSHO btw)
OK, core of the problem is that I don't know what mb() is supposed to
do. Here's what we have on the PPC:
sync : stall CPU until all IO has completed.
eieio: prevent CPU from reordering/collapsing reads/writes to memory.
(but otherwise run at full steam!)
We would want to use eieio for drivers and such accessing their
controller in a strict serialized manner. We would want to use sync
for SMP related stuff since it ensures, well, synchronization between
multiple CPUs wrt memory access.
Using sync for drivers is a bad idea; it's overkill, stalling the
CPU for no good reason.
That's why I added the iobarrier() macros (adding _w/_r/_rw on Alan's
request) that are only related to IO synchronization within the same
CPU. Essentially it's just renaming the eieio() macro already used in
many PPC drivers because it's a bad name; Linux/APUS will be sharing
drivers with Linux/m68k where eieio isn't such a helpful name.
Given that mb() was defined as sync, I assumed mb() to be the common
Linux name for a thingie used for SMP synchronization.
I may have been wrong. iobarrier() may not be such a good name after
all, but I think it's important for the names to reflect the semantics
of the function. And there are two separate synchronization semantics
required (at least on the PPC) - I don't want to merge them just
because there's already a common Linux function that's named mb()
(memory barrier, presumably).
Don't know what the functions/macros should be named, but it would be
nice if:
a) the names reflected semantics: CPU internal IO synchronization vs
inter-CPU synchronization.
b) the names were common on all Linux
archs, defined as do {} while(0) when not applicable.
For bigger brains to discuss further. I rest my case :)
Jesper
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 8:57 ` Synchronization [was Re: The Magic Show: kernel_map() disappearing] Jesper Skov
@ 1999-01-14 9:55 ` Jes Sorensen
1999-01-14 16:25 ` luther sven
1999-01-14 13:27 ` Benjamin Herrenschmidt
` (2 subsequent siblings)
3 siblings, 1 reply; 16+ messages in thread
From: Jes Sorensen @ 1999-01-14 9:55 UTC (permalink / raw)
To: Jesper Skov; +Cc: Cort Dougan, linuxppc-dev, alan, Linux/APUS mailing list
>>>>> "Jesper" == Jesper Skov <jskov@cygnus.co.uk> writes:
>>>>> "Cort" == Cort Dougan <cort@persephone.cs.nmt.edu> writes:
Cort> You're right, that was an oversight on my part. I'll fix the
Cort> mistake. I'll commit that to vger now. I'm going to leave the
Cort> sync in there as well, to make sure that things stall until the
Cort> writes are done.
Jesper> OK, core of the problem is that I don't know what mb() is
Jesper> supposed to do. Here's what we have on the PPC:
mb() is supposed to ensure that the CPU does not reschedule
instructions' memory access beyond the mb().
Jesper> sync : stall CPU until all IO has completed. eieio: prevent
Jesper> CPU from reordering/collapsing reads/writes to memory. (but
Jesper> otherwise run at full steam!)
[snip]
Jesper> That's why I added the iobarrier() macros (adding _w/_r/_rw on
Jesper> Alan's request) that are only related to IO synchronization
Jesper> within the same CPU. Essentially it's just renaming the
Jesper> eieio() macro already used in many PPC drivers because it's a
Jesper> bad name; Linux/APUS will be sharing drivers with Linux/m68k
Jesper> where eieio isn't such a helpful name.
Jesper> Given that mb() was defined as sync, I assumed mb() to be the
Jesper> common Linux name for a thingie used for SMP synchronization.
I guess you would normally use a spinlock() for that, mb() is supposed
to ensure the ordering regarding access to memory which is really what
is happening in most of our drivers (at least all the Amiga ones) -
this is why I was moaning about the iobarrier() stuff as it was not
clear to me what it was supposed to do differently from mb() - except
if you want ordering when going out on an I/O bus like on the PC.
Jesper> I may have been wrong. iobarrier() may not be such a good name
Jesper> after all, but I think it's important for the names to reflect
Jesper> the semantics of the function. And there are two separate
Jesper> synchronization semantics required (at least on the PPC) - I
Jesper> don't want to merge them just because there's already a common
Jesper> Linux function that's named mb() (memory barrier, presumably).
When considering the name, memory barrier is the right name, after
all, all your driver registers are memory mapped and therefore `just'
another type of memory.
Jes
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 8:57 ` Synchronization [was Re: The Magic Show: kernel_map() disappearing] Jesper Skov
1999-01-14 9:55 ` Jes Sorensen
@ 1999-01-14 13:27 ` Benjamin Herrenschmidt
1999-01-14 19:46 ` Douglas Godfrey
1999-01-14 20:52 ` Alan Cox
3 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 1999-01-14 13:27 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Cort Dougan, Jesper Skov
On Thu, Jan 14, 1999, Jesper Skov <jskov@cygnus.co.uk> wrote:
>We would want to use eieio for drivers and such accessing their
>controller in a strict serialized manner. We would want to use sync
>for SMP related stuff since it ensures, well, synchronization between
>multiple CPUs wrt memory access.
And I'll add the usual warning: If the device is a PCI device and you
need to make sure that the write actually reached the device (for example
making sure the interrupt enable bits are set before re-enabling the
interrupts on the CPU), you should add a read from the same device (from
the same bus should be enough) to make sure tall the bridges in the path
to the device completed their write.
Remember that a write to PCI is usually a "posted write" and so is
asynchronous, regardless of eieio or sync's done on the CPU.
--
E-Mail: <mailto:bh40@calva.net>
BenH. Web : <http://calvaweb.calvacom.fr/bh40/>
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 9:55 ` Jes Sorensen
@ 1999-01-14 16:25 ` luther sven
0 siblings, 0 replies; 16+ messages in thread
From: luther sven @ 1999-01-14 16:25 UTC (permalink / raw)
To: Jes Sorensen, Jesper Skov
Cc: Cort Dougan, linuxppc-dev, alan, Linux/APUS mailing list
On Thu, Jan 14, 1999 at 10:55:37AM +0100, Jes Sorensen wrote:
> >>>>> "Jesper" == Jesper Skov <jskov@cygnus.co.uk> writes:
>
> >>>>> "Cort" == Cort Dougan <cort@persephone.cs.nmt.edu> writes:
> Cort> You're right, that was an oversight on my part. I'll fix the
> Cort> mistake. I'll commit that to vger now. I'm going to leave the
> Cort> sync in there as well, to make sure that things stall until the
> Cort> writes are done.
>
> Jesper> OK, core of the problem is that I don't know what mb() is
> Jesper> supposed to do. Here's what we have on the PPC:
>
> mb() is supposed to ensure that the CPU does not reschedule
> instructions' memory access beyond the mb().
>
> Jesper> sync : stall CPU until all IO has completed. eieio: prevent
> Jesper> CPU from reordering/collapsing reads/writes to memory. (but
> Jesper> otherwise run at full steam!)
>
> [snip]
>
> Jesper> That's why I added the iobarrier() macros (adding _w/_r/_rw on
> Jesper> Alan's request) that are only related to IO synchronization
> Jesper> within the same CPU. Essentially it's just renaming the
> Jesper> eieio() macro already used in many PPC drivers because it's a
> Jesper> bad name; Linux/APUS will be sharing drivers with Linux/m68k
> Jesper> where eieio isn't such a helpful name.
>
> Jesper> Given that mb() was defined as sync, I assumed mb() to be the
> Jesper> common Linux name for a thingie used for SMP synchronization.
>
> I guess you would normally use a spinlock() for that, mb() is supposed
> to ensure the ordering regarding access to memory which is really what
> is happening in most of our drivers (at least all the Amiga ones) -
> this is why I was moaning about the iobarrier() stuff as it was not
> clear to me what it was supposed to do differently from mb() - except
> if you want ordering when going out on an I/O bus like on the PC.
>
> Jesper> I may have been wrong. iobarrier() may not be such a good name
> Jesper> after all, but I think it's important for the names to reflect
> Jesper> the semantics of the function. And there are two separate
> Jesper> synchronization semantics required (at least on the PPC) - I
> Jesper> don't want to merge them just because there's already a common
> Jesper> Linux function that's named mb() (memory barrier, presumably).
>
> When considering the name, memory barrier is the right name, after
> all, all your driver registers are memory mapped and therefore `just'
> another type of memory.
If i understood things correctly, it shopuld be :
mb() is in fact an eieio call.
spinlock() should be an sync() call.
so the current use of mb() is either wrong or misdefined.
Did i miss something here ?
Friendly;
Sven LUTHER
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 8:57 ` Synchronization [was Re: The Magic Show: kernel_map() disappearing] Jesper Skov
1999-01-14 9:55 ` Jes Sorensen
1999-01-14 13:27 ` Benjamin Herrenschmidt
@ 1999-01-14 19:46 ` Douglas Godfrey
1999-01-14 20:52 ` Alan Cox
3 siblings, 0 replies; 16+ messages in thread
From: Douglas Godfrey @ 1999-01-14 19:46 UTC (permalink / raw)
To: Jesper Skov; +Cc: linuxppc-dev, Jes Sorensen, alan, Linux/APUS mailing list
If you define a structure with an independant spinlock for each driver
and change the iobarrier() macro to iobarrier(lock) and iobarrier(unlock)
you can get correct MP behavior without slowing down UP systems. The MP
version of iobarrier() would do a eieio instruction and then acquire/release
the spinlock and while the UP version would just do a eieio. MP systems will
incurr the overhead of locating and locking/unlocking the spinlock. UP
systems will have no overhead beond the eieio. The lock/unlock parameter
would be ignored for UP systems and required for MP systems.
For both Nubus and PCI PPC systems the requirement is just that only 1
driver at a time and access a device and that load/stores be done in
strict program order.
For Example:
While the SCSI driver is setting up a read I/O, it is perfectly OK for a
serial driver to be writing to a serial port on another CPU. The PCI accesses
for the 2 drivers can be interleaved in any order as long as each driver's
accesses are in proper sequence.
At 3:57 AM -0500 1/14/99, Jesper Skov wrote: [Synchronization [was Re: The
Magic Show: kernel_map()]
>>>>>> "Cort" == Cort Dougan <cort@persephone.cs.nmt.edu> writes:
>
>Cort> You're right, that was an oversight on my part. I'll fix the
>Cort> mistake. I'll commit that to vger now. I'm going to leave the
>Cort> sync in there as well, to make sure that things stall until the
>Cort> writes are done.
>
>Cort> }The reordering thing can also be achieved with 'sync', but it
>Cort> stalls }the CPU until all IO has completed. 'eieio' is the
>Cort> correct solution }(IMHO.. And Motos NSHO btw)
>
>
>OK, core of the problem is that I don't know what mb() is supposed to
>do. Here's what we have on the PPC:
>
> sync : stall CPU until all IO has completed.
> eieio: prevent CPU from reordering/collapsing reads/writes to memory.
> (but otherwise run at full steam!)
>
>We would want to use eieio for drivers and such accessing their
>controller in a strict serialized manner. We would want to use sync
>for SMP related stuff since it ensures, well, synchronization between
>multiple CPUs wrt memory access.
>
>Using sync for drivers is a bad idea; it's overkill, stalling the
>CPU for no good reason.
>
>That's why I added the iobarrier() macros (adding _w/_r/_rw on Alan's
>request) that are only related to IO synchronization within the same
>CPU. Essentially it's just renaming the eieio() macro already used in
>many PPC drivers because it's a bad name; Linux/APUS will be sharing
>drivers with Linux/m68k where eieio isn't such a helpful name.
>
>Given that mb() was defined as sync, I assumed mb() to be the common
>Linux name for a thingie used for SMP synchronization.
>
>I may have been wrong. iobarrier() may not be such a good name after
>all, but I think it's important for the names to reflect the semantics
>of the function. And there are two separate synchronization semantics
>required (at least on the PPC) - I don't want to merge them just
>because there's already a common Linux function that's named mb()
>(memory barrier, presumably).
>
>Don't know what the functions/macros should be named, but it would be
>nice if:
>
> a) the names reflected semantics: CPU internal IO synchronization vs
> inter-CPU synchronization.
>
> b) the names were common on all Linux
> archs, defined as do {} while(0) when not applicable.
>
>
>For bigger brains to discuss further. I rest my case :)
>
>Jesper
Thanx...
Doug
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 8:57 ` Synchronization [was Re: The Magic Show: kernel_map() disappearing] Jesper Skov
` (2 preceding siblings ...)
1999-01-14 19:46 ` Douglas Godfrey
@ 1999-01-14 20:52 ` Alan Cox
1999-01-14 21:53 ` Cort Dougan
1999-01-15 1:57 ` Paul Mackerras
3 siblings, 2 replies; 16+ messages in thread
From: Alan Cox @ 1999-01-14 20:52 UTC (permalink / raw)
To: Jesper Skov; +Cc: cort, linuxppc-dev, Jes.Sorensen, alan, linux-apus
> eieio: prevent CPU from reordering/collapsing reads/writes to memory.
> (but otherwise run at full steam!)
Thats what mb() does - its a memory-barrier hence the name - it imposes
strong store ordering properties across it.
> That's why I added the iobarrier() macros (adding _w/_r/_rw on Alan's
> request) that are only related to IO synchronization within the same
> CPU. Essentially it's just renaming the eieio() macro already used in
> many PPC drivers because it's a bad name; Linux/APUS will be sharing
> drivers with Linux/m68k where eieio isn't such a helpful name.
Yep.
x86 and most other processors dont have the notion of a store barrier and
an i/o barrier beign different
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 20:52 ` Alan Cox
@ 1999-01-14 21:53 ` Cort Dougan
1999-01-15 1:38 ` Alan Cox
1999-01-15 8:26 ` Jesper Skov
1999-01-15 1:57 ` Paul Mackerras
1 sibling, 2 replies; 16+ messages in thread
From: Cort Dougan @ 1999-01-14 21:53 UTC (permalink / raw)
To: Alan Cox; +Cc: Jesper Skov, linuxppc-dev, Jes.Sorensen, linux-apus
That's my rationale for doing the sync and eieio in the mb(). That way,
we're guaranteed no races no matter what assumptions someone makes about
the x86 when adding barriers to their driver code. Is that unreasonable?
}x86 and most other processors dont have the notion of a store barrier and
}an i/o barrier beign different
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 21:53 ` Cort Dougan
@ 1999-01-15 1:38 ` Alan Cox
1999-01-15 8:26 ` Jesper Skov
1 sibling, 0 replies; 16+ messages in thread
From: Alan Cox @ 1999-01-15 1:38 UTC (permalink / raw)
To: Cort Dougan; +Cc: alan, jskov, linuxppc-dev, Jes.Sorensen, linux-apus
> That's my rationale for doing the sync and eieio in the mb(). That way,
> we're guaranteed no races no matter what assumptions someone makes about
> the x86 when adding barriers to their driver code. Is that unreasonable?
It would be good to get the right stuff done in the drivers not take a
wired in performance hit we cant get back out of
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 20:52 ` Alan Cox
1999-01-14 21:53 ` Cort Dougan
@ 1999-01-15 1:57 ` Paul Mackerras
1999-01-15 8:40 ` Jes Sorensen
1999-01-15 16:10 ` Alan Cox
1 sibling, 2 replies; 16+ messages in thread
From: Paul Mackerras @ 1999-01-15 1:57 UTC (permalink / raw)
To: alan, jskov, cort, linuxppc-dev, Jes.Sorensen, linux-apus
Alan Cox <alan@cymru.net> wrote:
> > eieio: prevent CPU from reordering/collapsing reads/writes to memory.
> > (but otherwise run at full steam!)
>
> Thats what mb() does - its a memory-barrier hence the name - it imposes
> strong store ordering properties across it.
My understanding of the original mb() (and correct me if I'm wrong)
was that it basically said "an interrupt or another processor might
have changed memory, so don't keep values from memory cached in
registers". With wmb() on SMP, this seems to be extended to include
"make sure other cpus can see the values we just wrote". I don't know
exactly how rmb() differs from mb().
I just read in the Programming Environments Manual (the doc that
defines the PPC architecture) that eieio is supposed to provide
ordering for two sets of accesses:
- loads and stores to cache-inhibited, guarded addresses, and stores
to write-through cached addresses (i.e. I/O accesses),
- stores to cached, coherent addresses (i.e. addresses where the
corresponding PTE has WIM == 001).
The two sets are ordered separately. The eieio instruction doesn't
wait for previous accesses to complete, it just inserts a barrier into
the stream of memory accesses.
I guess eieio probably is strong enough for wmb(), since all ordinary
memory is marked coherent in PPC SMP.
The sync instruction is stronger than eieio, it says "wait until all
outstanding loads and stores (and instructions) have completed before
starting any new instructions". AFAICS, it subsumes eieio so there
would be no point in doing an eieio immediately after a sync.
I put a sync in for mb, rmb and wmb, which may be overkill. Certainly
I think the eieio that Cort added after the sync for these things is
unnecessary.
> x86 and most other processors dont have the notion of a store barrier and
> an i/o barrier beign different
On x86, i/o accesses are strongly ordered already. On PPC the eieio
instruction provides this sort of ordering (if you do it after each
access). So I think eieio is right for iobarrier_*. Whether eieio
would be sufficient for *mb(), or whether sync is needed, I'm not
sure. Certainly sync should be sufficient.
Paul.
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-14 21:53 ` Cort Dougan
1999-01-15 1:38 ` Alan Cox
@ 1999-01-15 8:26 ` Jesper Skov
1 sibling, 0 replies; 16+ messages in thread
From: Jesper Skov @ 1999-01-15 8:26 UTC (permalink / raw)
To: Cort Dougan; +Cc: Alan Cox, linuxppc-dev, Jes.Sorensen, linux-apus
>>>>> "Cort" == Cort Dougan <cort@persephone.cs.nmt.edu> writes:
Cort> That's my rationale for doing the sync and eieio in the mb().
Cort> That way, we're guaranteed no races no matter what assumptions
Cort> someone makes about the x86 when adding barriers to their driver
Cort> code. Is that unreasonable?
Cort> Alan} x86 and most other processors dont have the notion of a store
Cort> Alan} barrier and an i/o barrier beign different
IMHO, it is unreasonable. Why should the majority of PPC drivers run
with suboptimal performance because of bad programmer assumptions?
I'd suggest changing mb() (or whatever an appropriate name would be)
to 'eieio'. MP code and generic drivers that expect inter-CPU
synchronization to happen when using this macro should be fixed.
...but then, what do I know? :)
Jesper
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-15 1:57 ` Paul Mackerras
@ 1999-01-15 8:40 ` Jes Sorensen
1999-01-15 16:10 ` Alan Cox
1 sibling, 0 replies; 16+ messages in thread
From: Jes Sorensen @ 1999-01-15 8:40 UTC (permalink / raw)
To: Paul.Mackerras; +Cc: alan, jskov, cort, linuxppc-dev, linux-apus
>>>>> "Paul" == Paul Mackerras <paulus@cs.anu.edu.au> writes:
Paul> Alan Cox <alan@cymru.net> wrote:
>> > eieio: prevent CPU from reordering/collapsing reads/writes to
>> memory. > (but otherwise run at full steam!)
>>
>> Thats what mb() does - its a memory-barrier hence the name - it
>> imposes strong store ordering properties across it.
Paul> My understanding of the original mb() (and correct me if I'm
Paul> wrong) was that it basically said "an interrupt or another
Paul> processor might have changed memory, so don't keep values from
Paul> memory cached in registers". With wmb() on SMP, this seems to
Paul> be extended to include "make sure other cpus can see the values
Paul> we just wrote". I don't know exactly how rmb() differs from
Paul> mb().
Hmmm
My understanding is that mb() is also meant to ensure that
instructions are issued in the right order, ie. like cases where we
want to read data out of a register in a device before resetting it or
something:
data = regs->dat;
mb();
regs->reset = 1;
Maybe I am missing something, but at least thats the assumption I work
from when I use mb()'s. I haven't noticed wmb()/rmb() and checking the
code I see that these are not defined for the m68k nor the Sparc
ports.
The question is whether it makes sense to introduce the io_barrier()
macros at all or mb() is sufficient as it is. I think it is and I'd
prefer not to try and convince all the other ports to use a new macro
unless we have a real good reason for doing so. Most cases where you
would use mb() (sync on the PPC) are slow access anyway so as far as I
can see it really doesn't cost that much to let mb() do the sync.
Jes
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
@ 1999-01-15 8:50 Benjamin Herrenschmidt
0 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 1999-01-15 8:50 UTC (permalink / raw)
To: linuxppc-dev, Paul.Mackerras
On Fri, Jan 15, 1999, Paul Mackerras <paulus@cs.anu.edu.au> wrote:
>I put a sync in for mb, rmb and wmb, which may be overkill. Certainly
>I think the eieio that Cort added after the sync for these things is
>unnecessary.
The sync may still be useful for subtle situations where the driver may
require the access to be physically done before doing something else,
like turning on interrupts on the CPU or setting a shared flag which can
be used by another CPU. Usually, those drivers are broken anyway because
of the PCI posting which is rarely handled (it was apparently also the
cause of the bogus interrupts, see the fix I posted previously).
I suggest keeping sync() in mb's for max. compatibility, and
batch-changing mb() and eieio() in current PPC drivers to iobarrier()
which, in turns, does eieio()
>> x86 and most other processors dont have the notion of a store barrier and
>> an i/o barrier beign different
>
>On x86, i/o accesses are strongly ordered already. On PPC the eieio
>instruction provides this sort of ordering (if you do it after each
>access). So I think eieio is right for iobarrier_*. Whether eieio
>would be sufficient for *mb(), or whether sync is needed, I'm not
>sure. Certainly sync should be sufficient.
--
E-Mail: <mailto:bh40@calva.net>
BenH. Web : <http://calvaweb.calvacom.fr/bh40/>
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-15 1:57 ` Paul Mackerras
1999-01-15 8:40 ` Jes Sorensen
@ 1999-01-15 16:10 ` Alan Cox
1999-01-15 19:28 ` Cort Dougan
1999-01-16 1:00 ` Douglas Godfrey
1 sibling, 2 replies; 16+ messages in thread
From: Alan Cox @ 1999-01-15 16:10 UTC (permalink / raw)
To: Paul.Mackerras; +Cc: alan, jskov, cort, linuxppc-dev, Jes.Sorensen, linux-apus
> was that it basically said "an interrupt or another processor might
> have changed memory, so don't keep values from memory cached in
> registers". With wmb() on SMP, this seems to be extended to include
> "make sure other cpus can see the values we just wrote". I don't know
> exactly how rmb() differs from mb().
rmb() Do not re-order reads across this point (CPU or compiler)
wmb() Do not re-order writes across this point (CPU or compiler)
mb() Do not re-order reads or write across this point
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-15 16:10 ` Alan Cox
@ 1999-01-15 19:28 ` Cort Dougan
1999-01-16 1:00 ` Douglas Godfrey
1 sibling, 0 replies; 16+ messages in thread
From: Cort Dougan @ 1999-01-15 19:28 UTC (permalink / raw)
To: Alan Cox; +Cc: Paul.Mackerras, jskov, linuxppc-dev, Jes.Sorensen, linux-apus
Then my paranoid use of sync can go away, and we can stick with eieio as
long as we have the "memory" marked changed in the linline asm. Sound
good to everyone?
} rmb() Do not re-order reads across this point (CPU or compiler)
} wmb() Do not re-order writes across this point (CPU or compiler)
} mb() Do not re-order reads or write across this point
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map() disappearing]
1999-01-15 16:10 ` Alan Cox
1999-01-15 19:28 ` Cort Dougan
@ 1999-01-16 1:00 ` Douglas Godfrey
1999-01-16 1:09 ` Synchronization [was Re: The Magic Show: kernel_map() Alan Cox
1 sibling, 1 reply; 16+ messages in thread
From: Douglas Godfrey @ 1999-01-16 1:00 UTC (permalink / raw)
To: Alan Cox, alan, jskov, cort, linuxppc-dev, Jes.Sorensen,
linux-apus, Paul.Mackerras
At 11:10 AM -0500 1/15/99, Alan Cox wrote: [Re: Synchronization [was Re:
The Magic Show: kernel_ma]
>> was that it basically said "an interrupt or another processor might
>> have changed memory, so don't keep values from memory cached in
>> registers". With wmb() on SMP, this seems to be extended to include
>> "make sure other cpus can see the values we just wrote". I don't know
>> exactly how rmb() differs from mb().
>
> rmb() Do not re-order reads across this point (CPU or compiler)
> wmb() Do not re-order writes across this point (CPU or compiler)
> mb() Do not re-order reads or write across this point
>
>
A simple way to force any good C compiler to not save any intermediate values
or pointers in registers and still allow full compiler optimization is as
follows:
1) create a macro to be placed before and after the critical section of code
that needs to be protected. The macro increments a compiler variable and
generates a unique label with the incremented number as a suffix.
2) create a second macro that is inserted at the beginning of the main routine
that has a private volatile integer variable which is initialized to 1 and
then has a computed goto based on the variable's value where the value of 1
branches to a label immediately after the goto and the other values of the
volitile variable branch to the before and after labels from the macro in
#1 above. The volatile variable is never set to any value other than 1 but
the compiler cannot optimize the computed goto out of existance because
the variable is volatile.
3) any compiler that generates proper code will recognize that a branch based
on a volatile variable prohibits keeping any values in registers at the
target label(s) that are branched to.
Thanx...
Doug
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: Synchronization [was Re: The Magic Show: kernel_map()
1999-01-16 1:00 ` Douglas Godfrey
@ 1999-01-16 1:09 ` Alan Cox
0 siblings, 0 replies; 16+ messages in thread
From: Alan Cox @ 1999-01-16 1:09 UTC (permalink / raw)
To: Douglas Godfrey
Cc: alan, jskov, cort, linuxppc-dev, Jes.Sorensen, linux-apus,
Paul.Mackerras
> > wmb() Do not re-order writes across this point (CPU or compiler)
> > mb() Do not re-order reads or write across this point
> >
> >
> A simple way to force any good C compiler to not save any intermediate values
> or pointers in registers and still allow full compiler optimization is as
> follows:
gcc has a whole set of facilities for this.
> 3) any compiler that generates proper code will recognize that a branch based
> on a volatile variable prohibits keeping any values in registers at the
> target label(s) that are branched to.
and also stop other optimisations if not careful. With gcc you can mark
areas of memory (or all memory) as a side effect. That is done anyway for
several things. What is the issue for instruction stuff is write gathering
and store reordering by the processor itself.
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~1999-01-16 1:09 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <13980.23937.676502.388522@lassi.cygnus.co.uk>
[not found] ` <Pine.LNX.3.96.990113130000.3632F-100000@persephone.cs.nmt.edu>
1999-01-14 8:57 ` Synchronization [was Re: The Magic Show: kernel_map() disappearing] Jesper Skov
1999-01-14 9:55 ` Jes Sorensen
1999-01-14 16:25 ` luther sven
1999-01-14 13:27 ` Benjamin Herrenschmidt
1999-01-14 19:46 ` Douglas Godfrey
1999-01-14 20:52 ` Alan Cox
1999-01-14 21:53 ` Cort Dougan
1999-01-15 1:38 ` Alan Cox
1999-01-15 8:26 ` Jesper Skov
1999-01-15 1:57 ` Paul Mackerras
1999-01-15 8:40 ` Jes Sorensen
1999-01-15 16:10 ` Alan Cox
1999-01-15 19:28 ` Cort Dougan
1999-01-16 1:00 ` Douglas Godfrey
1999-01-16 1:09 ` Synchronization [was Re: The Magic Show: kernel_map() Alan Cox
1999-01-15 8:50 Synchronization [was Re: The Magic Show: kernel_map() disappearing] Benjamin Herrenschmidt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).