Re: atomic-up.h : memory barriers
Mathieu Desnoyers <[email protected]>
| Newsgroups | gmane.linux.kernel.tracing |
|---|---|
| Message-ID | <20061110033757.GA16182@Krystal> |
Hi,
Looking carefully at both i386 and PowerPC, I found out that by being less
strict on the data ordering on PowerPC (I removed the lwsync and isync from the
cmpxchg to do the same as the UP case) brings some ordering issues : I noticed
that both the write offset in the buffer and the commit count are only written
by their own CPU, but can be read by any CPU.
Therefore, I must insure that memory write ordering is correct by putting a
smp_wmb() before the commit_count update, here is why :
* Memory ordering
offset
written by local CPU
read by local CPU and other CPUs (reader)
commit count
written by local CPU
read by local CPU and other CPUs (reader)
consumed offset (reader position)
written by any CPU
read by any CPU
data inside the slot
written by local CPU
read by any CPU
test done in the reader before reading a subbuffer :
if ( consumed <= offset - SUBBUF_LEN )
if ( subbuf.commit_count is a multiple of SUBBUF_LEN )
read subbuffer data
increment consumed offset
We must guarantee the following ordering :
* offset
Seen from the local CPU :
offset must always be incremented before the data is written (already
consistent with the program flow)
Seen from other cpus :
offset and data can be written out of order
(because offset is always incremented : in an out of order case, offset is
lower than the actual data ready, but the commit_count _has_ to be incremented
to read the data (and a commit_count update is preceded by a store fence).
* commit_count
commit_count increment must always be seen by other CPUs after the data has
been written. Therefore, we must put a store fence before the commit_count
write. (smp_wmb)
* consumed offset
Rarely updated, use LOCK prefix on i386. Acts as a full memory barrier.
So, a smp_wmb() on commit_count should fix this problem.
Mathieu
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68