barrier: add compiler barrier and use it in MMIO
spdk_compiler_barrier() prevents the compiler from moving pointer dereferences across the barrier. Use this in the MMIO helper functions to ensure that the compiler can't reorder operations around e.g. hardware register access. Specifically, this fixes the compiler optimizing out writes to g_thread_mmio_ctrlr in the NVMe hotplug handling code. Change-Id: I6b9cec48da0e6d8d75825c28b12ece5251110080 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
4baf5962e9
commit
4a1d47ebea
@ -42,6 +42,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Compiler memory barrier */
|
||||
#define spdk_compiler_barrier() __asm volatile("" ::: "memory")
|
||||
|
||||
/** Write memory barrier */
|
||||
#define spdk_wmb() __asm volatile("sfence" ::: "memory")
|
||||
|
||||
|
@ -44,6 +44,8 @@ extern "C" {
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "spdk/barrier.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define SPDK_MMIO_64BIT 1 /* Can do atomic 64-bit memory read/write (over PCIe) */
|
||||
#else
|
||||
@ -53,12 +55,14 @@ extern "C" {
|
||||
static inline uint32_t
|
||||
spdk_mmio_read_4(const volatile uint32_t *addr)
|
||||
{
|
||||
spdk_compiler_barrier();
|
||||
return *addr;
|
||||
}
|
||||
|
||||
static inline void
|
||||
spdk_mmio_write_4(volatile uint32_t *addr, uint32_t val)
|
||||
{
|
||||
spdk_compiler_barrier();
|
||||
*addr = val;
|
||||
}
|
||||
|
||||
@ -68,6 +72,8 @@ spdk_mmio_read_8(volatile uint64_t *addr)
|
||||
uint64_t val;
|
||||
volatile uint32_t *addr32 = (volatile uint32_t *)addr;
|
||||
|
||||
spdk_compiler_barrier();
|
||||
|
||||
if (SPDK_MMIO_64BIT) {
|
||||
val = *addr;
|
||||
} else {
|
||||
@ -88,6 +94,8 @@ spdk_mmio_write_8(volatile uint64_t *addr, uint64_t val)
|
||||
{
|
||||
volatile uint32_t *addr32 = (volatile uint32_t *)addr;
|
||||
|
||||
spdk_compiler_barrier();
|
||||
|
||||
if (SPDK_MMIO_64BIT) {
|
||||
*addr = val;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user