From 4a1d47ebea0bccd7dc1708fd3e35fd1ac1e98a57 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Mon, 6 Feb 2017 17:37:18 -0700 Subject: [PATCH] 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 --- include/spdk/barrier.h | 3 +++ include/spdk/mmio.h | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/include/spdk/barrier.h b/include/spdk/barrier.h index 3f5887190..1b83f354b 100644 --- a/include/spdk/barrier.h +++ b/include/spdk/barrier.h @@ -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") diff --git a/include/spdk/mmio.h b/include/spdk/mmio.h index 041eed6fb..0f062e74b 100644 --- a/include/spdk/mmio.h +++ b/include/spdk/mmio.h @@ -44,6 +44,8 @@ extern "C" { #include +#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 {