| 1 | /* |
| 2 | * Copyright (C) 2012 Fusion-io |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of the GNU General Public |
| 6 | * License v2 as published by the Free Software Foundation. |
| 7 | * |
| 8 | * This program is distributed in the hope that it will be useful, |
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | * GNU General Public License for more details. |
| 12 | * |
| 13 | * You should have received a copy of the GNU General Public License |
| 14 | * along with this program; if not, write to the Free Software |
| 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 16 | * |
| 17 | * Parts of this file were imported from Jens Axboe's blktrace sources (also GPL) |
| 18 | */ |
| 19 | #ifndef __IOWATCH_BLKPARSE__ |
| 20 | #define __IOWATCH_BLKPARSE__ |
| 21 | #define MINORBITS 20 |
| 22 | #define MINORMASK ((1 << MINORBITS) - 1) |
| 23 | #define SECONDS(x) ((unsigned long long)(x) / 1000000000) |
| 24 | #define NANO_SECONDS(x) ((unsigned long long)(x) % 1000000000) |
| 25 | #define DOUBLE_TO_NANO_ULL(d) ((unsigned long long)((d) * 1000000000)) |
| 26 | #define CHECK_MAGIC(t) (((t)->magic & 0xffffff00) == BLK_IO_TRACE_MAGIC) |
| 27 | |
| 28 | struct dev_info { |
| 29 | u32 device; |
| 30 | u64 min; |
| 31 | u64 max; |
| 32 | u64 map; |
| 33 | }; |
| 34 | |
| 35 | #define MAX_DEVICES_PER_TRACE 64 |
| 36 | |
| 37 | struct trace { |
| 38 | int fd; |
| 39 | u64 len; |
| 40 | char *start; |
| 41 | char *cur; |
| 42 | struct blk_io_trace *io; |
| 43 | u64 start_timestamp; |
| 44 | struct timespec abs_start_time; |
| 45 | |
| 46 | /* |
| 47 | * flags for the things we find in the stream |
| 48 | * we prefer different events for different things |
| 49 | */ |
| 50 | int found_issue; |
| 51 | int found_completion; |
| 52 | int found_queue; |
| 53 | |
| 54 | char *mpstat_start; |
| 55 | char *mpstat_cur; |
| 56 | u64 mpstat_len; |
| 57 | int mpstat_fd; |
| 58 | int mpstat_seconds; |
| 59 | int mpstat_num_cpus; |
| 60 | |
| 61 | char *fio_start; |
| 62 | char *fio_cur; |
| 63 | u64 fio_len; |
| 64 | int fio_fd; |
| 65 | int fio_seconds; |
| 66 | int num_devices; |
| 67 | struct dev_info devices[MAX_DEVICES_PER_TRACE]; |
| 68 | }; |
| 69 | |
| 70 | struct trace_file { |
| 71 | struct list_head list; |
| 72 | char *filename; |
| 73 | char *label; |
| 74 | struct trace *trace; |
| 75 | unsigned int stop_seconds; /* Time when trace stops */ |
| 76 | unsigned int min_seconds; /* Beginning of the interval we should plot */ |
| 77 | unsigned int max_seconds; /* End of the interval we should plot */ |
| 78 | u64 min_offset; |
| 79 | u64 max_offset; |
| 80 | |
| 81 | char *reads_color; |
| 82 | char *writes_color; |
| 83 | char *line_color; |
| 84 | |
| 85 | struct graph_line_data *tput_writes_gld; |
| 86 | struct graph_line_data *tput_reads_gld; |
| 87 | struct graph_line_data *iop_gld; |
| 88 | struct graph_line_data *latency_gld; |
| 89 | struct graph_line_data *queue_depth_gld; |
| 90 | |
| 91 | int fio_trace; |
| 92 | struct graph_line_data *fio_gld; |
| 93 | |
| 94 | /* Number of entries in gdd_writes / gdd_reads */ |
| 95 | int io_plots; |
| 96 | |
| 97 | /* Allocated array size for gdd_writes / gdd_reads */ |
| 98 | int io_plots_allocated; |
| 99 | struct graph_dot_data **gdd_writes; |
| 100 | struct graph_dot_data **gdd_reads; |
| 101 | |
| 102 | unsigned int mpstat_min_seconds; |
| 103 | unsigned int mpstat_max_seconds; |
| 104 | unsigned int mpstat_stop_seconds; |
| 105 | struct graph_line_data **mpstat_gld; |
| 106 | }; |
| 107 | |
| 108 | static inline unsigned int MAJOR(unsigned int dev) |
| 109 | { |
| 110 | return dev >> MINORBITS; |
| 111 | } |
| 112 | |
| 113 | static inline unsigned int MINOR(unsigned int dev) |
| 114 | { |
| 115 | return dev & MINORMASK; |
| 116 | } |
| 117 | |
| 118 | void init_io_hash_table(void); |
| 119 | void init_process_hash_table(void); |
| 120 | struct trace *open_trace(char *filename); |
| 121 | u64 find_last_time(struct trace *trace); |
| 122 | void find_extreme_offsets(struct trace *trace, u64 *min_ret, u64 *max_ret, |
| 123 | u64 *max_bank_ret, u64 *max_offset_ret); |
| 124 | int filter_outliers(struct trace *trace, u64 min_offset, u64 max_offset, |
| 125 | u64 *yzoom_min, u64 *yzoom_max); |
| 126 | int action_char_to_num(char action); |
| 127 | void add_iop(struct trace *trace, struct graph_line_data *gld); |
| 128 | void check_record(struct trace *trace); |
| 129 | void add_completed_io(struct trace *trace, |
| 130 | struct graph_line_data *latency_gld); |
| 131 | void add_io(struct trace *trace, struct trace_file *tf); |
| 132 | void add_tput(struct trace *trace, struct graph_line_data *writes_gld, |
| 133 | struct graph_line_data *reads_gld); |
| 134 | void add_pending_io(struct trace *trace, struct graph_line_data *gld); |
| 135 | int next_record(struct trace *trace); |
| 136 | u64 get_record_time(struct trace *trace); |
| 137 | void first_record(struct trace *trace); |
| 138 | #endif |