Commit 4a1d47eb authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

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: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 4baf5962
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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")

+8 −0
Original line number Diff line number Diff line
@@ -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 {