Skip to content

About those compiler_fence calls in the barrier functions. #308

Closed
@cbiffle

Description

@cbiffle

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:

  1. asm! without the nomem attribute participates in the compiler's ordering of memory accesses, such that no loads/stores above the asm! will be moved to below it in the generated instruction stream. In this case, the compiler_fence is unnecessary and arguably misleading (as it has misled at least one person: me).

  2. The compiler_fence really is necessary to prevent motion of memory accesses, in which case the compiler is free to move instructions after the dmb but before the compiler_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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions