The following changes since commit 0b139881150f7179688243c224a07b57eedbdfa0:

  posix_fadvise() returns positive error values (2015-12-03 15:08:08 -0700)

are available in the git repository at:

  git://git.kernel.dk/fio.git master

for you to fetch changes up to a6a3469ea8753a999b9bb9bea33299700d3094eb:

  workqueue: fix potential ABBA deadlock in stats summing (2015-12-04 13:15:36 
-0700)

----------------------------------------------------------------
Jens Axboe (3):
      io_u: make io_u_quiesce() return how many IOs it completed
      workqueue: properly account ->cur_depth
      workqueue: fix potential ABBA deadlock in stats summing

Li Zhong (1):
      powerpc: enable cpu clock for powerpc64

 arch/arch-ppc.h | 24 ++++++++++++++++++++++++
 backend.c       | 30 ++++++++++++++++++++++++++----
 io_u.c          | 10 ++++++++--
 ioengine.h      |  2 +-
 workqueue.c     | 38 +++++++++++++++++++++++++++++---------
 5 files changed, 88 insertions(+), 16 deletions(-)

---

Diff of recent changes:

diff --git a/arch/arch-ppc.h b/arch/arch-ppc.h
index aed41f9..161c39c 100644
--- a/arch/arch-ppc.h
+++ b/arch/arch-ppc.h
@@ -67,6 +67,21 @@ static inline unsigned int mfspr(unsigned int reg)
 #define SPRN_ATBL  0x20E /* Alternate Time Base Lower */
 #define SPRN_ATBU  0x20F /* Alternate Time Base Upper */
 
+#ifdef __powerpc64__
+static inline unsigned long long get_cpu_clock(void)
+{
+       unsigned long long rval;
+
+       asm volatile(
+               "90:    mfspr %0, %1;\n"
+               "       cmpwi %0,0;\n"
+               "       beq-  90b;\n"
+       : "=r" (rval)
+       : "i" (SPRN_TBRL));
+
+       return rval;
+}
+#else
 static inline unsigned long long get_cpu_clock(void)
 {
        unsigned int tbl, tbu0, tbu1;
@@ -87,6 +102,7 @@ static inline unsigned long long get_cpu_clock(void)
        ret = (((unsigned long long)tbu0) << 32) | tbl;
        return ret;
 }
+#endif
 
 #if 0
 static void atb_child(void)
@@ -136,4 +152,12 @@ static inline int arch_init(char *envp[])
  * #define ARCH_HAVE_CPU_CLOCK
  */
 
+/*
+ * Let's have it defined for ppc64
+ */
+
+#ifdef __powerpc64__
+#define ARCH_HAVE_CPU_CLOCK
+#endif
+
 #endif
diff --git a/backend.c b/backend.c
index 4a689eb..10622ef 100644
--- a/backend.c
+++ b/backend.c
@@ -1358,16 +1358,38 @@ static void io_workqueue_fn(struct thread_data *td, 
struct io_u *io_u)
 
        td->cur_depth++;
 
-       ret = td_io_queue(td, io_u);
+       do {
+               ret = td_io_queue(td, io_u);
+               if (ret != FIO_Q_BUSY)
+                       break;
+               ret = io_u_queued_complete(td, 1);
+               if (ret > 0)
+                       td->cur_depth -= ret;
+               io_u_clear(io_u, IO_U_F_FLIGHT);
+       } while (1);
 
        dprint(FD_RATE, "io_u %p ret %d by %u\n", io_u, ret, gettid());
 
        io_queue_event(td, io_u, &ret, ddir, NULL, 0, NULL);
 
-       if (ret == FIO_Q_QUEUED)
-               ret = io_u_queued_complete(td, 1);
+       if (ret == FIO_Q_COMPLETED)
+               td->cur_depth--;
+       else if (ret == FIO_Q_QUEUED) {
+               unsigned int min_evts;
 
-       td->cur_depth--;
+               if (td->o.iodepth == 1)
+                       min_evts = 1;
+               else
+                       min_evts = 0;
+
+               ret = io_u_queued_complete(td, min_evts);
+               if (ret > 0)
+                       td->cur_depth -= ret;
+       } else if (ret == FIO_Q_BUSY) {
+               ret = io_u_queued_complete(td, td->cur_depth);
+               if (ret > 0)
+                       td->cur_depth -= ret;
+       }
 }
 
 /*
diff --git a/io_u.c b/io_u.c
index d45a6f0..f86367b 100644
--- a/io_u.c
+++ b/io_u.c
@@ -542,8 +542,10 @@ static inline enum fio_ddir get_rand_ddir(struct 
thread_data *td)
        return DDIR_WRITE;
 }
 
-void io_u_quiesce(struct thread_data *td)
+int io_u_quiesce(struct thread_data *td)
 {
+       int completed = 0;
+
        /*
         * We are going to sleep, ensure that we flush anything pending as
         * not to skew our latency numbers.
@@ -563,7 +565,11 @@ void io_u_quiesce(struct thread_data *td)
                int fio_unused ret;
 
                ret = io_u_queued_complete(td, 1);
+               if (ret > 0)
+                       completed += ret;
        }
+
+       return completed;
 }
 
 static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
@@ -1856,7 +1862,7 @@ int io_u_queued_complete(struct thread_data *td, int 
min_evts)
        for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++)
                td->bytes_done[ddir] += icd.bytes_done[ddir];
 
-       return 0;
+       return ret;
 }
 
 /*
diff --git a/ioengine.h b/ioengine.h
index c557f7a..37f0336 100644
--- a/ioengine.h
+++ b/ioengine.h
@@ -214,7 +214,7 @@ extern void requeue_io_u(struct thread_data *, struct io_u 
**);
 extern int __must_check io_u_sync_complete(struct thread_data *, struct io_u 
*);
 extern int __must_check io_u_queued_complete(struct thread_data *, int);
 extern void io_u_queued(struct thread_data *, struct io_u *);
-extern void io_u_quiesce(struct thread_data *);
+extern int io_u_quiesce(struct thread_data *);
 extern void io_u_log_error(struct thread_data *, struct io_u *);
 extern void io_u_mark_depth(struct thread_data *, unsigned int);
 extern void fill_io_buffer(struct thread_data *, void *, unsigned int, 
unsigned int);
diff --git a/workqueue.c b/workqueue.c
index 3442375..7cd83bf 100644
--- a/workqueue.c
+++ b/workqueue.c
@@ -217,13 +217,32 @@ static void sum_val(uint64_t *dst, uint64_t *src)
 }
 #endif
 
-static void sum_ddir(struct thread_data *dst, struct thread_data *src,
-                    enum fio_ddir ddir)
+static void pthread_double_unlock(pthread_mutex_t *lock1,
+                                 pthread_mutex_t *lock2)
+{
+#ifndef CONFIG_SFAA
+       pthread_mutex_unlock(lock1);
+       pthread_mutex_unlock(lock2);
+#endif
+}
+
+static void pthread_double_lock(pthread_mutex_t *lock1, pthread_mutex_t *lock2)
 {
 #ifndef CONFIG_SFAA
-       pthread_mutex_lock(&dst->io_wq.stat_lock);
-       pthread_mutex_lock(&src->io_wq.stat_lock);
+       if (lock1 < lock2) {
+               pthread_mutex_lock(lock1);
+               pthread_mutex_lock(lock2);
+       } else {
+               pthread_mutex_lock(lock2);
+               pthread_mutex_lock(lock1);
+       }
 #endif
+}
+
+static void sum_ddir(struct thread_data *dst, struct thread_data *src,
+                    enum fio_ddir ddir)
+{
+       pthread_double_lock(&dst->io_wq.stat_lock, &src->io_wq.stat_lock);
 
        sum_val(&dst->io_bytes[ddir], &src->io_bytes[ddir]);
        sum_val(&dst->io_blocks[ddir], &src->io_blocks[ddir]);
@@ -231,10 +250,7 @@ static void sum_ddir(struct thread_data *dst, struct 
thread_data *src,
        sum_val(&dst->this_io_bytes[ddir], &src->this_io_bytes[ddir]);
        sum_val(&dst->bytes_done[ddir], &src->bytes_done[ddir]);
 
-#ifndef CONFIG_SFAA
-       pthread_mutex_unlock(&src->io_wq.stat_lock);
-       pthread_mutex_unlock(&dst->io_wq.stat_lock);
-#endif
+       pthread_double_unlock(&dst->io_wq.stat_lock, &src->io_wq.stat_lock);
 }
 
 static void update_accounting(struct submit_worker *sw)
@@ -283,8 +299,12 @@ static void *worker_thread(void *data)
 
                        if (td->io_u_queued || td->cur_depth ||
                            td->io_u_in_flight) {
+                               int ret;
+
                                pthread_mutex_unlock(&sw->lock);
-                               io_u_quiesce(td);
+                               ret = io_u_quiesce(td);
+                               if (ret > 0)
+                                       td->cur_depth -= ret;
                                pthread_mutex_lock(&sw->lock);
                        }
 
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to