aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-09-05 23:01:08 +0200
committerChris Mason <chris.mason@oracle.com>2012-09-10 20:53:05 -0400
commit230f060187f09a71185d1321192a497e6a344f80 (patch)
treea1572f533a097cea65e528748964370f50c5d6b3
parentf752a6eb5f4b2b0b2af547044b14e94694860e83 (diff)
downloadblktrace-230f060187f09a71185d1321192a497e6a344f80.tar.gz
iowatcher: Add possibility to limit seconds from below
Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r--iowatcher/main.c79
-rw-r--r--iowatcher/plot.c21
-rw-r--r--iowatcher/plot.h14
3 files changed, 67 insertions, 47 deletions
diff --git a/iowatcher/main.c b/iowatcher/main.c
index 570c10f..1385676 100644
--- a/iowatcher/main.c
+++ b/iowatcher/main.c
@@ -161,8 +161,9 @@ struct trace_file {
char *filename;
char *label;
struct trace *trace;
- int max_seconds;
- int stop_seconds;
+ int stop_seconds; /* Time when trace stops */
+ int min_seconds; /* Beginning of the interval we should plot */
+ int max_seconds; /* End of the interval we should plot */
u64 min_offset;
u64 max_offset;
@@ -176,6 +177,7 @@ struct trace_file {
struct graph_dot_data *gdd_writes;
struct graph_dot_data *gdd_reads;
+ int mpstat_min_seconds;
int mpstat_max_seconds;
int mpstat_stop_seconds;
struct graph_line_data **mpstat_gld;
@@ -280,12 +282,12 @@ static void setup_trace_file_graphs(void)
int i;
list_for_each_entry(tf, &all_traces, list) {
- tf->tput_gld = alloc_line_data(tf->max_seconds, tf->stop_seconds);
- tf->latency_gld = alloc_line_data(tf->max_seconds, tf->stop_seconds);
- tf->queue_depth_gld = alloc_line_data(tf->max_seconds, tf->stop_seconds);
- tf->iop_gld = alloc_line_data(tf->max_seconds, tf->stop_seconds);
- tf->gdd_writes = alloc_dot_data(tf->max_seconds, tf->min_offset, tf->max_offset, tf->stop_seconds);
- tf->gdd_reads = alloc_dot_data(tf->max_seconds, tf->min_offset, tf->max_offset, tf->stop_seconds);
+ tf->tput_gld = alloc_line_data(tf->min_seconds, tf->max_seconds, tf->stop_seconds);
+ tf->latency_gld = alloc_line_data(tf->min_seconds, tf->max_seconds, tf->stop_seconds);
+ tf->queue_depth_gld = alloc_line_data(tf->min_seconds, tf->max_seconds, tf->stop_seconds);
+ tf->iop_gld = alloc_line_data(tf->min_seconds, tf->max_seconds, tf->stop_seconds);
+ tf->gdd_writes = alloc_dot_data(tf->min_seconds, tf->max_seconds, tf->min_offset, tf->max_offset, tf->stop_seconds);
+ tf->gdd_reads = alloc_dot_data(tf->min_seconds, tf->max_seconds, tf->min_offset, tf->max_offset, tf->stop_seconds);
if (tf->trace->mpstat_num_cpus == 0)
continue;
@@ -293,7 +295,8 @@ static void setup_trace_file_graphs(void)
alloc_mpstat_gld(tf);
for (i = 0; i < (tf->trace->mpstat_num_cpus + 1) * MPSTAT_GRAPHS; i++) {
tf->mpstat_gld[i] =
- alloc_line_data(tf->mpstat_max_seconds,
+ alloc_line_data(tf->mpstat_min_seconds,
+ tf->mpstat_max_seconds,
tf->mpstat_max_seconds);
tf->mpstat_gld[i]->max = 100;
}
@@ -462,11 +465,12 @@ static void compare_minmax_tf(struct trace_file *tf, int *max_seconds, u64 *min_
*min_offset = tf->min_offset;
}
-static void set_all_minmax_tf(int max_seconds, u64 min_offset, u64 max_offset)
+static void set_all_minmax_tf(int min_seconds, int max_seconds, u64 min_offset, u64 max_offset)
{
struct trace_file *tf;
list_for_each_entry(tf, &all_traces, list) {
+ tf->min_seconds = min_seconds;
tf->max_seconds = max_seconds;
tf->min_offset = min_offset;
tf->max_offset = max_offset;
@@ -550,7 +554,7 @@ static void free_all_plot_history(struct list_head *head)
}
}
-static void plot_io(struct plot *plot, int max_seconds, u64 min_offset, u64 max_offset)
+static void plot_io(struct plot *plot, int min_seconds, int max_seconds, u64 min_offset, u64 max_offset)
{
struct trace_file *tf;
@@ -565,7 +569,7 @@ static void plot_io(struct plot *plot, int max_seconds, u64 min_offset, u64 max_
set_ylabel(plot, "Offset (MB)");
set_yticks(plot, 4, min_offset / (1024 * 1024),
max_offset / (1024 * 1024), "");
- set_xticks(plot, num_xticks, 0, max_seconds);
+ set_xticks(plot, num_xticks, min_seconds, max_seconds);
list_for_each_entry(tf, &all_traces, list) {
char *label = tf->label;
@@ -587,7 +591,7 @@ static void plot_io(struct plot *plot, int max_seconds, u64 min_offset, u64 max_
close_plot(plot);
}
-static void plot_tput(struct plot *plot, int max_seconds)
+static void plot_tput(struct plot *plot, int min_seconds, int max_seconds)
{
struct trace_file *tf;
char *units;
@@ -615,7 +619,7 @@ static void plot_tput(struct plot *plot, int max_seconds)
sprintf(line, "%sB/s", units);
set_ylabel(plot, line);
set_yticks(plot, 4, 0, max, "");
- set_xticks(plot, num_xticks, 0, max_seconds);
+ set_xticks(plot, num_xticks, min_seconds, max_seconds);
list_for_each_entry(tf, &all_traces, list) {
svg_line_graph(plot, tf->tput_gld, tf->read_color, 0, 0);
@@ -668,17 +672,19 @@ static void plot_cpu(struct plot *plot, int max_seconds, char *label,
set_yticks(plot, 4, 0, tf->mpstat_gld[gld_index]->max, "");
set_ylabel(plot, "Percent");
- set_xticks(plot, num_xticks, 0, max_seconds);
+ set_xticks(plot, num_xticks, tf->mpstat_min_seconds, max_seconds);
cpu_color_index = 0;
list_for_each_entry(tf, &all_traces, list) {
- for (i = 0; i < tf->mpstat_gld[0]->stop_seconds; i++) {
+ for (i = tf->mpstat_gld[0]->min_seconds;
+ i < tf->mpstat_gld[0]->stop_seconds; i++) {
if (tf->mpstat_gld[gld_index]->data[i].count) {
avg += (tf->mpstat_gld[gld_index]->data[i].sum /
tf->mpstat_gld[gld_index]->data[i].count);
}
}
- avg /= tf->mpstat_gld[gld_index]->stop_seconds;
+ avg /= tf->mpstat_gld[gld_index]->stop_seconds -
+ tf->mpstat_gld[gld_index]->min_seconds;
color = pick_cpu_color();
svg_line_graph(plot, tf->mpstat_gld[0], color, 0, 0);
svg_add_legend(plot, tf->label, " avg", color);
@@ -687,16 +693,18 @@ static void plot_cpu(struct plot *plot, int max_seconds, char *label,
struct graph_line_data *gld = tf->mpstat_gld[i * MPSTAT_GRAPHS + gld_index];
double this_avg = 0;
- for (gld_i = 0; gld_i < gld->stop_seconds; gld_i++) {
+ for (gld_i = gld->min_seconds;
+ gld_i < gld->stop_seconds; gld_i++) {
if (gld->data[i].count) {
this_avg += gld->data[i].sum /
gld->data[i].count;
}
}
- this_avg /= gld->stop_seconds;
+ this_avg /= gld->stop_seconds - gld->min_seconds;
- for (gld_i = 0; gld_i < gld->stop_seconds; gld_i++) {
+ for (gld_i = gld->min_seconds;
+ gld_i < gld->stop_seconds; gld_i++) {
double val;
if (gld->data[gld_i].count == 0)
@@ -728,7 +736,7 @@ static void plot_cpu(struct plot *plot, int max_seconds, char *label,
total_graphs_written++;
}
-static void plot_queue_depth(struct plot *plot, int max_seconds)
+static void plot_queue_depth(struct plot *plot, int min_seconds, int max_seconds)
{
struct trace_file *tf;
@@ -743,7 +751,7 @@ static void plot_queue_depth(struct plot *plot, int max_seconds)
tf = list_entry(all_traces.next, struct trace_file, list);
set_ylabel(plot, "Pending IO");
set_yticks(plot, 4, 0, tf->queue_depth_gld->max, "");
- set_xticks(plot, num_xticks, 0, max_seconds);
+ set_xticks(plot, num_xticks, min_seconds, max_seconds);
list_for_each_entry(tf, &all_traces, list) {
svg_line_graph(plot, tf->queue_depth_gld, tf->read_color, 0, 0);
@@ -824,13 +832,15 @@ static void plot_io_movie(struct plot *plot)
set_graph_size(cols / graph_width_factor, rows / 8);
plot->timeline = i / graph_width_factor;
- plot_tput(plot, tf->gdd_reads->max_seconds);
+ plot_tput(plot, tf->gdd_reads->min_seconds,
+ tf->gdd_reads->max_seconds);
plot_cpu(plot, tf->gdd_reads->max_seconds,
"CPU System Time", CPU_SYS_GRAPH_INDEX, MPSTAT_SYS);
plot->direction = PLOT_ACROSS;
- plot_queue_depth(plot, tf->gdd_reads->max_seconds);
+ plot_queue_depth(plot, tf->gdd_reads->min_seconds,
+ tf->gdd_reads->max_seconds);
/* movie graph starts here */
plot->start_y_offset = orig_y_offset;
@@ -885,7 +895,7 @@ static void plot_io_movie(struct plot *plot)
free(movie_dir);
}
-static void plot_latency(struct plot *plot, int max_seconds)
+static void plot_latency(struct plot *plot, int min_seconds, int max_seconds)
{
struct trace_file *tf;
char *units;
@@ -913,7 +923,7 @@ static void plot_latency(struct plot *plot, int max_seconds)
sprintf(line, "latency (%ss)", units);
set_ylabel(plot, line);
set_yticks(plot, 4, 0, max, "");
- set_xticks(plot, num_xticks, 0, max_seconds);
+ set_xticks(plot, num_xticks, min_seconds, max_seconds);
list_for_each_entry(tf, &all_traces, list) {
svg_line_graph(plot, tf->latency_gld, tf->read_color, 0, 0);
@@ -929,7 +939,7 @@ static void plot_latency(struct plot *plot, int max_seconds)
total_graphs_written++;
}
-static void plot_iops(struct plot *plot, int max_seconds)
+static void plot_iops(struct plot *plot, int min_seconds, int max_seconds)
{
struct trace_file *tf;
char *units;
@@ -957,7 +967,7 @@ static void plot_iops(struct plot *plot, int max_seconds)
set_ylabel(plot, "IO/s");
set_yticks(plot, 4, 0, max, units);
- set_xticks(plot, num_xticks, 0, max_seconds);
+ set_xticks(plot, num_xticks, min_seconds, max_seconds);
list_for_each_entry(tf, &all_traces, list) {
svg_line_graph(plot, tf->iop_gld, tf->read_color, 0, 0);
@@ -1124,6 +1134,7 @@ static int parse_options(int ac, char **av)
int main(int ac, char **av)
{
struct plot *plot;
+ int min_seconds = 0;
int max_seconds = 0;
u64 max_offset = 0;
u64 min_offset = ~(u64)0;
@@ -1194,7 +1205,7 @@ int main(int ac, char **av)
list_for_each_entry(tf, &all_traces, list)
compare_minmax_tf(tf, &max_seconds, &min_offset, &max_offset);
/* push the max we found into all the tfs */
- set_all_minmax_tf(max_seconds, min_offset, max_offset);
+ set_all_minmax_tf(min_seconds, max_seconds, min_offset, max_offset);
/* alloc graphing structs for all the traces */
setup_trace_file_graphs();
@@ -1223,7 +1234,7 @@ int main(int ac, char **av)
plot->add_xlabel = 1;
set_plot_title(plot, graph_title);
- plot_io(plot, max_seconds, min_offset, max_offset);
+ plot_io(plot, min_seconds, max_seconds, min_offset, max_offset);
plot->add_xlabel = 0;
if (columns > 1) {
@@ -1234,7 +1245,7 @@ int main(int ac, char **av)
}
check_plot_columns(plot, TPUT_GRAPH_INDEX);
- plot_tput(plot, max_seconds);
+ plot_tput(plot, min_seconds, max_seconds);
check_plot_columns(plot, CPU_IO_GRAPH_INDEX);
plot_cpu(plot, max_seconds, "CPU IO Wait Time",
@@ -1257,13 +1268,13 @@ int main(int ac, char **av)
CPU_USER_GRAPH_INDEX, MPSTAT_USER);
check_plot_columns(plot, LATENCY_GRAPH_INDEX);
- plot_latency(plot, max_seconds);
+ plot_latency(plot, min_seconds, max_seconds);
check_plot_columns(plot, QUEUE_DEPTH_GRAPH_INDEX);
- plot_queue_depth(plot, max_seconds);
+ plot_queue_depth(plot, min_seconds, max_seconds);
check_plot_columns(plot, IOPS_GRAPH_INDEX);
- plot_iops(plot, max_seconds);
+ plot_iops(plot, min_seconds, max_seconds);
/* once for all */
close_plot(plot);
diff --git a/iowatcher/plot.c b/iowatcher/plot.c
index ed28211..c19da54 100644
--- a/iowatcher/plot.c
+++ b/iowatcher/plot.c
@@ -69,7 +69,7 @@ static char line[1024];
static int final_height = 0;
static int final_width = 0;
-struct graph_line_data *alloc_line_data(int max_seconds, int stop_seconds)
+struct graph_line_data *alloc_line_data(int min_seconds, int max_seconds, int stop_seconds)
{
int size = sizeof(struct graph_line_data) + (stop_seconds + 1) * sizeof(struct graph_line_pair);
struct graph_line_data *gld;
@@ -79,6 +79,7 @@ struct graph_line_data *alloc_line_data(int max_seconds, int stop_seconds)
fprintf(stderr, "Unable to allocate memory for graph data\n");
exit(1);
}
+ gld->min_seconds = min_seconds;
gld->max_seconds = max_seconds;
gld->stop_seconds = stop_seconds;
return gld;
@@ -90,7 +91,7 @@ void free_line_data(struct graph_line_data *gld)
free(gld);
}
-struct graph_dot_data *alloc_dot_data(int max_seconds, u64 min_offset, u64 max_offset, int stop_seconds)
+struct graph_dot_data *alloc_dot_data(int min_seconds, int max_seconds, u64 min_offset, u64 max_offset, int stop_seconds)
{
int size;
int arr_size;
@@ -111,6 +112,7 @@ struct graph_dot_data *alloc_dot_data(int max_seconds, u64 min_offset, u64 max_o
fprintf(stderr, "Unable to allocate memory for graph data\n");
exit(1);
}
+ gdd->min_seconds = min_seconds;
gdd->max_seconds = max_seconds;
gdd->stop_seconds = stop_seconds;
gdd->rows = rows;
@@ -128,7 +130,7 @@ void free_dot_data(struct graph_dot_data *gdd)
void set_gdd_bit(struct graph_dot_data *gdd, u64 offset, double bytes, double time)
{
double bytes_per_row = (double)(gdd->max_offset - gdd->min_offset + 1) / gdd->rows;
- double secs_per_col = (double)gdd->max_seconds / gdd->cols;
+ double secs_per_col = (double)(gdd->max_seconds - gdd->min_seconds) / gdd->cols;
double col;
double row;
int col_int;
@@ -145,7 +147,7 @@ void set_gdd_bit(struct graph_dot_data *gdd, u64 offset, double bytes, double ti
time = time / 1000000000.0;
while (bytes > 0) {
row = (double)(offset - gdd->min_offset) / bytes_per_row;
- col = time / secs_per_col;
+ col = (time - gdd->min_seconds) / secs_per_col;
col_int = floor(col);
row_int = floor(row);
@@ -485,7 +487,8 @@ void set_xticks(struct plot *plot, int num_ticks, int first, int last)
if (!tick_only) {
snprintf(line, line_len, "<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%d\" "
"fill=\"black\" style=\"text-anchor: %s\">%d</text>\n",
- tick_x, text_y, font_family, tick_font_size, anchor, step * i);
+ tick_x, text_y, font_family, tick_font_size, anchor,
+ first + step * i);
write(plot->fd, line, strlen(line));
}
tick_x += pixels_per_tick;
@@ -706,7 +709,7 @@ int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color,
int fd = plot->fd;
char *start = "<path d=\"";
double yscale = ((double)gld->max) / graph_height;
- double xscale = (double)(gld->max_seconds - 1) / graph_width;
+ double xscale = (double)(gld->max_seconds - gld->min_seconds - 1) / graph_width;
char c = 'M';
double x;
int printed_header = 0;
@@ -717,9 +720,9 @@ int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color,
else if (rolling_avg_secs)
rolling = rolling_avg_secs;
else
- rolling = gld->stop_seconds / 25;
+ rolling = (gld->stop_seconds - gld->min_seconds) / 25;
- for (i = 0; i < gld->stop_seconds; i++) {
+ for (i = gld->min_seconds; i < gld->stop_seconds; i++) {
avg = rolling_avg(gld->data, i, rolling);
if (yscale == 0)
val = 0;
@@ -731,7 +734,7 @@ int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color,
if (val < 0)
val = 0;
- x = (double)i / xscale;
+ x = (double)(i - gld->min_seconds) / xscale;
if (!thresh1 && !thresh2) {
if (!printed_header) {
diff --git a/iowatcher/plot.h b/iowatcher/plot.h
index e527915..fb9c63b 100644
--- a/iowatcher/plot.h
+++ b/iowatcher/plot.h
@@ -68,7 +68,10 @@ struct graph_line_pair {
};
struct graph_line_data {
- /* total number of seconds in this graph */
+ /* beginning of an interval displayed by this graph */
+ int min_seconds;
+
+ /* end of an interval displayed by this graph */
int max_seconds;
int stop_seconds;
@@ -96,7 +99,10 @@ struct graph_dot_data {
/* in pixels, number of cols in our bitmap */
int cols;
- /* total number of seconds in this graph */
+ /* beginning of an interval displayed by this graph */
+ int min_seconds;
+
+ /* end of an interval displayed by this graph */
int max_seconds;
int stop_seconds;
@@ -119,9 +125,9 @@ struct plot_history {
int svg_io_graph(struct plot *plot, struct graph_dot_data *gdd, char *color);
int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color, int thresh1, int thresh2);
-struct graph_line_data *alloc_line_data(int max_seconds, int stop_seconds);
+struct graph_line_data *alloc_line_data(int min_seconds, int max_seconds, int stop_seconds);
void free_line_data(struct graph_line_data *gld);
-struct graph_dot_data *alloc_dot_data(int max_seconds, u64 min_offset, u64 max_offset, int stop_seconds);
+struct graph_dot_data *alloc_dot_data(int min_seconds, int max_seconds, u64 min_offset, u64 max_offset, int stop_seconds);
void free_dot_data(struct graph_dot_data *gdd);
void set_gdd_bit(struct graph_dot_data *gdd, u64 offset, double bytes, double time);
void print_gdd(struct graph_dot_data *gdd);