summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/latency.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/latency.c')
-rw-r--r--libglusterfs/src/latency.c205
1 files changed, 53 insertions, 152 deletions
diff --git a/libglusterfs/src/latency.c b/libglusterfs/src/latency.c
index dfce235c07c..ce4b0e8255d 100644
--- a/libglusterfs/src/latency.c
+++ b/libglusterfs/src/latency.c
@@ -1,183 +1,84 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
-
/*
* This file contains functions to support dumping of
* latencies of FOPs broken down by subvolumes.
*/
-#include "glusterfs.h"
-#include "stack.h"
-#include "xlator.h"
-#include "common-utils.h"
-#include "statedump.h"
-
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/statedump.h"
-void
-gf_set_fop_from_fn_pointer (call_frame_t *frame, struct xlator_fops *fops, void *fn)
+gf_latency_t *
+gf_latency_new(size_t n)
{
- glusterfs_fop_t fop = -1;
+ int i = 0;
+ gf_latency_t *lat = NULL;
- if (fops->stat == fn)
- fop = GF_FOP_STAT;
- else if (fops->readlink == fn)
- fop = GF_FOP_READLINK;
- else if (fops->mknod == fn)
- fop = GF_FOP_MKNOD;
- else if (fops->mkdir == fn)
- fop = GF_FOP_MKDIR;
- else if (fops->unlink == fn)
- fop = GF_FOP_UNLINK;
- else if (fops->rmdir == fn)
- fop = GF_FOP_RMDIR;
- else if (fops->symlink == fn)
- fop = GF_FOP_SYMLINK;
- else if (fops->rename == fn)
- fop = GF_FOP_RENAME;
- else if (fops->link == fn)
- fop = GF_FOP_LINK;
- else if (fops->truncate == fn)
- fop = GF_FOP_TRUNCATE;
- else if (fops->open == fn)
- fop = GF_FOP_OPEN;
- else if (fops->readv == fn)
- fop = GF_FOP_READ;
- else if (fops->writev == fn)
- fop = GF_FOP_WRITE;
- else if (fops->statfs == fn)
- fop = GF_FOP_STATFS;
- else if (fops->flush == fn)
- fop = GF_FOP_FLUSH;
- else if (fops->fsync == fn)
- fop = GF_FOP_FSYNC;
- else if (fops->setxattr == fn)
- fop = GF_FOP_SETXATTR;
- else if (fops->getxattr == fn)
- fop = GF_FOP_GETXATTR;
- else if (fops->removexattr == fn)
- fop = GF_FOP_REMOVEXATTR;
- else if (fops->opendir == fn)
- fop = GF_FOP_OPENDIR;
- else if (fops->fsyncdir == fn)
- fop = GF_FOP_FSYNCDIR;
- else if (fops->access == fn)
- fop = GF_FOP_ACCESS;
- else if (fops->create == fn)
- fop = GF_FOP_CREATE;
- else if (fops->ftruncate == fn)
- fop = GF_FOP_FTRUNCATE;
- else if (fops->fstat == fn)
- fop = GF_FOP_FSTAT;
- else if (fops->lk == fn)
- fop = GF_FOP_LK;
- else if (fops->lookup == fn)
- fop = GF_FOP_LOOKUP;
- else if (fops->readdir == fn)
- fop = GF_FOP_READDIR;
- else if (fops->inodelk == fn)
- fop = GF_FOP_INODELK;
- else if (fops->finodelk == fn)
- fop = GF_FOP_FINODELK;
- else if (fops->entrylk == fn)
- fop = GF_FOP_ENTRYLK;
- else if (fops->fentrylk == fn)
- fop = GF_FOP_FENTRYLK;
- else if (fops->xattrop == fn)
- fop = GF_FOP_XATTROP;
- else if (fops->fxattrop == fn)
- fop = GF_FOP_FXATTROP;
- else if (fops->fgetxattr == fn)
- fop = GF_FOP_FGETXATTR;
- else if (fops->fsetxattr == fn)
- fop = GF_FOP_FSETXATTR;
- else if (fops->rchecksum == fn)
- fop = GF_FOP_RCHECKSUM;
- else if (fops->setattr == fn)
- fop = GF_FOP_SETATTR;
- else if (fops->fsetattr == fn)
- fop = GF_FOP_FSETATTR;
- else if (fops->readdirp == fn)
- fop = GF_FOP_READDIRP;
- else if (fops->getspec == fn)
- fop = GF_FOP_GETSPEC;
- else
- fop = -1;
+ lat = GF_MALLOC(n * sizeof(*lat), gf_common_mt_latency_t);
+ if (!lat)
+ return NULL;
- frame->op = fop;
+ for (i = 0; i < n; i++) {
+ gf_latency_reset(lat + i);
+ }
+ return lat;
}
-
void
-gf_update_latency (call_frame_t *frame)
+gf_latency_update(gf_latency_t *lat, struct timespec *begin,
+ struct timespec *end)
{
- double elapsed;
- struct timeval *begin, *end;
-
- fop_latency_t *lat;
+ if (!(begin->tv_sec && end->tv_sec)) {
+ /*Measure latency might have been enabled/disabled during the op*/
+ return;
+ }
- begin = &frame->begin;
- end = &frame->end;
+ double elapsed = gf_tsdiff(begin, end);
- elapsed = (end->tv_sec - begin->tv_sec) * 1e6
- + (end->tv_usec - begin->tv_usec);
+ if (lat->max < elapsed)
+ lat->max = elapsed;
- lat = &frame->this->latencies[frame->op];
+ if (lat->min > elapsed)
+ lat->min = elapsed;
- lat->total += elapsed;
- lat->count++;
- lat->mean = lat->mean + (elapsed - lat->mean) / lat->count;
+ lat->total += elapsed;
+ lat->count++;
}
-
void
-gf_proc_dump_latency_info (xlator_t *xl)
+gf_latency_reset(gf_latency_t *lat)
{
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
- char key[GF_DUMP_MAX_BUF_LEN];
- int i;
-
- snprintf (key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.latency", xl->name);
- gf_proc_dump_add_section (key_prefix);
-
- for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- gf_proc_dump_build_key (key, key_prefix, gf_fop_list[i]);
-
- gf_proc_dump_write (key, "%.03f,%"PRId64",%.03f",
- xl->latencies[i].mean,
- xl->latencies[i].count,
- xl->latencies[i].total);
- }
+ if (!lat)
+ return;
+ memset(lat, 0, sizeof(*lat));
+ lat->min = ULLONG_MAX;
+ /* make sure 'min' is set to high value, so it would be
+ properly set later */
}
-
void
-gf_latency_toggle (int signum)
+gf_frame_latency_update(call_frame_t *frame)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = glusterfs_ctx_get ();
-
- if (ctx) {
- ctx->measure_latency = !ctx->measure_latency;
- gf_log ("[core]", GF_LOG_INFO,
- "Latency measurement turned %s",
- ctx->measure_latency ? "on" : "off");
- }
+ gf_latency_t *lat;
+ /* Can happen mostly at initiator xlator, as STACK_WIND/UNWIND macros
+ set it right anyways for those frames */
+ if (!frame->op)
+ frame->op = frame->root->op;
+
+ if (frame->op < 0 || frame->op >= GF_FOP_MAXVALUE) {
+ gf_log("[core]", GF_LOG_WARNING, "Invalid frame op value: %d",
+ frame->op);
+ return;
+ }
+
+ lat = &frame->this->stats.interval.latencies[frame->op];
+ gf_latency_update(lat, &frame->begin, &frame->end);
}