syslet: add proper read barrier between user_tail and completion read
authorJens Axboe <jens.axboe@oracle.com>
Tue, 11 Dec 2007 07:55:53 +0000 (08:55 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 11 Dec 2007 07:55:53 +0000 (08:55 +0100)
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 <jens.axboe@oracle.com>
arch/arch-alpha.h
arch/arch-ia64.h
arch/arch-ppc.h
arch/arch-s390.h
arch/arch-x86.h
arch/arch-x86_64.h
engines/syslet-rw.c

index b899494..a476891 100644 (file)
@@ -14,5 +14,6 @@
 
 #define nop            do { } while (0)
 #define fio_ffz(v)     generic_ffz((v))
+#define read_barrier() __asm__ __volatile__("mb": : :"memory")
 
 #endif
index 7baccca..3268acc 100644 (file)
@@ -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)                                                 \
 ({                                                                     \
index 0a23c01..9783131 100644 (file)
 
 #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;
index ed5d462..5e13155 100644 (file)
@@ -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
index 7bb8ffb..343e51a 100644 (file)
@@ -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)
 {
index 4f75add..979c320 100644 (file)
@@ -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)
 {
index e3be485..49bbc71 100644 (file)
@@ -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);