aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2014-01-08 17:04:26 -0500
committerChris Mason <clm@fb.com>2014-01-08 17:04:26 -0500
commit4748783e170b168013bf157679faa10f49eb8000 (patch)
treeab5733e97896be512a23a3837280eaa6053e44d3
parent5d845e37b509032a3154b419e2b332a3bf6101f6 (diff)
parent283ee99d31561ccd16ec20841eaa0417bf739bac (diff)
downloadiowatcher-4748783e170b168013bf157679faa10f49eb8000.tar.gz
Merge Jan Kara's fixes
-rw-r--r--README9
-rw-r--r--blkparse.c28
-rw-r--r--blkparse.h13
-rw-r--r--fio.c2
-rw-r--r--fio.h2
-rw-r--r--main.c59
-rw-r--r--plot.c18
-rw-r--r--plot.h14
8 files changed, 81 insertions, 64 deletions
diff --git a/README b/README
index f91fb6c..83db494 100644
--- a/README
+++ b/README
@@ -32,6 +32,10 @@ The basic options:
If you want more than one trace in a given graph, you can specify
-t more than once.
+ -F Add a fio bandwidth log graph. You need to run fio --bandwidth-log
+ to get one of these, and then pass either the read log or the write
+ log into iowatcher.
+
-l Sets a label in the graph for a trace file. The labels are added in
the same order the trace files are added.
@@ -55,6 +59,9 @@ The basic options:
current second with seconds from the past. Longer numbers here
give you flatter graphs.
+ -P add per-process tags to the IO. Each process responsible for
+ submitting the IO gets a different color.
+
-O add a single graph to the output. By default all the graphs
are included, but with -O you get only the graphs you ask for.
-O may be used more than once.
@@ -63,7 +70,7 @@ The basic options:
than once.
Choices for -O and -N are:
- io, tput, latency, queue_depth, iops, cpu-sys, cpu-io,
+ io, fio, tput, latency, queue_depth, iops, cpu-sys, cpu-io,
cpu-irq, cpu-user, cpu-soft
Examples:
diff --git a/blkparse.c b/blkparse.c
index d27b547..43eb269 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -181,12 +181,10 @@ struct pid_map {
char name[0];
};
-#define MINORBITS 20
-#define MINORMASK ((1 << MINORBITS) - 1)
-#define SECONDS(x) ((unsigned long long)(x) / 1000000000)
-#define NANO_SECONDS(x) ((unsigned long long)(x) % 1000000000)
-#define DOUBLE_TO_NANO_ULL(d) ((unsigned long long)((d) * 1000000000))
-#define CHECK_MAGIC(t) (((t)->magic & 0xffffff00) == BLK_IO_TRACE_MAGIC)
+u64 get_record_time(struct trace *trace)
+{
+ return trace->io->time;
+}
void init_io_hash_table(void)
{
@@ -960,9 +958,6 @@ void add_tput(struct trace *trace, struct graph_line_data *writes_gld,
gld = writes_gld;
seconds = SECONDS(io->time);
- if (seconds > gld->max_seconds)
- return;
-
gld->data[seconds].sum += io->bytes;
gld->data[seconds].count = 1;
@@ -1043,7 +1038,7 @@ void add_io(struct trace *trace, struct trace_file *tf)
void add_pending_io(struct trace *trace, struct graph_line_data *gld)
{
- int seconds;
+ unsigned int seconds;
struct blk_io_trace *io = trace->io;
int action = io->action & BLK_TA_MASK;
double avg;
@@ -1057,11 +1052,12 @@ void add_pending_io(struct trace *trace, struct graph_line_data *gld)
hash_queued_io(trace->io);
return;
}
- if (action != __BLK_TA_ISSUE)
+ if (action == __BLK_TA_REQUEUE) {
+ if (ios_in_flight > 0)
+ ios_in_flight--;
return;
-
- seconds = SECONDS(io->time);
- if (seconds > gld->max_seconds)
+ }
+ if (action != __BLK_TA_ISSUE)
return;
pio = hash_dispatched_io(trace->io);
@@ -1075,6 +1071,7 @@ void add_pending_io(struct trace *trace, struct graph_line_data *gld)
ios_in_flight++;
+ seconds = SECONDS(io->time);
gld->data[seconds].sum += ios_in_flight;
gld->data[seconds].count++;
@@ -1138,9 +1135,6 @@ void add_iop(struct trace *trace, struct graph_line_data *gld)
return;
seconds = SECONDS(io->time);
- if (seconds > gld->max_seconds)
- return;
-
gld->data[seconds].sum += 1;
gld->data[seconds].count = 1;
if (gld->data[seconds].sum > gld->max)
diff --git a/blkparse.h b/blkparse.h
index 84bda4a..fce9d01 100644
--- a/blkparse.h
+++ b/blkparse.h
@@ -72,9 +72,9 @@ struct trace_file {
char *filename;
char *label;
struct trace *trace;
- 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 */
+ unsigned int stop_seconds; /* Time when trace stops */
+ unsigned int min_seconds; /* Beginning of the interval we should plot */
+ unsigned int max_seconds; /* End of the interval we should plot */
u64 min_offset;
u64 max_offset;
@@ -99,9 +99,9 @@ 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;
+ unsigned int mpstat_min_seconds;
+ unsigned int mpstat_max_seconds;
+ unsigned int mpstat_stop_seconds;
struct graph_line_data **mpstat_gld;
};
@@ -133,5 +133,6 @@ void add_tput(struct trace *trace, struct graph_line_data *writes_gld,
struct graph_line_data *reads_gld);
void add_pending_io(struct trace *trace, struct graph_line_data *gld);
int next_record(struct trace *trace);
+u64 get_record_time(struct trace *trace);
void first_record(struct trace *trace);
#endif
diff --git a/fio.c b/fio.c
index 1fd2715..d10f8a2 100644
--- a/fio.c
+++ b/fio.c
@@ -198,7 +198,7 @@ int read_fio_event(struct trace *trace, int *time_ret, u64 *bw_ret, int *dir_ret
return 0;
}
-int add_fio_gld(int time, u64 bw, struct graph_line_data *gld)
+int add_fio_gld(unsigned int time, u64 bw, struct graph_line_data *gld)
{
double val;
diff --git a/fio.h b/fio.h
index e413ffa..31ee473 100644
--- a/fio.h
+++ b/fio.h
@@ -18,7 +18,7 @@
#define __FIO__
int read_fio_event(struct trace *trace, int *time, u64 *bw, int *dir);
-int add_fio_gld(int time, u64 bw, struct graph_line_data *gld);
+int add_fio_gld(unsigned int time, u64 bw, struct graph_line_data *gld);
int next_fio_line(struct trace *trace);
struct trace *open_fio_trace(char *path);
char *first_fio(struct trace *trace);
diff --git a/main.c b/main.c
index d23e3b2..5cbfa53 100644
--- a/main.c
+++ b/main.c
@@ -53,7 +53,7 @@ static int opt_graph_width = 0;
static int opt_graph_height = 0;
static int columns = 1;
-static int num_xticks = 7;
+static int num_xticks = 9;
static int num_yticks = 4;
static double min_time = 0;
@@ -414,7 +414,7 @@ static void read_trace_events(void)
struct trace *trace;
int ret;
int i;
- int time;
+ unsigned int time;
double user, sys, iowait, irq, soft;
double max_user = 0, max_sys = 0, max_iowait = 0,
max_irq = 0, max_soft = 0;
@@ -426,17 +426,16 @@ static void read_trace_events(void)
trace = tf->trace;
first_record(trace);
- while (1) {
+ do {
+ if (SECONDS(get_record_time(trace)) > tf->max_seconds)
+ continue;
check_record(trace);
add_tput(trace, tf->tput_writes_gld, tf->tput_reads_gld);
add_iop(trace, tf->iop_gld);
add_io(trace, tf);
add_pending_io(trace, tf->queue_depth_gld);
add_completed_io(trace, tf->latency_gld);
- ret = next_record(trace);
- if (ret)
- break;
- }
+ } while (!(ret = next_record(trace)));
}
list_for_each_entry(tf, &all_traces, list) {
trace = tf->trace;
@@ -446,7 +445,7 @@ static void read_trace_events(void)
first_mpstat(trace);
- for (time = 0; time < tf->mpstat_stop_seconds; time ++) {
+ for (time = 0; time < tf->mpstat_stop_seconds; time++) {
for (i = 0; i < (trace->mpstat_num_cpus + 1) * MPSTAT_GRAPHS; i += MPSTAT_GRAPHS) {
ret = read_mpstat_event(trace, &user, &sys,
&iowait, &irq, &soft);
@@ -532,7 +531,8 @@ static void set_blktrace_outfile(char *arg)
}
-static void compare_minmax_tf(struct trace_file *tf, int *max_seconds, u64 *min_offset, u64 *max_offset)
+static void compare_minmax_tf(struct trace_file *tf, unsigned int *max_seconds,
+ u64 *min_offset, u64 *max_offset)
{
if (tf->max_seconds > *max_seconds)
*max_seconds = tf->max_seconds;
@@ -542,7 +542,9 @@ 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 min_seconds, int max_seconds, u64 min_offset, u64 max_offset)
+static void set_all_minmax_tf(unsigned int min_seconds,
+ unsigned int max_seconds,
+ u64 min_offset, u64 max_offset)
{
struct trace_file *tf;
struct list_head *traces = &all_traces;
@@ -722,7 +724,8 @@ static int count_io_plot_types(void)
return total_io_types;
}
-static void plot_io(struct plot *plot, int min_seconds, int max_seconds, u64 min_offset, u64 max_offset)
+static void plot_io(struct plot *plot, unsigned int min_seconds,
+ unsigned int max_seconds, u64 min_offset, u64 max_offset)
{
struct trace_file *tf;
int i;
@@ -776,8 +779,8 @@ static void plot_io(struct plot *plot, int min_seconds, int max_seconds, u64 min
close_plot(plot);
}
-static void plot_tput(struct plot *plot, int min_seconds, int max_seconds,
- int with_legend)
+static void plot_tput(struct plot *plot, unsigned int min_seconds,
+ unsigned int max_seconds, int with_legend)
{
struct trace_file *tf;
char *units;
@@ -837,7 +840,8 @@ static void plot_tput(struct plot *plot, int min_seconds, int max_seconds,
total_graphs_written++;
}
-static void plot_fio_tput(struct plot *plot, int min_seconds, int max_seconds)
+static void plot_fio_tput(struct plot *plot,
+ unsigned int min_seconds, unsigned int max_seconds)
{
struct trace_file *tf;
char *units;
@@ -888,13 +892,13 @@ static void plot_fio_tput(struct plot *plot, int min_seconds, int max_seconds)
total_graphs_written++;
}
-static void plot_cpu(struct plot *plot, int max_seconds, char *label,
+static void plot_cpu(struct plot *plot, unsigned int max_seconds, char *label,
int active_index, int gld_index)
{
struct trace_file *tf;
int max = 0;
int i;
- int gld_i;
+ unsigned int gld_i;
char *color;
double avg = 0;
int ymax;
@@ -931,11 +935,11 @@ static void plot_cpu(struct plot *plot, int max_seconds, char *label,
list_for_each_entry(tf, &all_traces, list) {
if (tf->mpstat_gld == 0)
break;
- 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);
+ for (gld_i = tf->mpstat_gld[0]->min_seconds;
+ gld_i < tf->mpstat_gld[0]->stop_seconds; gld_i++) {
+ if (tf->mpstat_gld[gld_index]->data[gld_i].count) {
+ avg += (tf->mpstat_gld[gld_index]->data[gld_i].sum /
+ tf->mpstat_gld[gld_index]->data[gld_i].count);
}
}
avg /= tf->mpstat_gld[gld_index]->stop_seconds -
@@ -991,7 +995,8 @@ static void plot_cpu(struct plot *plot, int max_seconds, char *label,
total_graphs_written++;
}
-static void plot_queue_depth(struct plot *plot, int min_seconds, int max_seconds)
+static void plot_queue_depth(struct plot *plot, unsigned int min_seconds,
+ unsigned int max_seconds)
{
struct trace_file *tf;
@@ -1192,7 +1197,8 @@ static void plot_io_movie(struct plot *plot)
free(movie_dir);
}
-static void plot_latency(struct plot *plot, int min_seconds, int max_seconds)
+static void plot_latency(struct plot *plot, unsigned int min_seconds,
+ unsigned int max_seconds)
{
struct trace_file *tf;
char *units;
@@ -1238,7 +1244,8 @@ static void plot_latency(struct plot *plot, int min_seconds, int max_seconds)
total_graphs_written++;
}
-static void plot_iops(struct plot *plot, int min_seconds, int max_seconds)
+static void plot_iops(struct plot *plot, unsigned int min_seconds,
+ unsigned int max_seconds)
{
struct trace_file *tf;
char *units;
@@ -1568,8 +1575,8 @@ static void dest_mkdir(char *dir)
int main(int ac, char **av)
{
struct plot *plot;
- int min_seconds = 0;
- int max_seconds = 0;
+ unsigned int min_seconds = 0;
+ unsigned int max_seconds = 0;
u64 max_offset = 0;
u64 min_offset = ~(u64)0;
struct trace_file *tf;
diff --git a/plot.c b/plot.c
index d486f29..885fe05 100644
--- a/plot.c
+++ b/plot.c
@@ -127,7 +127,9 @@ void reset_cpu_color(void)
cpu_color_index = 0;
}
-struct graph_line_data *alloc_line_data(int min_seconds, int max_seconds, int stop_seconds)
+struct graph_line_data *alloc_line_data(unsigned int min_seconds,
+ unsigned int max_seconds,
+ unsigned int stop_seconds)
{
int size = sizeof(struct graph_line_data) + (stop_seconds + 1) * sizeof(struct graph_line_pair);
struct graph_line_data *gld;
@@ -149,7 +151,11 @@ void free_line_data(struct graph_line_data *gld)
free(gld);
}
-struct graph_dot_data *alloc_dot_data(int min_seconds, int max_seconds, u64 min_offset, u64 max_offset, int stop_seconds, char *color, char *label)
+struct graph_dot_data *alloc_dot_data(unsigned int min_seconds,
+ unsigned int max_seconds,
+ u64 min_offset, u64 max_offset,
+ unsigned int stop_seconds,
+ char *color, char *label)
{
int size;
int arr_size;
@@ -206,8 +212,10 @@ void set_gdd_bit(struct graph_dot_data *gdd, u64 offset, double bytes, double ti
if (offset > gdd->max_offset || offset < gdd->min_offset)
return;
- gdd->total_ios++;
time = time / 1000000000.0;
+ if (time < gdd->min_seconds || time > gdd->max_seconds)
+ return;
+ gdd->total_ios++;
while (bytes > 0 && offset <= gdd->max_offset) {
row = (double)(offset - gdd->min_offset) / bytes_per_row;
col = (time - gdd->min_seconds) / secs_per_col;
@@ -563,7 +571,7 @@ void set_xticks(struct plot *plot, int num_ticks, int first, int last)
* We don't want last two ticks to be too close together so subtract
* 20% of the step from the interval
*/
- num_ticks = (double)(last - first - step / 5) / step + 1;
+ num_ticks = (double)(last - first - step) / step + 1;
pixels_per_tick = graph_width * step / (double)(last - first);
for (i = 0; i < num_ticks; i++) {
@@ -807,7 +815,7 @@ void scale_line_graph_time(u64 *max, char **units)
int svg_line_graph(struct plot *plot, struct graph_line_data *gld, char *color, int thresh1, int thresh2)
{
- int i;
+ unsigned int i;
double val;
double avg;
int rolling;
diff --git a/plot.h b/plot.h
index f7dea5d..02e6529 100644
--- a/plot.h
+++ b/plot.h
@@ -69,12 +69,12 @@ struct graph_line_pair {
struct graph_line_data {
/* beginning of an interval displayed by this graph */
- int min_seconds;
+ unsigned int min_seconds;
/* end of an interval displayed by this graph */
- int max_seconds;
+ unsigned int max_seconds;
- int stop_seconds;
+ unsigned int stop_seconds;
/* Y max */
u64 max;
@@ -103,8 +103,8 @@ struct graph_dot_data {
int min_seconds;
/* end of an interval displayed by this graph */
- int max_seconds;
- int stop_seconds;
+ unsigned int max_seconds;
+ unsigned int stop_seconds;
/* label for the legend */
char *label;
@@ -138,9 +138,9 @@ char *pick_cpu_color(void);
void reset_cpu_color(void);
int svg_io_graph(struct plot *plot, struct graph_dot_data *gdd);
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 min_seconds, int max_seconds, int stop_seconds);
+struct graph_line_data *alloc_line_data(unsigned int min_seconds, unsigned int max_seconds, unsigned int stop_seconds);
void free_line_data(struct graph_line_data *gld);
-struct graph_dot_data *alloc_dot_data(int min_seconds, int max_seconds, u64 min_offset, u64 max_offset, int stop_seconds, char *color, char *label);
+struct graph_dot_data *alloc_dot_data(unsigned int min_seconds, unsigned int max_seconds, u64 min_offset, u64 max_offset, unsigned int stop_seconds, char *color, char *label);
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);