Description
We're going through doing an audit of barrier/fence usage in DMA situations in a separate codebase, and I was comparing my implementations to yours when I noticed something odd that I wanted to ask about.
#264 introduced calls to compiler_fence
in the inline asm versions of the barrier functions, such as dmb
. The current implementation of dmb
reads:
#[inline(always)]
pub unsafe fn __dmb() {
asm!("dmb");
compiler_fence(Ordering::SeqCst);
}
I'm concerned about what the presence of compiler_fence
implies. One of two things must be true here:
-
asm!
without thenomem
attribute participates in the compiler's ordering of memory accesses, such that no loads/stores above theasm!
will be moved to below it in the generated instruction stream. In this case, thecompiler_fence
is unnecessary and arguably misleading (as it has misled at least one person: me). -
The
compiler_fence
really is necessary to prevent motion of memory accesses, in which case the compiler is free to move instructions after thedmb
but before thecompiler_fence
. This would be, well, bad.
I think (1) is likely the case, though it is not explicitly documented as such in the inline asm RFC. Before I go hassle the UCG folks again, I was curious if I'm missing something and y'all had a more detailed rationale for this pattern.
Thanks!