• Paul Burton's avatar
    MIPS: barrier: Add __SYNC() infrastructure · bf929272
    Paul Burton authored
    Introduce an asm/sync.h header which provides infrastructure that can be
    used to generate sync instructions of various types, and for various
    reasons. For example if we need a sync instruction that provides a full
    completion barrier but only on systems which have weak memory ordering,
    we can generate the appropriate assembly code using:
    
      __SYNC(full, weak_ordering)
    
    When the kernel is configured to run on systems with weak memory
    ordering (ie. CONFIG_WEAK_ORDERING is selected) we'll emit a sync
    instruction. When the kernel is configured to run on systems with strong
    memory ordering (ie. CONFIG_WEAK_ORDERING is not selected) we'll emit
    nothing. The caller doesn't need to know which happened - it simply says
    what it needs & when, with no concern for checking the kernel
    configuration.
    
    There are some scenarios in which we may want to emit code only when we
    *didn't* emit a sync instruction. For example, some Loongson3 CPUs
    suffer from a bug that requires us to emit a sync instruction prior to
    each ll instruction (enabled by CONFIG_CPU_LOONGSON3_WORKAROUNDS). In
    cases where this bug workaround is enabled, it's wasteful to then have
    more generic code emit another sync instruction to provide barriers we
    need in general. A __SYNC_ELSE() macro allows for this, providing an
    extra argument that contains code to be assembled only in cases where
    the sync instruction was not emitted. For example if we have a scenario
    in which we generally want to emit a release barrier but for affected
    Loongson3 configurations upgrade that to a full completion barrier, we
    can do that like so:
    
      __SYNC_ELSE(full, loongson3_war, __SYNC(rl, always))
    
    The assembly generated by these macros can be used either as inline
    assembly or in assembly source files.
    
    Differing types of sync as provided by MIPSr6 are defined, but currently
    they all generate a full completion barrier except in kernels configured
    for Cavium Octeon systems. There the wmb sync-type is used, and rmb
    syncs are omitted, as has been the case since commit 6b07d38a
    ("MIPS: Octeon: Use optimized memory barrier primitives."). Using
    __SYNC() with the wmb or rmb types will abstract away the Octeon
    specific behavior and allow us to later clean up asm/barrier.h code that
    currently includes a plethora of #ifdef's.
    Signed-off-by: default avatarPaul Burton <paul.burton@mips.com>
    Cc: linux-mips@vger.kernel.org
    Cc: Huacai Chen <chenhc@lemote.com>
    Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
    Cc: linux-kernel@vger.kernel.org
    bf929272
barrier.h 5.47 KB