| /* |
| * Copyright (C) 2012 Fusion-io |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public |
| * License v2 as published by the Free Software Foundation. |
| * |
| * This program 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, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| * |
| * Parts of this file were imported from Jens Axboe's blktrace sources (also GPL) |
| */ |
| #ifndef __IOWATCH_BLKPARSE__ |
| #define __IOWATCH_BLKPARSE__ |
| #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) |
| |
| struct dev_info { |
| u32 device; |
| u64 min; |
| u64 max; |
| u64 map; |
| }; |
| |
| #define MAX_DEVICES_PER_TRACE 64 |
| |
| struct trace { |
| int fd; |
| u64 len; |
| char *start; |
| char *cur; |
| struct blk_io_trace *io; |
| u64 start_timestamp; |
| struct timespec abs_start_time; |
| |
| /* |
| * flags for the things we find in the stream |
| * we prefer different events for different things |
| */ |
| int found_issue; |
| int found_completion; |
| int found_queue; |
| |
| char *mpstat_start; |
| char *mpstat_cur; |
| u64 mpstat_len; |
| int mpstat_fd; |
| int mpstat_seconds; |
| int mpstat_num_cpus; |
| |
| char *fio_start; |
| char *fio_cur; |
| u64 fio_len; |
| int fio_fd; |
| int fio_seconds; |
| int num_devices; |
| struct dev_info devices[MAX_DEVICES_PER_TRACE]; |
| }; |
| |
| struct trace_file { |
| struct list_head list; |
| 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 */ |
| u64 min_offset; |
| u64 max_offset; |
| |
| char *reads_color; |
| char *writes_color; |
| char *line_color; |
| |
| struct graph_line_data *tput_writes_gld; |
| struct graph_line_data *tput_reads_gld; |
| struct graph_line_data *iop_gld; |
| struct graph_line_data *latency_gld; |
| struct graph_line_data *queue_depth_gld; |
| |
| int fio_trace; |
| struct graph_line_data *fio_gld; |
| |
| /* Number of entries in gdd_writes / gdd_reads */ |
| int io_plots; |
| |
| /* Allocated array size for gdd_writes / gdd_reads */ |
| int io_plots_allocated; |
| 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; |
| }; |
| |
| static inline unsigned int MAJOR(unsigned int dev) |
| { |
| return dev >> MINORBITS; |
| } |
| |
| static inline unsigned int MINOR(unsigned int dev) |
| { |
| return dev & MINORMASK; |
| } |
| |
| void init_io_hash_table(void); |
| void init_process_hash_table(void); |
| struct trace *open_trace(char *filename); |
| u64 find_last_time(struct trace *trace); |
| void find_extreme_offsets(struct trace *trace, u64 *min_ret, u64 *max_ret, |
| u64 *max_bank_ret, u64 *max_offset_ret); |
| int filter_outliers(struct trace *trace, u64 min_offset, u64 max_offset, |
| u64 *yzoom_min, u64 *yzoom_max); |
| int action_char_to_num(char action); |
| void add_iop(struct trace *trace, struct graph_line_data *gld); |
| void check_record(struct trace *trace); |
| void add_completed_io(struct trace *trace, |
| struct graph_line_data *latency_gld); |
| void add_io(struct trace *trace, struct trace_file *tf); |
| 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); |
| void first_record(struct trace *trace); |
| #endif |