diff options
Diffstat (limited to 'libglusterfs/src/latency.c')
| -rw-r--r-- | libglusterfs/src/latency.c | 205 |
1 files changed, 53 insertions, 152 deletions
diff --git a/libglusterfs/src/latency.c b/libglusterfs/src/latency.c index bc2409138c4..ce4b0e8255d 100644 --- a/libglusterfs/src/latency.c +++ b/libglusterfs/src/latency.c @@ -1,183 +1,84 @@ /* - Copyright (c) 2010 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 Affero 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 - Affero General Public License for more details. - - You should have received a copy of the GNU Affero 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_NORMAL, - "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); } |
