21ab4e
From 0a3577c161bc1e23c8d4f4a70dff4c1cc5a2c363 Mon Sep 17 00:00:00 2001
21ab4e
From: Niels de Vos <ndevos@redhat.com>
21ab4e
Date: Thu, 6 Apr 2017 15:11:00 +0200
21ab4e
Subject: [PATCH 615/616] io-stats: use gf_atomic_t instead of partial atomic
21ab4e
 variables
21ab4e
21ab4e
io-stats should not use the legacy __sync_*() builtin functions for
21ab4e
doing atomic operations. Instead, it should use the gf_atomic_t type and
21ab4e
macros for any of the statistics it calculates. This makes sure that the
21ab4e
behaviour is the same on all architectures.
21ab4e
21ab4e
Also the __sync_*() builtins are being deprecated with __atomic_*()
21ab4e
functions. The "atomic.h" header will be one of the very few places
21ab4e
where these builtin functions are used and the feature checking will be
21ab4e
needed.
21ab4e
21ab4e
While replacing many of the uint64_t types, it seemed that locking
21ab4e
around some of the statements is not needed anymore (done automatically
21ab4e
with the GF_ATOMIC_*() macros). This resulted in quite some removal and
21ab4e
cleanup of those BUMP_*() macros. It seemed appropriate to make these
21ab4e
macros normal functions and let the compiler decide on inlining them.
21ab4e
This caused some existing functions to be shuffled around.
21ab4e
21ab4e
>Reviewed-on: https://review.gluster.org/17009
21ab4e
>URL: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
21ab4e
>Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
21ab4e
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
>Reviewed-by: Amar Tumballi <amarts@redhat.com>
21ab4e
>Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
21ab4e
21ab4e
Change-Id: I7c4f3df1832eae51debda2b127b943e14546b605
21ab4e
BUG: 1475721
21ab4e
Signed-off-by: Niels de Vos <ndevos@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/117185
21ab4e
Tested-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 xlators/debug/io-stats/src/io-stats.c | 747 ++++++++++++++++++----------------
21ab4e
 1 file changed, 392 insertions(+), 355 deletions(-)
21ab4e
21ab4e
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c
21ab4e
index 46e1272..92f05e5 100644
21ab4e
--- a/xlators/debug/io-stats/src/io-stats.c
21ab4e
+++ b/xlators/debug/io-stats/src/io-stats.c
21ab4e
@@ -42,6 +42,7 @@
21ab4e
 #define MAX_LIST_MEMBERS 100
21ab4e
 #define DEFAULT_PWD_BUF_SZ 16384
21ab4e
 #define DEFAULT_GRP_BUF_SZ 16384
21ab4e
+#define IOS_BLOCK_COUNT_SIZE 32
21ab4e
 
