1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/*
Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
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 "libglusterfs-messages.h"
void
gf_update_latency (call_frame_t *frame)
{
double elapsed;
struct timespec *begin, *end;
fop_latency_t *lat;
begin = &frame->begin;
end = &frame->end;
if (!(begin->tv_sec && end->tv_sec))
goto out;
elapsed = (end->tv_sec - begin->tv_sec) * 1e9
+ (end->tv_nsec - begin->tv_nsec);
/* 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;
lat = &frame->this->stats.interval.latencies[frame->op];
if (lat->max < elapsed)
lat->max = elapsed;
if (lat->min > elapsed)
lat->min = elapsed;
lat->total += elapsed;
lat->count++;
out:
return;
}
void
gf_proc_dump_latency_info (xlator_t *xl)
{
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, "%s",
(char *)gf_fop_list[i]);
fop_latency_t *lat = &xl->stats.interval.latencies[i];
/* Doesn't make sense to continue if there are no fops
came in the given interval */
if (!lat->count)
continue;
gf_proc_dump_write (key, "%.03f,%"PRId64",%.03f",
(lat->total / lat->count), lat->count,
lat->total);
}
memset (xl->stats.interval.latencies, 0,
sizeof (xl->stats.interval.latencies));
/* make sure 'min' is set to high value, so it would be
properly set later */
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
xl->stats.interval.latencies[i].min = 0xffffffff;
}
}
void
gf_latency_toggle (int signum, glusterfs_ctx_t *ctx)
{
if (ctx) {
ctx->measure_latency = !ctx->measure_latency;
gf_msg ("[core]", GF_LOG_INFO, 0,
LG_MSG_LATENCY_MEASUREMENT_STATE,
"Latency measurement turned %s",
ctx->measure_latency ? "on" : "off");
}
}
|