From db6defc77508f5bf217f0a6768d13426eee21119 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 11 Dec 2007 08:55:53 +0100 Subject: [PATCH] syslet: add proper read barrier between user_tail and completion read Also fixup a bug with ring indexing, it needs to use the real ring size mask, not the io depth. Signed-off-by: Jens Axboe --- arch/arch-alpha.h | 1 + arch/arch-ia64.h | 3 ++- arch/arch-ppc.h | 8 ++++++++ arch/arch-s390.h | 1 + arch/arch-x86.h | 3 ++- arch/arch-x86_64.h | 3 ++- engines/syslet-rw.c | 9 +++++++-- 7 files changed, 23 insertions(+), 5 deletions(-) diff --git a/arch/arch-alpha.h b/arch/arch-alpha.h index b899494f..a476891a 100644 --- a/arch/arch-alpha.h +++ b/arch/arch-alpha.h @@ -14,5 +14,6 @@ #define nop do { } while (0) #define fio_ffz(v) generic_ffz((v)) +#define read_barrier() __asm__ __volatile__("mb": : :"memory") #endif diff --git a/arch/arch-ia64.h b/arch/arch-ia64.h index 7baccca5..3268acc5 100644 --- a/arch/arch-ia64.h +++ b/arch/arch-ia64.h @@ -18,7 +18,8 @@ #define __NR_sys_vmsplice 1302 #endif -#define nop asm volatile ("hint @pause" ::: "memory"); +#define nop asm volatile ("hint @pause" ::: "memory"); +#define read_barrier() asm volatile ("mf" ::: "memory") #define ia64_popcnt(x) \ ({ \ diff --git a/arch/arch-ppc.h b/arch/arch-ppc.h index 0a23c01a..97831319 100644 --- a/arch/arch-ppc.h +++ b/arch/arch-ppc.h @@ -20,6 +20,14 @@ #define nop do { } while (0) +#ifdef __powerpc64__ +#define read_barrier() \ + __asm__ __volatile__ ("lwsync" : : : "memory") +#else +#define read_barrier() \ + __asm__ __volatile__ ("sync" : : : "memory") +#endif + static inline int __ilog2(unsigned long bitmask) { int lz; diff --git a/arch/arch-s390.h b/arch/arch-s390.h index ed5d462d..5e131559 100644 --- a/arch/arch-s390.h +++ b/arch/arch-s390.h @@ -14,5 +14,6 @@ #define nop asm volatile ("diag 0,0,68" : : : "memory") #define fio_ffz(v) generic_ffz((v)) +#define read_barrier() asm volatile("bcr 15,0" : : : "memory") #endif diff --git a/arch/arch-x86.h b/arch/arch-x86.h index 7bb8ffb9..343e51ab 100644 --- a/arch/arch-x86.h +++ b/arch/arch-x86.h @@ -29,7 +29,8 @@ #define FIO_HAVE_SYSLET -#define nop __asm__ __volatile__("rep;nop": : :"memory") +#define nop __asm__ __volatile__("rep;nop": : :"memory") +#define read_barrier() asm volatile ("": : :"memory") static inline unsigned long fio_ffz(unsigned long bitmask) { diff --git a/arch/arch-x86_64.h b/arch/arch-x86_64.h index 4f75addc..979c3206 100644 --- a/arch/arch-x86_64.h +++ b/arch/arch-x86_64.h @@ -29,7 +29,8 @@ #define FIO_HAVE_SYSLET -#define nop __asm__ __volatile__("rep;nop": : :"memory") +#define nop __asm__ __volatile__("rep;nop": : :"memory") +#define read_barrier() asm volatile("lfence":::"memory") static inline unsigned long fio_ffz(unsigned long bitmask) { diff --git a/engines/syslet-rw.c b/engines/syslet-rw.c index e3be4859..49bbc712 100644 --- a/engines/syslet-rw.c +++ b/engines/syslet-rw.c @@ -32,6 +32,7 @@ struct syslet_data { unsigned int nr_events; struct syslet_ring *ring; + unsigned int ring_mask; void *stack; }; @@ -46,10 +47,13 @@ static void fio_syslet_add_event(struct thread_data *td, struct io_u *io_u) static void fio_syslet_add_events(struct thread_data *td, unsigned int nr) { struct syslet_data *sd = td->io_ops->data; - unsigned int i; + unsigned int i, uidx; + + uidx = sd->ring->user_tail; + read_barrier(); for (i = 0; i < nr; i++) { - unsigned int idx = (i + sd->ring->user_tail) % td->o.iodepth; + unsigned int idx = (i + uidx) & sd->ring_mask; struct syslet_completion *comp = &sd->ring->comp[idx]; struct io_u *io_u = (struct io_u *) (long) comp->caller_data; long ret; @@ -262,6 +266,7 @@ static int fio_syslet_init(struct thread_data *td) goto err_mem; sd->ring = ring; + sd->ring_mask = ring_nr - 1; sd->stack = stack; memset(sd->ring, 0, ring_size); -- 2.25.1