On 1/23/2023 6:34 PM, Alan Stern wrote:
On Mon, Jan 23, 2023 at 08:40:14AM -0800, Paul E. McKenney wrote:
In the case, the value read is passed into cmpxchg_relaxed(), which
checks the value against memory. In this case, as Arjan noted, the only
compiler-and-silicon difference between data_race() and READ_ONCE()
is that use of data_race() might allow the compiler to do things like
tear the load, thus forcing the occasional spurious cmpxchg_relaxed()
failure.
Is it possible in theory for a torn load to cause a spurious
cmpxchg_relaxed() success? Or would that not matter here?
Note that in this example there are no memory accesses between the read
and the CAS.
So if the cmpxchg succeeds, what you non-atomically read must be exactly
the value that is read by the cmpxchg, and you could pretend that the
torn read happened at the same time as the cmpxchg.
This "pretend" part requires that there are no other events in the
middle, otherwise you could be violating some ordering constraint
between those events and the torn reads. Otherwise you might get some
issues. E.g., you might read a sequence count of 259 from reading the
lower half when the count is 3 and the upper half when the count is 256,
and then do the CAS when the sequence count is 259, so if you had two
peeks at sequence-count-protected data between that read and the CAS you
might see different states despite the CAS succeeding.
have fun, jonas