21ab4e
 typedef enum {
21ab4e
         IOS_STATS_TYPE_NONE,
21ab4e
@@ -70,7 +71,7 @@ struct ios_stat {
21ab4e
         gf_lock_t       lock;
21ab4e
         uuid_t          gfid;
21ab4e
         char           *filename;
21ab4e
-        uint64_t        counters [IOS_STATS_TYPE_MAX];
21ab4e
+        gf_atomic_t     counters[IOS_STATS_TYPE_MAX];
21ab4e
         struct ios_stat_lat thru_counters [IOS_STATS_THRU_MAX];
21ab4e
         int             refcnt;
21ab4e
 };
21ab4e
@@ -115,12 +116,12 @@ struct ios_lat {
21ab4e
 };
21ab4e
 
21ab4e
 struct ios_global_stats {
21ab4e
-        uint64_t        data_written;
21ab4e
-        uint64_t        data_read;
21ab4e
-        uint64_t        block_count_write[32];
21ab4e
-        uint64_t        block_count_read[32];
21ab4e
-        uint64_t        fop_hits[GF_FOP_MAXVALUE];
21ab4e
-        uint64_t        upcall_hits[GF_UPCALL_FLAGS_MAXVALUE];
21ab4e
+        gf_atomic_t     data_written;
21ab4e
+        gf_atomic_t     data_read;
21ab4e
+        gf_atomic_t     block_count_write[IOS_BLOCK_COUNT_SIZE];
21ab4e
+        gf_atomic_t     block_count_read[IOS_BLOCK_COUNT_SIZE];
21ab4e
+        gf_atomic_t     fop_hits[GF_FOP_MAXVALUE];
21ab4e
+        gf_atomic_t     upcall_hits[GF_UPCALL_FLAGS_MAXVALUE];
21ab4e
         struct timeval  started_at;
21ab4e
         struct ios_lat  latency[GF_FOP_MAXVALUE];
21ab4e
         uint64_t        nr_opens;
21ab4e
@@ -164,10 +165,10 @@ struct ios_conf {
21ab4e
 
21ab4e
 struct ios_fd {
21ab4e
         char           *filename;
21ab4e
-        uint64_t        data_written;
21ab4e
-        uint64_t        data_read;
21ab4e
-        uint64_t        block_count_write[32];
21ab4e
-        uint64_t        block_count_read[32];
21ab4e
+        gf_atomic_t     data_written;
21ab4e
+        gf_atomic_t     data_read;
21ab4e
+        gf_atomic_t     block_count_write[IOS_BLOCK_COUNT_SIZE];
21ab4e
+        gf_atomic_t     block_count_read[IOS_BLOCK_COUNT_SIZE];
21ab4e
         struct timeval  opened_at;
21ab4e
 };
21ab4e
 
21ab4e
@@ -244,26 +245,10 @@ is_fop_latency_started (call_frame_t *frame)
21ab4e
                 conf = this->private;                                   \
21ab4e
                 if (!conf)                                              \
21ab4e
                         break;                                          \
21ab4e
-                conf->cumulative.fop_hits[GF_FOP_##op]++;               \
21ab4e
-                conf->incremental.fop_hits[GF_FOP_##op]++;              \
21ab4e
+                GF_ATOMIC_INC (conf->cumulative.fop_hits[GF_FOP_##op]); \
21ab4e
+                GF_ATOMIC_INC (conf->incremental.fop_hits[GF_FOP_##op]);\
21ab4e
         } while (0)
21ab4e
 
21ab4e
-#if defined(HAVE_SYNC_BUILTINS)
21ab4e
-/* FIXME: use gf_atomic_t from libglusterfs/src/atomic.h
21ab4e
- *
21ab4e
- * This is currently not behaving correctly. Values are going out of sync in
21ab4e
- * the case where HAVE_SYNC_BUILTINS are available, but are updated under a
21ab4e
- * single lock for other cases.
21ab4e
- */
21ab4e
-#define STATS_LOCK(x)
21ab4e
-#define STATS_UNLOCK(x)
21ab4e
-#define STATS_ADD(x,i)  __sync_add_and_fetch (&x, i)
21ab4e
-#else
21ab4e
-#define STATS_LOCK(x)   LOCK (x)
21ab4e
-#define STATS_UNLOCK(x) UNLOCK (x)
21ab4e
-#define STATS_ADD(x,i)  (x) += (i)
21ab4e
-#endif
21ab4e
-
21ab4e
 #define UPDATE_PROFILE_STATS(frame, op)                                       \
21ab4e
         do {                                                                  \
21ab4e
                 struct ios_conf  *conf = NULL;                                \
21ab4e
@@ -271,85 +256,12 @@ is_fop_latency_started (call_frame_t *frame)
21ab4e
                 if (!is_fop_latency_started (frame))                          \
21ab4e
                         break;                                                \
21ab4e
                 conf = this->private;                                         \
21ab4e
-                STATS_LOCK (&conf->lock);                                     \
21ab4e
-                {                                                             \
21ab4e
-                        if (conf && conf->measure_latency &&                  \
21ab4e
-                            conf->count_fop_hits) {                           \
21ab4e
-                                BUMP_FOP(op);                                 \
21ab4e
-                                gettimeofday (&frame->end, NULL);             \
21ab4e
-                                update_ios_latency (conf, frame, GF_FOP_##op);\
21ab4e
-                        }                                                     \
21ab4e
+                if (conf && conf->measure_latency &&                          \
21ab4e
+                    conf->count_fop_hits) {                                   \
21ab4e
+                        BUMP_FOP (op);                                        \
21ab4e
+                        gettimeofday (&frame->end, NULL);                     \
21ab4e
+                        update_ios_latency (conf, frame, GF_FOP_##op);        \
21ab4e
                 }                                                             \
21ab4e
-                STATS_UNLOCK (&conf->lock);                                   \
21ab4e
-        } while (0)
21ab4e
-
21ab4e
-#define BUMP_READ(fd, len)                                                     \
21ab4e
-        do {                                                                   \
21ab4e
-                struct ios_conf  *conf = NULL;                                 \
21ab4e
-                struct ios_fd    *iosfd = NULL;                                \
21ab4e
-                int               lb2 = 0;                                     \
21ab4e
-                                                                               \
21ab4e
-                conf = this->private;                                          \
21ab4e
-                lb2 = log_base2 (len);                                         \
21ab4e
-                ios_fd_ctx_get (fd, this, &iosfd);                             \
21ab4e
-                if (!conf)                                                     \
21ab4e
-                        break;                                                 \
21ab4e
-                                                                               \
21ab4e
-                STATS_LOCK (&conf->lock);                                      \
21ab4e
-                {                                                              \
21ab4e
-                        STATS_ADD (conf->cumulative.data_read, len);           \
21ab4e
-                        STATS_ADD (conf->incremental.data_read, len);          \
21ab4e
-                        STATS_ADD (conf->cumulative.block_count_read[lb2], 1); \
21ab4e
-                        STATS_ADD (conf->incremental.block_count_read[lb2], 1);\
21ab4e
-                                                                               \
21ab4e
-                        if (iosfd) {                                           \
21ab4e
-                                STATS_ADD (iosfd->data_read, len);             \
21ab4e
-                                STATS_ADD (iosfd->block_count_read[lb2], 1);   \
21ab4e
-                        }                                                      \
21ab4e
-                }                                                              \
21ab4e
-                STATS_UNLOCK (&conf->lock);                                    \
21ab4e
-        } while (0)
21ab4e
-
21ab4e
-#define BUMP_WRITE(fd, len)                                                    \
21ab4e
-        do {                                                                   \
21ab4e
-                struct ios_conf  *conf = NULL;                                 \
21ab4e
-                struct ios_fd    *iosfd = NULL;                                \
21ab4e
-                int               lb2 = 0;                                     \
21ab4e
-                                                                               \
21ab4e
-                conf = this->private;                                          \
21ab4e
-                lb2 = log_base2 (len);                                         \
21ab4e
-                ios_fd_ctx_get (fd, this, &iosfd);                             \
21ab4e
-                if (!conf)                                                     \
21ab4e
-                        break;                                                 \
21ab4e
-                STATS_LOCK (&conf->lock);                                      \
21ab4e
-                {                                                              \
21ab4e
-                        STATS_ADD (conf->cumulative.data_written, len);        \
21ab4e
-                        STATS_ADD (conf->incremental.data_written, len);       \
21ab4e
-                        STATS_ADD (conf->cumulative.block_count_write[lb2], 1);\
21ab4e
-                        STATS_ADD (conf->incremental.block_count_write[lb2], 1);\
21ab4e
-                                                                               \
21ab4e
-                        if (iosfd) {                                           \
21ab4e
-                                STATS_ADD (iosfd->data_written, len);          \
21ab4e
-                                STATS_ADD (iosfd->block_count_write[lb2], 1);  \
21ab4e
-                        }                                                      \
21ab4e
-                }                                                              \
21ab4e
-                STATS_UNLOCK (&conf->lock);                                    \
21ab4e
-        } while (0)
21ab4e
-
21ab4e
-#define BUMP_STATS(iosstat, type)                                       \
21ab4e
-        do {                                                            \
21ab4e
-                struct ios_conf         *conf = NULL;                   \
21ab4e
-                uint64_t                 value = 0;                     \
21ab4e
-                                                                        \
21ab4e
-                conf = this->private;                                   \
21ab4e
-                                                                        \
21ab4e
-                LOCK(&iosstat->lock);                                   \
21ab4e
-                {                                                       \
21ab4e
-                        value = STATS_ADD (iosstat->counters[type], 1); \
21ab4e
-                }                                                       \
21ab4e
-                UNLOCK (&iosstat->lock);                                \
21ab4e
-                ios_stat_add_to_list (&conf->list[type],                \
21ab4e
-                                     value, iosstat);                   \
21ab4e
         } while (0)
21ab4e
 
21ab4e
 #define BUMP_THROUGHPUT(iosstat, type)                                         \
21ab4e
@@ -368,7 +280,7 @@ is_fop_latency_started (call_frame_t *frame)
21ab4e
                 throughput = op_ret / elapsed;                                 \
21ab4e
                                                                                \
21ab4e
                 conf = this->private;                                          \
21ab4e
-                STATS_LOCK (&iosstat->lock);                                   \
21ab4e
+                LOCK (&iosstat->lock);                                         \
21ab4e
                 {                                                              \
21ab4e
                         if (iosstat->thru_counters[type].throughput            \
21ab4e
                                 <= throughput) {                               \
21ab4e
@@ -379,26 +291,14 @@ is_fop_latency_started (call_frame_t *frame)
21ab4e
                                flag = 1;                                       \
21ab4e
                         }                                                      \
21ab4e
                 }                                                              \
21ab4e
-                STATS_UNLOCK (&iosstat->lock);                                 \
21ab4e
+                UNLOCK (&iosstat->lock);                                       \
21ab4e
                 if (flag)                                                      \
21ab4e
                        ios_stat_add_to_list (&conf->thru_list[type],           \
21ab4e
                                                throughput, iosstat);           \
21ab4e
         } while (0)
21ab4e
 
21ab4e
-#define BUMP_UPCALL(event)                                                     \
21ab4e
-        do {                                                                   \
21ab4e
-                struct ios_conf  *conf = NULL;                                 \
21ab4e
-                                                                               \
21ab4e
-                conf = this->private;                                          \
21ab4e
-                if (!conf)                                                     \
21ab4e
-                        break;                                                 \
21ab4e
-                if (conf->count_fop_hits) {                                    \
21ab4e
-                        conf->cumulative.upcall_hits[event]++;                 \
21ab4e
-                        conf->incremental.upcall_hits[event]++;                \
21ab4e
-                }                                                              \
21ab4e
-        } while (0)
21ab4e
 
21ab4e
-int
21ab4e
+static int
21ab4e
 ios_fd_ctx_get (fd_t *fd, xlator_t *this, struct ios_fd **iosfd)
21ab4e
 {
21ab4e
         uint64_t      iosfd64 = 0;
21ab4e
@@ -414,8 +314,7 @@ ios_fd_ctx_get (fd_t *fd, xlator_t *this, struct ios_fd **iosfd)
21ab4e
 }
21ab4e
 
21ab4e
 
21ab4e
-
21ab4e
-int
21ab4e
+static int
21ab4e
 ios_fd_ctx_set (fd_t *fd, xlator_t *this, struct ios_fd *iosfd)
21ab4e
 {
21ab4e
         uint64_t   iosfd64 = 0;
21ab4e
@@ -427,7 +326,8 @@ ios_fd_ctx_set (fd_t *fd, xlator_t *this, struct ios_fd *iosfd)
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
-int
21ab4e
+
21ab4e
+static int
21ab4e
 ios_stat_ref (struct ios_stat *iosstat)
21ab4e
 {
21ab4e
         LOCK (&iosstat->lock);
21ab4e
@@ -439,7 +339,8 @@ ios_stat_ref (struct ios_stat *iosstat)
21ab4e
         return iosstat->refcnt;
21ab4e
 }
21ab4e
 
21ab4e
-int
21ab4e
+
21ab4e
+static int
21ab4e
 ios_stat_unref (struct ios_stat *iosstat)
21ab4e
 {
21ab4e
         int cleanup = 0;
21ab4e
@@ -465,101 +366,8 @@ ios_stat_unref (struct ios_stat *iosstat)
21ab4e
         return 0;
21ab4e
 }
21ab4e
 
21ab4e
-int
21ab4e
-ios_inode_ctx_set (inode_t *inode, xlator_t *this, struct ios_stat *iosstat)
21ab4e
-{
21ab4e
-        uint64_t   iosstat64 = 0;
21ab4e
-        int        ret     = 0;
21ab4e
-
21ab4e
-        ios_stat_ref (iosstat);
21ab4e
-        iosstat64 = (unsigned long )iosstat;
21ab4e
-        ret = inode_ctx_put (inode, this, iosstat64);
21ab4e
-        return ret;
21ab4e
-}
21ab4e
-
21ab4e
-int
21ab4e
-ios_inode_ctx_get (inode_t *inode, xlator_t *this, struct ios_stat **iosstat)
21ab4e
-{
21ab4e
-        uint64_t      iosstat64 = 0;
21ab4e
-        unsigned long iosstatlong = 0;
21ab4e
-        int           ret = 0;
21ab4e
-
21ab4e
-        ret = inode_ctx_get (inode, this, &iosstat64);
21ab4e
-        iosstatlong = iosstat64;
21ab4e
-        if (ret != -1)
21ab4e
-                *iosstat = (void *) iosstatlong;
21ab4e
-
21ab4e
-        return ret;
21ab4e
-
21ab4e
-}
21ab4e
-
21ab4e
-/*
21ab4e
- * So why goto all this trouble?  Why not just queue up some samples in
21ab4e
- * a big list and malloc away?  Well malloc is expensive relative
21ab4e
- * to what we are measuring, so cannot have any malloc's (or worse
21ab4e
- * callocs) in our measurement code paths.  Instead, we are going to
21ab4e
- * pre-allocate a circular buffer and collect a maximum number of samples.
21ab4e
- * Prior to dumping them all we'll create a new buffer and swap the
21ab4e
- * old buffer with the new, and then proceed to dump the statistics
21ab4e
- * in our dump thread.
21ab4e
- *
21ab4e
- */
21ab4e
-ios_sample_buf_t *
21ab4e
-ios_create_sample_buf (size_t buf_size)
21ab4e
-{
21ab4e
-        ios_sample_buf_t *ios_sample_buf = NULL;
21ab4e
-        ios_sample_t     *ios_samples = NULL;
21ab4e
-
21ab4e
-        ios_sample_buf = GF_CALLOC (1,
21ab4e
-                sizeof (*ios_sample_buf),
21ab4e
-                gf_io_stats_mt_ios_sample_buf);
21ab4e
-        if (!ios_sample_buf)
21ab4e
-                goto err;
21ab4e
-
21ab4e
-        ios_samples = GF_CALLOC (buf_size,
21ab4e
-                sizeof (*ios_samples),
21ab4e
-                gf_io_stats_mt_ios_sample);
21ab4e
-
21ab4e
-        if (!ios_samples)
21ab4e
-                goto err;
21ab4e
-
21ab4e
-        ios_sample_buf->ios_samples = ios_samples;
21ab4e
-        ios_sample_buf->size = buf_size;
21ab4e
-        ios_sample_buf->pos = 0;
21ab4e
-        ios_sample_buf->observed = 0;
21ab4e
-        ios_sample_buf->collected = 0;
21ab4e
-
21ab4e
-        return ios_sample_buf;
21ab4e
-err:
21ab4e
-        GF_FREE (ios_sample_buf);
21ab4e
-        return NULL;
21ab4e
-}
21ab4e
-
21ab4e
-void
21ab4e
-ios_destroy_sample_buf (ios_sample_buf_t *ios_sample_buf)
21ab4e
-{
21ab4e
-        GF_FREE (ios_sample_buf->ios_samples);
21ab4e
-        GF_FREE (ios_sample_buf);
21ab4e
-}
21ab4e
 
21ab4e
 static int
21ab4e
-ios_init_sample_buf (struct ios_conf *conf)
21ab4e
-{
21ab4e
-        int32_t        ret = -1;
21ab4e
-
21ab4e
-        GF_ASSERT (conf);
21ab4e
-        LOCK (&conf->lock);
21ab4e
-        conf->ios_sample_buf = ios_create_sample_buf (
21ab4e
-                conf->ios_sample_buf_size);
21ab4e
-        if (!conf->ios_sample_buf)
21ab4e
-                goto out;
21ab4e
-        ret = 0;
21ab4e
-out:
21ab4e
-        UNLOCK (&conf->lock);
21ab4e
-        return ret;
21ab4e
-}
21ab4e
-
21ab4e
-int
21ab4e
 ios_stat_add_to_list (struct ios_stat_head *list_head, uint64_t value,
21ab4e
                             struct ios_stat *iosstat)
21ab4e
 {
21ab4e
@@ -654,6 +462,180 @@ out:
21ab4e
         return 0;
21ab4e
 }
21ab4e
 
21ab4e
+
21ab4e
+static void
21ab4e
+ios_bump_read (xlator_t *this, fd_t *fd, size_t len)
21ab4e
+{
21ab4e
+        struct ios_conf  *conf = NULL;
21ab4e
+        struct ios_fd    *iosfd = NULL;
21ab4e
+        int               lb2 = 0;
21ab4e
+
21ab4e
+        conf = this->private;
21ab4e
+        lb2 = log_base2 (len);
21ab4e
+        ios_fd_ctx_get (fd, this, &iosfd);
21ab4e
+        if (!conf)
21ab4e
+                return;
21ab4e
+
21ab4e
+        GF_ATOMIC_ADD (conf->cumulative.data_read, len);
21ab4e
+        GF_ATOMIC_ADD (conf->incremental.data_read, len);
21ab4e
+        GF_ATOMIC_INC (conf->cumulative.block_count_read[lb2]);
21ab4e
+        GF_ATOMIC_INC (conf->incremental.block_count_read[lb2]);
21ab4e
+
21ab4e
+        if (iosfd) {
21ab4e
+                GF_ATOMIC_ADD (iosfd->data_read, len);
21ab4e
+                GF_ATOMIC_INC (iosfd->block_count_read[lb2]);
21ab4e
+        }
21ab4e
+}
21ab4e
+
21ab4e
+
21ab4e
+static void
21ab4e
+ios_bump_write (xlator_t *this, fd_t *fd, size_t len)
21ab4e
+{
21ab4e
+        struct ios_conf  *conf = NULL;
21ab4e
+        struct ios_fd    *iosfd = NULL;
21ab4e
+        int               lb2 = 0;
21ab4e
+
21ab4e
+        conf = this->private;
21ab4e
+        lb2 = log_base2 (len);
21ab4e
+        ios_fd_ctx_get (fd, this, &iosfd);
21ab4e
+        if (!conf)
21ab4e
+                return;
21ab4e
+
21ab4e
+        GF_ATOMIC_ADD (conf->cumulative.data_written, len);
21ab4e
+        GF_ATOMIC_ADD (conf->incremental.data_written, len);
21ab4e
+        GF_ATOMIC_INC (conf->cumulative.block_count_write[lb2]);
21ab4e
+        GF_ATOMIC_INC (conf->incremental.block_count_write[lb2]);
21ab4e
+
21ab4e
+        if (iosfd) {
21ab4e
+                GF_ATOMIC_ADD (iosfd->data_written, len);
21ab4e
+                GF_ATOMIC_INC (iosfd->block_count_write[lb2]);
21ab4e
+        }
21ab4e
+}
21ab4e
+
21ab4e
+
21ab4e
+static void
21ab4e
+ios_bump_upcall (xlator_t *this, gf_upcall_flags_t event)
21ab4e
+{
21ab4e
+        struct ios_conf  *conf = NULL;
21ab4e
+
21ab4e
+        conf = this->private;
21ab4e
+        if (!conf)
21ab4e
+                return;
21ab4e
+        if (conf->count_fop_hits) {
21ab4e
+                GF_ATOMIC_INC (conf->cumulative.upcall_hits[event]);
21ab4e
+                GF_ATOMIC_INC (conf->incremental.upcall_hits[event]);
21ab4e
+        }
21ab4e
+}
21ab4e
+
21ab4e
+
21ab4e
+static void
21ab4e
+ios_bump_stats (xlator_t *this, struct ios_stat *iosstat,
21ab4e
+                ios_stats_type_t type)
21ab4e
+{
21ab4e
+        struct ios_conf         *conf = NULL;
21ab4e
+        uint64_t                 value = 0;
21ab4e
+
21ab4e
+        conf = this->private;
21ab4e
+
21ab4e
+        value = GF_ATOMIC_INC (iosstat->counters[type]);
21ab4e
+        ios_stat_add_to_list (&conf->list[type], value, iosstat);
21ab4e
+}
21ab4e
+
21ab4e
+
21ab4e
+int
21ab4e
+ios_inode_ctx_set (inode_t *inode, xlator_t *this, struct ios_stat *iosstat)
21ab4e
+{
21ab4e
+        uint64_t   iosstat64 = 0;
21ab4e
+        int        ret     = 0;
21ab4e
+
21ab4e
+        ios_stat_ref (iosstat);
21ab4e
+        iosstat64 = (unsigned long) iosstat;
21ab4e
+        ret = inode_ctx_put (inode, this, iosstat64);
21ab4e
+        return ret;
21ab4e
+}
21ab4e
+
21ab4e
+int
21ab4e
+ios_inode_ctx_get (inode_t *inode, xlator_t *this, struct ios_stat **iosstat)
21ab4e
+{
21ab4e
+        uint64_t      iosstat64 = 0;
21ab4e
+        unsigned long iosstatlong = 0;
21ab4e
+        int           ret = 0;
21ab4e
+
21ab4e
+        ret = inode_ctx_get (inode, this, &iosstat64);
21ab4e
+        iosstatlong = iosstat64;
21ab4e
+        if (ret != -1)
21ab4e
+                *iosstat = (void *) iosstatlong;
21ab4e
+
21ab4e
+        return ret;
21ab4e
+
21ab4e
+}
21ab4e
+
21ab4e
+/*
21ab4e
+ * So why goto all this trouble?  Why not just queue up some samples in
21ab4e
+ * a big list and malloc away?  Well malloc is expensive relative
21ab4e
+ * to what we are measuring, so cannot have any malloc's (or worse
21ab4e
+ * callocs) in our measurement code paths.  Instead, we are going to
21ab4e
+ * pre-allocate a circular buffer and collect a maximum number of samples.
21ab4e
+ * Prior to dumping them all we'll create a new buffer and swap the
21ab4e
+ * old buffer with the new, and then proceed to dump the statistics
21ab4e
+ * in our dump thread.
21ab4e
+ *
21ab4e
+ */
21ab4e
+ios_sample_buf_t *
21ab4e
+ios_create_sample_buf (size_t buf_size)
21ab4e
+{
21ab4e
+        ios_sample_buf_t *ios_sample_buf = NULL;
21ab4e
+        ios_sample_t     *ios_samples = NULL;
21ab4e
+
21ab4e
+        ios_sample_buf = GF_CALLOC (1,
21ab4e
+                sizeof (*ios_sample_buf),
21ab4e
+                gf_io_stats_mt_ios_sample_buf);
21ab4e
+        if (!ios_sample_buf)
21ab4e
+                goto err;
21ab4e
+
21ab4e
+        ios_samples = GF_CALLOC (buf_size,
21ab4e
+                sizeof (*ios_samples),
21ab4e
+                gf_io_stats_mt_ios_sample);
21ab4e
+
21ab4e
+        if (!ios_samples)
21ab4e
+                goto err;
21ab4e
+
21ab4e
+        ios_sample_buf->ios_samples = ios_samples;
21ab4e
+        ios_sample_buf->size = buf_size;
21ab4e
+        ios_sample_buf->pos = 0;
21ab4e
+        ios_sample_buf->observed = 0;
21ab4e
+        ios_sample_buf->collected = 0;
21ab4e
+
21ab4e
+        return ios_sample_buf;
21ab4e
+err:
21ab4e
+        GF_FREE (ios_sample_buf);
21ab4e
+        return NULL;
21ab4e
+}
21ab4e
+
21ab4e
+void
21ab4e
+ios_destroy_sample_buf (ios_sample_buf_t *ios_sample_buf)
21ab4e
+{
21ab4e
+        GF_FREE (ios_sample_buf->ios_samples);
21ab4e
+        GF_FREE (ios_sample_buf);
21ab4e
+}
21ab4e
+
21ab4e
+static int
21ab4e
+ios_init_sample_buf (struct ios_conf *conf)
21ab4e
+{
21ab4e
+        int32_t        ret = -1;
21ab4e
+
21ab4e
+        GF_ASSERT (conf);
21ab4e
+        LOCK (&conf->lock);
21ab4e
+        conf->ios_sample_buf = ios_create_sample_buf (
21ab4e
+                conf->ios_sample_buf_size);
21ab4e
+        if (!conf->ios_sample_buf)
21ab4e
+                goto out;
21ab4e
+        ret = 0;
21ab4e
+out:
21ab4e
+        UNLOCK (&conf->lock);
21ab4e
+        return ret;
21ab4e
+}
21ab4e
+
21ab4e
 static int
21ab4e
 ios_stats_cleanup (xlator_t *this, inode_t *inode)
21ab4e
 {
21ab4e
@@ -808,7 +790,7 @@ io_stats_dump_global_to_json_logfp (xlator_t *this,
21ab4e
         int                   ret = 1;  /* Default to error */
21ab4e
         int                   rw_size;
21ab4e
         char                  *rw_unit = NULL;
21ab4e
-        long                  fop_hits;
21ab4e
+        uint64_t              fop_hits;
21ab4e
         float                 fop_lat_ave;
21ab4e
         float                 fop_lat_min;
21ab4e
         float                 fop_lat_max;
21ab4e
@@ -847,24 +829,26 @@ io_stats_dump_global_to_json_logfp (xlator_t *this,
21ab4e
 
21ab4e
                 if (interval == -1) {
21ab4e
                         ios_log (this, logfp,
21ab4e
-                                "\"%s.%s.read_%d%s\": \"%"PRId64"\",",
21ab4e
+                                "\"%s.%s.read_%d%s\": \"%"GF_PRI_ATOMIC"\",",
21ab4e
                                 key_prefix, str_prefix, rw_size, rw_unit,
21ab4e
-                                stats->block_count_read[i]);
21ab4e
+                                GF_ATOMIC_GET (stats->block_count_read[i]));
21ab4e
                         ios_log (this, logfp,
21ab4e
-                                "\"%s.%s.write_%d%s\": \"%"PRId64"\",",
21ab4e
+                                "\"%s.%s.write_%d%s\": \"%"GF_PRI_ATOMIC"\",",
21ab4e
                                 key_prefix, str_prefix, rw_size, rw_unit,
21ab4e
-                                stats->block_count_write[i]);
21ab4e
+                                GF_ATOMIC_GET (stats->block_count_write[i]));
21ab4e
                 } else {
21ab4e
                         ios_log (this, logfp,
21ab4e
                                 "\"%s.%s.read_%d%s_per_sec\": \"%0.2lf\",",
21ab4e
                                 key_prefix, str_prefix, rw_size, rw_unit,
21ab4e
-                                (double)(stats->block_count_read[i] /
21ab4e
-                                        interval_sec));
21ab4e
+                                (double)
21ab4e
+                                (GF_ATOMIC_GET (stats->block_count_read[i]) /
21ab4e
+                                 interval_sec));
21ab4e
                         ios_log (this, logfp,
21ab4e
                                 "\"%s.%s.write_%d%s_per_sec\": \"%0.2lf\",",
21ab4e
                                 key_prefix, str_prefix, rw_size, rw_unit,
21ab4e
-                                (double)(stats->block_count_write[i] /
21ab4e
-                                        interval_sec));
21ab4e
+                                (double)
21ab4e
+                                (GF_ATOMIC_GET (stats->block_count_write[i]) /
21ab4e
+                                 interval_sec));
21ab4e
                 }
21ab4e
         }
21ab4e
 
21ab4e
@@ -883,12 +867,11 @@ io_stats_dump_global_to_json_logfp (xlator_t *this,
21ab4e
                         lc_fop_name[j] = tolower (lc_fop_name[j]);
21ab4e
                 }
21ab4e
 
21ab4e
-                fop_hits = 0;
21ab4e
+                fop_hits = GF_ATOMIC_GET (stats->fop_hits[i]);
21ab4e
                 fop_lat_ave = 0.0;
21ab4e
                 fop_lat_min = 0.0;
21ab4e
                 fop_lat_max = 0.0;
21ab4e
-                if (stats->fop_hits[i]) {
21ab4e
-                        fop_hits = stats->fop_hits[i];
21ab4e
+                if (fop_hits) {
21ab4e
                         if (stats->latency[i].avg) {
21ab4e
                                 fop_lat_ave = stats->latency[i].avg;
21ab4e
                                 fop_lat_min = stats->latency[i].min;
21ab4e
@@ -897,7 +880,7 @@ io_stats_dump_global_to_json_logfp (xlator_t *this,
21ab4e
                 }
21ab4e
                 if (interval == -1) {
21ab4e
                         ios_log (this, logfp,
21ab4e
-                                "\"%s.%s.fop.%s.count\": \"%"PRId64"\",",
21ab4e
+                                "\"%s.%s.fop.%s.count\": \"%"GF_PRI_ATOMIC"\",",
21ab4e
                                 key_prefix, str_prefix, lc_fop_name,
21ab4e
                                 fop_hits);
21ab4e
                 } else {
21ab4e
@@ -923,10 +906,10 @@ io_stats_dump_global_to_json_logfp (xlator_t *this,
21ab4e
                 for (j = 0; lc_fop_name[j]; j++) {
21ab4e
                         lc_fop_name[j] = tolower (lc_fop_name[j]);
21ab4e
                 }
21ab4e
-                fop_hits = stats->upcall_hits[i];
21ab4e
+                fop_hits = GF_ATOMIC_GET (stats->upcall_hits[i]);
21ab4e
                 if (interval == -1) {
21ab4e
                         ios_log (this, logfp,
21ab4e
-                                "\"%s.%s.fop.%s.count\": \"%"PRId64"\",",
21ab4e
+                                "\"%s.%s.fop.%s.count\": \"%"GF_PRI_ATOMIC"\",",
21ab4e
                                 key_prefix, str_prefix, lc_fop_name,
21ab4e
                                 fop_hits);
21ab4e
                 } else {
21ab4e
@@ -941,10 +924,12 @@ io_stats_dump_global_to_json_logfp (xlator_t *this,
21ab4e
                 ios_log (this, logfp, "\"%s.%s.uptime\": \"%"PRId64"\",",
21ab4e
                          key_prefix, str_prefix,
21ab4e
                          (uint64_t) (now->tv_sec - stats->started_at.tv_sec));
21ab4e
-                ios_log (this, logfp, "\"%s.%s.bytes_read\": \"%"PRId64"\",",
21ab4e
-                         key_prefix, str_prefix, stats->data_read);
21ab4e
-                ios_log (this, logfp, "\"%s.%s.bytes_written\": \"%"PRId64"\"",
21ab4e
-                         key_prefix, str_prefix, stats->data_written);
21ab4e
+                ios_log (this, logfp, "\"%s.%s.bytes_read\": \""
21ab4e
+                         "%"GF_PRI_ATOMIC"\",", key_prefix, str_prefix,
21ab4e
+                         GF_ATOMIC_GET (stats->data_read));
21ab4e
+                ios_log (this, logfp, "\"%s.%s.bytes_written\": \""
21ab4e
+                         "%"GF_PRI_ATOMIC"\"", key_prefix, str_prefix,
21ab4e
+                         GF_ATOMIC_GET (stats->data_written));
21ab4e
         } else {
21ab4e
                 ios_log (this, logfp,
21ab4e
                          "\"%s.%s.sample_interval_sec\": \"%0.2lf\",",
21ab4e
@@ -952,12 +937,12 @@ io_stats_dump_global_to_json_logfp (xlator_t *this,
21ab4e
                          interval_sec);
21ab4e
                 ios_log (this, logfp,
21ab4e
                          "\"%s.%s.bytes_read_per_sec\": \"%0.2lf\",",
21ab4e
-                         key_prefix, str_prefix,
21ab4e
-                         (double)(stats->data_read / interval_sec));
21ab4e
+                         key_prefix, str_prefix, (double)
21ab4e
+                         (GF_ATOMIC_GET (stats->data_read) / interval_sec));
21ab4e
                 ios_log (this, logfp,
21ab4e
                          "\"%s.%s.bytes_written_per_sec\": \"%0.2lf\"",
21ab4e
-                         key_prefix, str_prefix,
21ab4e
-                         (double)(stats->data_written / interval_sec));
21ab4e
+                         key_prefix, str_prefix, (double)
21ab4e
+                         (GF_ATOMIC_GET (stats->data_written) / interval_sec));
21ab4e
         }
21ab4e
 
21ab4e
         ios_log (this, logfp, "}");
21ab4e
@@ -1204,6 +1189,9 @@ io_stats_dump_global_to_logfp (xlator_t *this, struct ios_global_stats *stats,
21ab4e
         char                  str_header[128] = {0};
21ab4e
         char                  str_read[128] = {0};
21ab4e
         char                  str_write[128] = {0};
21ab4e
+        uint64_t              fop_hits = 0;
21ab4e
+        uint64_t              block_count_read = 0;
21ab4e
+        uint64_t              block_count_write = 0;
21ab4e
 
21ab4e
         conf = this->private;
21ab4e
 
21ab4e
@@ -1214,31 +1202,32 @@ io_stats_dump_global_to_logfp (xlator_t *this, struct ios_global_stats *stats,
21ab4e
                          interval);
21ab4e
         ios_log (this, logfp, "      Duration : %"PRId64" secs",
21ab4e
                  (uint64_t) (now->tv_sec - stats->started_at.tv_sec));
21ab4e
-        ios_log (this, logfp, "     BytesRead : %"PRId64,
21ab4e
-                 stats->data_read);
21ab4e
-        ios_log (this, logfp, "  BytesWritten : %"PRId64"\n",
21ab4e
-                 stats->data_written);
21ab4e
+        ios_log (this, logfp, "     BytesRead : %"GF_PRI_ATOMIC,
21ab4e
+                 GF_ATOMIC_GET (stats->data_read));
21ab4e
+        ios_log (this, logfp, "  BytesWritten : %"GF_PRI_ATOMIC"\n",
21ab4e
+                 GF_ATOMIC_GET (stats->data_written));
21ab4e
 
21ab4e
         snprintf (str_header, sizeof (str_header), "%-12s %c", "Block Size", ':');
21ab4e
         snprintf (str_read, sizeof (str_read), "%-12s %c", "Read Count", ':');
21ab4e
         snprintf (str_write, sizeof (str_write), "%-12s %c", "Write Count", ':');
21ab4e
         index = 14;
21ab4e
-        for (i = 0; i < 32; i++) {
21ab4e
-                if ((stats->block_count_read[i] == 0) &&
21ab4e
-                    (stats->block_count_write[i] == 0))
21ab4e
+        for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) {
21ab4e
+                block_count_read = GF_ATOMIC_GET (stats->block_count_read[i]);
21ab4e
+                block_count_write = GF_ATOMIC_GET (stats->block_count_write[i]);
21ab4e
+                if ((block_count_read == 0) && (block_count_write == 0))
21ab4e
                         continue;
21ab4e
                 per_line++;
21ab4e
 
21ab4e
                 snprintf (str_header+index, sizeof (str_header)-index,
21ab4e
                           "%16dB+", (1<
21ab4e
-                if (stats->block_count_read[i])
21ab4e
+                if (block_count_read)
21ab4e
                         snprintf (str_read+index, sizeof (str_read)-index,
21ab4e
-                                  "%18"PRId64, stats->block_count_read[i]);
21ab4e
+                                  "%18"PRId64, block_count_read);
21ab4e
                 else    snprintf (str_read+index, sizeof (str_read)-index,
21ab4e
                                   "%18s", "0");
21ab4e
-                if (stats->block_count_write[i])
21ab4e
+                if (block_count_write)
21ab4e
                         snprintf (str_write+index, sizeof (str_write)-index,
21ab4e
-                                  "%18"PRId64, stats->block_count_write[i]);
21ab4e
+                                  "%18"GF_PRI_ATOMIC, block_count_write);
21ab4e
                 else    snprintf (str_write+index, sizeof (str_write)-index,
21ab4e
                                   "%18s", "0");
21ab4e
 
21ab4e
@@ -1277,22 +1266,25 @@ io_stats_dump_global_to_logfp (xlator_t *this, struct ios_global_stats *stats,
21ab4e
                  "-----------", "-----------", "-----------");
21ab4e
 
21ab4e
         for (i = 0; i < GF_FOP_MAXVALUE; i++) {
21ab4e
-                if (stats->fop_hits[i] && !stats->latency[i].avg)
21ab4e
-                        ios_log (this, logfp, "%-13s %10"PRId64" %11s "
21ab4e
+                fop_hits = GF_ATOMIC_GET (stats->fop_hits[i]);
21ab4e
+                if (fop_hits && !stats->latency[i].avg)
21ab4e
+                        ios_log (this, logfp, "%-13s %10"GF_PRI_ATOMIC" %11s "
21ab4e
                                  "us %11s us %11s us", gf_fop_list[i],
21ab4e
-                                 stats->fop_hits[i], "0", "0", "0");
21ab4e
-                else if (stats->fop_hits[i] && stats->latency[i].avg)
21ab4e
-                        ios_log (this, logfp, "%-13s %10"PRId64" %11.2lf us "
21ab4e
-                                 "%11.2lf us %11.2lf us", gf_fop_list[i],
21ab4e
-                                 stats->fop_hits[i], stats->latency[i].avg,
21ab4e
-                                 stats->latency[i].min, stats->latency[i].max);
21ab4e
+                                 fop_hits, "0", "0", "0");
21ab4e
+                else if (fop_hits && stats->latency[i].avg)
21ab4e
+                        ios_log (this, logfp, "%-13s %10"GF_PRI_ATOMIC" "
21ab4e
+                                 "%11.2lf us %11.2lf us %11.2lf us",
21ab4e
+                                 gf_fop_list[i], fop_hits,
21ab4e
+                                 stats->latency[i].avg, stats->latency[i].min,
21ab4e
+                                 stats->latency[i].max);
21ab4e
         }
21ab4e
 
21ab4e
         for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) {
21ab4e
-                if (stats->upcall_hits[i])
21ab4e
+                fop_hits = GF_ATOMIC_GET (stats->upcall_hits[i]);
21ab4e
+                if (fop_hits)
21ab4e
                         ios_log (this, logfp, "%-13s %10"PRId64" %11s "
21ab4e
                                  "us %11s us %11s us", gf_upcall_list[i],
21ab4e
-                                 stats->upcall_hits[i], "0", "0", "0");
21ab4e
+                                 fop_hits, "0", "0", "0");
21ab4e
         }
21ab4e
 
21ab4e
         ios_log (this, logfp, "------ ----- ----- ----- ----- ----- ----- ----- "
21ab4e
@@ -1365,6 +1357,7 @@ io_stats_dump_global_to_dict (xlator_t *this, struct ios_global_stats *stats,
21ab4e
         uint64_t        sec = 0;
21ab4e
         int             i = 0;
21ab4e
         uint64_t        count = 0;
21ab4e
+        uint64_t        fop_hits = 0;
21ab4e
 
21ab4e
         GF_ASSERT (stats);
21ab4e
         GF_ASSERT (now);
21ab4e
@@ -1392,27 +1385,29 @@ io_stats_dump_global_to_dict (xlator_t *this, struct ios_global_stats *stats,
21ab4e
 
21ab4e
         memset (key, 0, sizeof (key));
21ab4e
         snprintf (key, sizeof (key), "%d-total-read", interval);
21ab4e
-        ret = dict_set_uint64 (dict, key, stats->data_read);
21ab4e
+        ret = dict_set_uint64 (dict, key, GF_ATOMIC_GET (stats->data_read));
21ab4e
         if (ret) {
21ab4e
                 gf_log (this->name, GF_LOG_ERROR, "failed to set total "
21ab4e
-                       "read(%d) - %"PRId64, interval, stats->data_read);
21ab4e
+                       "read(%d) - %"GF_PRI_ATOMIC, interval,
21ab4e
+                       GF_ATOMIC_GET (stats->data_read));
21ab4e
                 goto out;
21ab4e
         }
21ab4e
 
21ab4e
         memset (key, 0, sizeof (key));
21ab4e
         snprintf (key, sizeof (key), "%d-total-write", interval);
21ab4e
-        ret = dict_set_uint64 (dict, key, stats->data_written);
21ab4e
+        ret = dict_set_uint64 (dict, key, GF_ATOMIC_GET (stats->data_written));
21ab4e
         if (ret) {
21ab4e
                 gf_log (this->name, GF_LOG_ERROR, "failed to set total "
21ab4e
-                        "write(%d) - %"PRId64, interval, stats->data_written);
21ab4e
+                        "write(%d) - %"GF_PRI_ATOMIC, interval,
21ab4e
+                        GF_ATOMIC_GET (stats->data_written));
21ab4e
                 goto out;
21ab4e
         }
21ab4e
         for (i = 0; i < 32; i++) {
21ab4e
-                if (stats->block_count_read[i]) {
21ab4e
+                count = GF_ATOMIC_GET (stats->block_count_read[i]);
21ab4e
+                if (count) {
21ab4e
                         memset (key, 0, sizeof (key));
21ab4e
                         snprintf (key, sizeof (key), "%d-read-%d", interval,
21ab4e
                                   (1 << i));
21ab4e
-                        count = stats->block_count_read[i];
21ab4e
                         ret = dict_set_uint64 (dict, key, count);
21ab4e
                         if (ret) {
21ab4e
                                 gf_log (this->name, GF_LOG_ERROR, "failed to "
21ab4e
@@ -1423,11 +1418,11 @@ io_stats_dump_global_to_dict (xlator_t *this, struct ios_global_stats *stats,
21ab4e
                 }
21ab4e
         }
21ab4e
 
21ab4e
-        for (i = 0; i < 32; i++) {
21ab4e
-                if (stats->block_count_write[i]) {
21ab4e
+        for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) {
21ab4e
+                count = GF_ATOMIC_GET (stats->block_count_write[i]);
21ab4e
+                if (count) {
21ab4e
                         snprintf (key, sizeof (key), "%d-write-%d", interval,
21ab4e
                                   (1<
21ab4e
-                        count = stats->block_count_write[i];
21ab4e
                         ret = dict_set_uint64 (dict, key, count);
21ab4e
                         if (ret) {
21ab4e
                                 gf_log (this->name, GF_LOG_ERROR, "failed to "
21ab4e
@@ -1439,14 +1434,15 @@ io_stats_dump_global_to_dict (xlator_t *this, struct ios_global_stats *stats,
21ab4e
         }
21ab4e
 
21ab4e
         for (i = 0; i < GF_FOP_MAXVALUE; i++) {
21ab4e
-                if (stats->fop_hits[i] == 0)
21ab4e
+                fop_hits = GF_ATOMIC_GET (stats->fop_hits[i]);
21ab4e
+                if (fop_hits == 0)
21ab4e
                         continue;
21ab4e
                 snprintf (key, sizeof (key), "%d-%d-hits", interval, i);
21ab4e
-                ret = dict_set_uint64 (dict, key, stats->fop_hits[i]);
21ab4e
+                ret = dict_set_uint64 (dict, key, fop_hits);
21ab4e
                 if (ret) {
21ab4e
-                        gf_log (this->name, GF_LOG_ERROR, "failed to "
21ab4e
-                                "set %s-fop-hits: %"PRIu64, gf_fop_list[i],
21ab4e
-                                stats->fop_hits[i]);
21ab4e
+                        gf_log (this->name, GF_LOG_ERROR, "failed to set "
21ab4e
+                                "%s-fop-hits: %"GF_PRI_ATOMIC, gf_fop_list[i],
21ab4e
+                                fop_hits);
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
 
21ab4e
@@ -1478,15 +1474,15 @@ io_stats_dump_global_to_dict (xlator_t *this, struct ios_global_stats *stats,
21ab4e
                 }
21ab4e
         }
21ab4e
         for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) {
21ab4e
-                if (stats->upcall_hits[i] == 0)
21ab4e
+                fop_hits = GF_ATOMIC_GET (stats->upcall_hits[i]);
21ab4e
+                if (fop_hits == 0)
21ab4e
                         continue;
21ab4e
                 snprintf (key, sizeof (key), "%d-%d-upcall-hits", interval, i);
21ab4e
-                ret = dict_set_uint64 (dict, key, stats->upcall_hits[i]);
21ab4e
+                ret = dict_set_uint64 (dict, key, fop_hits);
21ab4e
                 if (ret) {
21ab4e
                         gf_log (this->name, GF_LOG_ERROR, "failed to "
21ab4e
                                 "set %s-upcall-hits: %"PRIu64,
21ab4e
-                                gf_upcall_list[i],
21ab4e
-                                stats->upcall_hits[i]);
21ab4e
+                                gf_upcall_list[i], fop_hits);
21ab4e
                         goto out;
21ab4e
                 }
21ab4e
         }
21ab4e
@@ -1572,8 +1568,8 @@ io_stats_dump (xlator_t *this, struct ios_dump_args *args,
21ab4e
                gf1_cli_info_op op, gf_boolean_t is_peek)
21ab4e
 {
21ab4e
         struct ios_conf         *conf = NULL;
21ab4e
-        struct ios_global_stats  cumulative = {0, };
21ab4e
-        struct ios_global_stats  incremental = {0, };
21ab4e
+        struct ios_global_stats  cumulative = {{0,}, };
21ab4e
+        struct ios_global_stats  incremental = {{0,}, };
21ab4e
         int                      increment = 0;
21ab4e
         struct timeval           now;
21ab4e
 
21ab4e
@@ -1626,6 +1622,10 @@ io_stats_dump_fd (xlator_t *this, struct ios_fd *iosfd)
21ab4e
         uint64_t                 sec = 0;
21ab4e
         uint64_t                 usec = 0;
21ab4e
         int                      i = 0;
21ab4e
+        uint64_t                 data_read = 0;
21ab4e
+        uint64_t                 data_written = 0;
21ab4e
+        uint64_t                 block_count_read = 0;
21ab4e
+        uint64_t                 block_count_write = 0;
21ab4e
 
21ab4e
         conf = this->private;
21ab4e
 
21ab4e
@@ -1658,27 +1658,29 @@ io_stats_dump_fd (xlator_t *this, struct ios_fd *iosfd)
21ab4e
                         "      Lifetime : %"PRId64"secs, %"PRId64"usecs",
21ab4e
                         sec, usec);
21ab4e
 
21ab4e
-        if (iosfd->data_read)
21ab4e
+        data_read = GF_ATOMIC_GET (iosfd->data_read);
21ab4e
+        if (data_read)
21ab4e
                 gf_log (this->name, GF_LOG_INFO,
21ab4e
-                        "     BytesRead : %"PRId64" bytes",
21ab4e
-                        iosfd->data_read);
21ab4e
+                        "     BytesRead : %"PRId64" bytes", data_read);
21ab4e
 
21ab4e
-        if (iosfd->data_written)
21ab4e
+        data_written = GF_ATOMIC_GET (iosfd->data_written);
21ab4e
+        if (data_written)
21ab4e
                 gf_log (this->name, GF_LOG_INFO,
21ab4e
                         "  BytesWritten : %"PRId64" bytes",
21ab4e
-                        iosfd->data_written);
21ab4e
+                        data_written);
21ab4e
 
21ab4e
         for (i = 0; i < 32; i++) {
21ab4e
-                if (iosfd->block_count_read[i])
21ab4e
-                        gf_log (this->name, GF_LOG_INFO,
21ab4e
-                                " Read %06db+ : %"PRId64,
21ab4e
-                                (1 << i), iosfd->block_count_read[i]);
21ab4e
+                block_count_read = GF_ATOMIC_GET (iosfd->block_count_read[i]);
21ab4e
+                if (block_count_read)
21ab4e
+                        gf_log (this->name, GF_LOG_INFO, " Read %06db+ :"
21ab4e
+                                "%"PRId64, (1 << i), block_count_read);
21ab4e
         }
21ab4e
-        for (i = 0; i < 32; i++) {
21ab4e
-                if (iosfd->block_count_write[i])
21ab4e
+        for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) {
21ab4e
+                block_count_write = GF_ATOMIC_GET (iosfd->block_count_write[i]);
21ab4e
+                if (block_count_write)
21ab4e
                         gf_log (this->name, GF_LOG_INFO,
21ab4e
                                 "Write %06db+ : %"PRId64,
21ab4e
-                                (1 << i), iosfd->block_count_write[i]);
21ab4e
+                                (1 << i), block_count_write);
21ab4e
         }
21ab4e
         return 0;
21ab4e
 }
21ab4e
@@ -1744,7 +1746,8 @@ update_ios_latency_stats (struct ios_global_stats   *stats, double elapsed,
21ab4e
 
21ab4e
         avg = stats->latency[op].avg;
21ab4e
 
21ab4e
-        stats->latency[op].avg = avg + (elapsed - avg) / stats->fop_hits[op];
21ab4e
+        stats->latency[op].avg = avg + (elapsed - avg) /
21ab4e
+                                       GF_ATOMIC_GET (stats->fop_hits[op]);
21ab4e
 }
21ab4e
 
21ab4e
 int
21ab4e
@@ -1886,6 +1889,29 @@ unlock_list_head:
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
+static struct ios_stat*
21ab4e
+ios_init_iosstat (xlator_t *this, char *path, uuid_t gfid, inode_t *inode)
21ab4e
+{
21ab4e
+        struct ios_stat *iosstat = NULL;
21ab4e
+        int              i       = 0;
21ab4e
+
21ab4e
+        iosstat = GF_CALLOC (1, sizeof (*iosstat), gf_io_stats_mt_ios_stat);
21ab4e
+        if (!iosstat)
21ab4e
+                goto out;
21ab4e
+
21ab4e
+        iosstat->filename = gf_strdup (path);
21ab4e
+        gf_uuid_copy (iosstat->gfid, gfid);
21ab4e
+        LOCK_INIT (&iosstat->lock);
21ab4e
+
21ab4e
+        for (i = 0; i < IOS_STATS_TYPE_MAX; i++)
21ab4e
+                GF_ATOMIC_INIT (iosstat->counters[i], 0);
21ab4e
+
21ab4e
+        ios_inode_ctx_set (inode, this, iosstat);
21ab4e
+
21ab4e
+out:
21ab4e
+        return iosstat;
21ab4e
+}
21ab4e
+
21ab4e
 int
21ab4e
 io_stats_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                      int32_t op_ret, int32_t op_errno, fd_t *fd,
21ab4e
@@ -1930,15 +1956,9 @@ io_stats_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         }
21ab4e
         UNLOCK (&conf->lock);
21ab4e
 
21ab4e
-        iosstat = GF_CALLOC (1, sizeof (*iosstat), gf_io_stats_mt_ios_stat);
21ab4e
-        if (!iosstat) {
21ab4e
+        iosstat = ios_init_iosstat (this, path, buf->ia_gfid, inode);
21ab4e
+        if (!iosstat)
21ab4e
                 GF_FREE (path);
21ab4e
-                goto unwind;
21ab4e
-        }
21ab4e
-        iosstat->filename = gf_strdup (path);
21ab4e
-        gf_uuid_copy (iosstat->gfid, buf->ia_gfid);
21ab4e
-        LOCK_INIT (&iosstat->lock);
21ab4e
-        ios_inode_ctx_set (fd->inode, this, iosstat);
21ab4e
 
21ab4e
 unwind:
21ab4e
         UPDATE_PROFILE_STATS (frame, CREATE);
21ab4e
@@ -1952,10 +1972,11 @@ int
21ab4e
 io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                    int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
21ab4e
 {
21ab4e
-        struct ios_fd *iosfd = NULL;
21ab4e
-        char          *path = NULL;
21ab4e
-        struct   ios_stat *iosstat = NULL;
21ab4e
+        struct ios_fd     *iosfd = NULL;
21ab4e
+        char              *path = NULL;
21ab4e
+        struct ios_stat   *iosstat = NULL;
21ab4e
         struct ios_conf   *conf = NULL;
21ab4e
+        int                i = 0;
21ab4e
 
21ab4e
         conf = this->private;
21ab4e
         path = frame->local;
21ab4e
@@ -1976,20 +1997,20 @@ io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         }
21ab4e
 
21ab4e
         iosfd->filename = path;
21ab4e
+        GF_ATOMIC_INIT (iosfd->data_read, 0);
21ab4e
+        GF_ATOMIC_INIT (iosfd->data_written, 0);
21ab4e
+        for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) {
21ab4e
+                GF_ATOMIC_INIT (iosfd->block_count_write[i], 0);
21ab4e
+                GF_ATOMIC_INIT (iosfd->block_count_read[i], 0);
21ab4e
+        }
21ab4e
         gettimeofday (&iosfd->opened_at, NULL);
21ab4e
 
21ab4e
         ios_fd_ctx_set (fd, this, iosfd);
21ab4e
 
21ab4e
         ios_inode_ctx_get (fd->inode, this, &iosstat);
21ab4e
         if (!iosstat) {
21ab4e
-                iosstat = GF_CALLOC (1, sizeof (*iosstat),
21ab4e
-                                     gf_io_stats_mt_ios_stat);
21ab4e
-                if (iosstat) {
21ab4e
-                        iosstat->filename = gf_strdup (path);
21ab4e
-                        gf_uuid_copy (iosstat->gfid, fd->inode->gfid);
21ab4e
-                        LOCK_INIT (&iosstat->lock);
21ab4e
-                        ios_inode_ctx_set (fd->inode, this, iosstat);
21ab4e
-                }
21ab4e
+                iosstat = ios_init_iosstat (this, path, fd->inode->gfid,
21ab4e
+                                            fd->inode);
21ab4e
         }
21ab4e
 
21ab4e
         LOCK (&conf->lock);
21ab4e
@@ -2002,8 +2023,8 @@ io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         }
21ab4e
         UNLOCK (&conf->lock);
21ab4e
         if (iosstat) {
21ab4e
-              BUMP_STATS (iosstat, IOS_STATS_TYPE_OPEN);
21ab4e
-              iosstat = NULL;
21ab4e
+                ios_bump_stats (this, iosstat, IOS_STATS_TYPE_OPEN);
21ab4e
+                iosstat = NULL;
21ab4e
         }
21ab4e
 unwind:
21ab4e
         UPDATE_PROFILE_STATS (frame, OPEN);
21ab4e
@@ -2039,16 +2060,16 @@ io_stats_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
 
21ab4e
         if (op_ret > 0) {
21ab4e
                 len = iov_length (vector, count);
21ab4e
-                BUMP_READ (fd, len);
21ab4e
+                ios_bump_read (this, fd, len);
21ab4e
         }
21ab4e
 
21ab4e
         UPDATE_PROFILE_STATS (frame, READ);
21ab4e
         ios_inode_ctx_get (fd->inode, this, &iosstat);
21ab4e
 
21ab4e
         if (iosstat) {
21ab4e
-              BUMP_STATS (iosstat, IOS_STATS_TYPE_READ);
21ab4e
-              BUMP_THROUGHPUT (iosstat, IOS_STATS_THRU_READ);
21ab4e
-              iosstat = NULL;
21ab4e
+                ios_bump_stats (this, iosstat, IOS_STATS_TYPE_READ);
21ab4e
+                BUMP_THROUGHPUT (iosstat, IOS_STATS_THRU_READ);
21ab4e
+                iosstat = NULL;
21ab4e
         }
21ab4e
 
21ab4e
         STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,
21ab4e
@@ -2072,7 +2093,7 @@ io_stats_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                 frame->local = NULL;
21ab4e
                 ios_inode_ctx_get (inode, this, &iosstat);
21ab4e
                 if (iosstat) {
21ab4e
-                        BUMP_STATS (iosstat, IOS_STATS_TYPE_WRITE);
21ab4e
+                        ios_bump_stats (this, iosstat, IOS_STATS_TYPE_WRITE);
21ab4e
                         BUMP_THROUGHPUT (iosstat, IOS_STATS_THRU_WRITE);
21ab4e
                         inode = NULL;
21ab4e
                         iosstat = NULL;
21ab4e
@@ -2101,8 +2122,8 @@ io_stats_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         ios_inode_ctx_get (inode, this, &iosstat);
21ab4e
 
21ab4e
         if (iosstat) {
21ab4e
-              BUMP_STATS (iosstat, IOS_STATS_TYPE_READDIRP);
21ab4e
-               iosstat = NULL;
21ab4e
+                ios_bump_stats (this, iosstat, IOS_STATS_TYPE_READDIRP);
21ab4e
+                iosstat = NULL;
21ab4e
         }
21ab4e
 
21ab4e
         STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, buf, xdata);
21ab4e
@@ -2226,7 +2247,6 @@ io_stats_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
                     struct iatt *preparent, struct iatt *postparent,
21ab4e
                     dict_t *xdata)
21ab4e
 {
21ab4e
-        struct ios_stat *iosstat = NULL;
21ab4e
         char   *path = frame->local;
21ab4e
 
21ab4e
         if (!path)
21ab4e
@@ -2236,13 +2256,8 @@ io_stats_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
         if (op_ret < 0)
21ab4e
                 goto unwind;
21ab4e
 
21ab4e
-        iosstat = GF_CALLOC (1, sizeof (*iosstat), gf_io_stats_mt_ios_stat);
21ab4e
-        if (iosstat) {
21ab4e
-                LOCK_INIT (&iosstat->lock);
21ab4e
-                iosstat->filename = gf_strdup(path);
21ab4e
-                gf_uuid_copy (iosstat->gfid, buf->ia_gfid);
21ab4e
-                ios_inode_ctx_set (inode, this, iosstat);
21ab4e
-        }
21ab4e
+        /* allocate a struct ios_stat and set the inode ctx */
21ab4e
+        ios_init_iosstat (this, path, buf->ia_gfid, inode);
21ab4e
 
21ab4e
 unwind:
21ab4e
         /* local is assigned with path */
21ab4e
@@ -2292,7 +2307,7 @@ io_stats_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
21ab4e
 
21ab4e
         ret = ios_inode_ctx_get (fd->inode, this, &iosstat);
21ab4e
         if (!ret)
21ab4e
-                BUMP_STATS (iosstat, IOS_STATS_TYPE_OPENDIR);
21ab4e
+                ios_bump_stats (this, iosstat, IOS_STATS_TYPE_OPENDIR);
21ab4e
 
21ab4e
 unwind:
21ab4e
         STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
21ab4e
@@ -2930,7 +2945,7 @@ io_stats_writev (call_frame_t *frame, xlator_t *this,
21ab4e
                 frame->local = fd->inode;
21ab4e
         len = iov_length (vector, count);
21ab4e
 
21ab4e
-        BUMP_WRITE (fd, len);
21ab4e
+        ios_bump_write (this, fd, len);
21ab4e
         START_FOP_LATENCY (frame);
21ab4e
 
21ab4e
         STACK_WIND (frame, io_stats_writev_cbk,
21ab4e
@@ -3704,23 +3719,23 @@ io_priv (xlator_t *this)
21ab4e
         if(!conf->count_fop_hits || !conf->measure_latency)
21ab4e
                 return -1;
21ab4e
 
21ab4e
-        gf_proc_dump_write("cumulative.data_read", "%"PRIu64,
21ab4e
-                                                conf->cumulative.data_read);
21ab4e
-        gf_proc_dump_write("cumulative.data_written", "%"PRIu64,
21ab4e
-                                                conf->cumulative.data_written);
21ab4e
+        gf_proc_dump_write ("cumulative.data_read", "%"GF_PRI_ATOMIC,
21ab4e
+                            GF_ATOMIC_GET (conf->cumulative.data_read));
21ab4e
+        gf_proc_dump_write ("cumulative.data_written", "%"GF_PRI_ATOMIC,
21ab4e
+                            GF_ATOMIC_GET (conf->cumulative.data_written));
21ab4e
 
21ab4e
-        gf_proc_dump_write("incremental.data_read", "%"PRIu64,
21ab4e
-                                                conf->incremental.data_read);
21ab4e
-        gf_proc_dump_write("incremental.data_written", "%"PRIu64,
21ab4e
-                                                conf->incremental.data_written);
21ab4e
+        gf_proc_dump_write ("incremental.data_read", "%"GF_PRI_ATOMIC,
21ab4e
+                            GF_ATOMIC_GET (conf->incremental.data_read));
21ab4e
+        gf_proc_dump_write ("incremental.data_written", "%"GF_PRI_ATOMIC,
21ab4e
+                            GF_ATOMIC_GET (conf->incremental.data_written));
21ab4e
 
21ab4e
         snprintf (key_prefix_cumulative, GF_DUMP_MAX_BUF_LEN, "%s.cumulative",
21ab4e
-                                                                    this->name);
21ab4e
+                  this->name);
21ab4e
         snprintf (key_prefix_incremental, GF_DUMP_MAX_BUF_LEN, "%s.incremental",
21ab4e
-                                                                    this->name);
21ab4e
+                  this->name);
21ab4e
 
21ab4e
         for (i = 0; i < GF_FOP_MAXVALUE; i++) {
21ab4e
-                count = conf->cumulative.fop_hits[i];
21ab4e
+                count = GF_ATOMIC_GET (conf->cumulative.fop_hits[i]);
21ab4e
                 total = conf->cumulative.latency[i].total;
21ab4e
                 min = conf->cumulative.latency[i].min;
21ab4e
                 max = conf->cumulative.latency[i].max;
21ab4e
@@ -3732,7 +3747,7 @@ io_priv (xlator_t *this)
21ab4e
                 gf_proc_dump_write (key,"%"PRId64",%"PRId64",%.03f,%.03f,%.03f",
21ab4e
                                     count, total, min, max, avg);
21ab4e
 
21ab4e
-                count = conf->incremental.fop_hits[i];
21ab4e
+                count = GF_ATOMIC_GET (conf->incremental.fop_hits[i]);
21ab4e
                 total = conf->incremental.latency[i].total;
21ab4e
                 min = conf->incremental.latency[i].min;
21ab4e
                 max = conf->incremental.latency[i].max;
21ab4e
@@ -3862,6 +3877,28 @@ ios_conf_destroy (struct ios_conf *conf)
21ab4e
         GF_FREE(conf);
21ab4e
 }
21ab4e
 
21ab4e
+static void
21ab4e
+ios_init_stats (struct ios_global_stats *stats)
21ab4e
+{
21ab4e
+        int i = 0;
21ab4e
+
21ab4e
+        GF_ATOMIC_INIT (stats->data_read, 0);
21ab4e
+        GF_ATOMIC_INIT (stats->data_written, 0);
21ab4e
+
21ab4e
+        for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) {
21ab4e
+                GF_ATOMIC_INIT (stats->block_count_write[i], 0);
21ab4e
+                GF_ATOMIC_INIT (stats->block_count_read[i], 0);
21ab4e
+        }
21ab4e
+
21ab4e
+        for (i = 0; i < GF_FOP_MAXVALUE; i++)
21ab4e
+                GF_ATOMIC_INIT (stats->fop_hits[i], 0);
21ab4e
+
21ab4e
+        for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++)
21ab4e
+                GF_ATOMIC_INIT (stats->upcall_hits[i], 0);
21ab4e
+
21ab4e
+        gettimeofday (&stats->started_at, NULL);
21ab4e
+}
21ab4e
+
21ab4e
 int
21ab4e
 init (xlator_t *this)
21ab4e
 {
21ab4e
@@ -3912,8 +3949,8 @@ init (xlator_t *this)
21ab4e
         LOCK_INIT (&conf->lock);
21ab4e
         LOCK_INIT (&conf->ios_sampling_lock);
21ab4e
 
21ab4e
-        gettimeofday (&conf->cumulative.started_at, NULL);
21ab4e
-        gettimeofday (&conf->incremental.started_at, NULL);
21ab4e
+        ios_init_stats (&conf->cumulative);
21ab4e
+        ios_init_stats (&conf->incremental);
21ab4e
 
21ab4e
         ret = ios_init_top_stats (conf);
21ab4e
         if (ret)
21ab4e
@@ -4119,24 +4156,24 @@ notify (xlator_t *this, int32_t event, void *data, ...)
21ab4e
                 break;
21ab4e
         case GF_EVENT_UPCALL:
21ab4e
                 up_data = (struct gf_upcall *)data;
21ab4e
-                BUMP_UPCALL (GF_UPCALL);
21ab4e
+                ios_bump_upcall (this, GF_UPCALL);
21ab4e
 
21ab4e
                 switch (up_data->event_type) {
21ab4e
                 case GF_UPCALL_RECALL_LEASE:
21ab4e
-                        BUMP_UPCALL (GF_UPCALL_LEASE_RECALL);
21ab4e
+                        ios_bump_upcall (this, GF_UPCALL_LEASE_RECALL);
21ab4e
                         break;
21ab4e
                 case GF_UPCALL_CACHE_INVALIDATION:
21ab4e
                         up_ci = (struct gf_upcall_cache_invalidation *)up_data->data;
21ab4e
                         if (up_ci->flags & (UP_XATTR | UP_XATTR_RM))
21ab4e
-                                BUMP_UPCALL (GF_UPCALL_CI_XATTR);
21ab4e
+                                ios_bump_upcall (this, GF_UPCALL_CI_XATTR);
21ab4e
                         if (up_ci->flags & IATT_UPDATE_FLAGS)
21ab4e
-                                BUMP_UPCALL (GF_UPCALL_CI_STAT);
21ab4e
+                                ios_bump_upcall (this, GF_UPCALL_CI_STAT);
21ab4e
                         if (up_ci->flags & UP_RENAME_FLAGS)
21ab4e
-                                BUMP_UPCALL (GF_UPCALL_CI_RENAME);
21ab4e
+                                ios_bump_upcall (this, GF_UPCALL_CI_RENAME);
21ab4e
                         if (up_ci->flags & UP_FORGET)
21ab4e
-                                BUMP_UPCALL (GF_UPCALL_CI_FORGET);
21ab4e
+                                ios_bump_upcall (this, GF_UPCALL_CI_FORGET);
21ab4e
                         if (up_ci->flags & UP_NLINK)
21ab4e
-                                BUMP_UPCALL (GF_UPCALL_CI_NLINK);
21ab4e
+                                ios_bump_upcall (this, GF_UPCALL_CI_NLINK);
21ab4e
                         break;
21ab4e
                 default:
21ab4e
                         gf_msg_debug (this->name, 0, "Unknown upcall event "
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e