Merge branch 'master' of ssh://git.kernel.dk/data/git/blktrace
[blktrace.git] / btt / globals.h
CommitLineData
63eba147
JA
1/*
2 * blktrace output analysis: generate a timeline & gather statistics
3 *
4 * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21#include <assert.h>
22#include <stdio.h>
23#include <string.h>
6eb42155 24#include <time.h>
63eba147
JA
25
26#include "blktrace.h"
6eb42155 27#include "rbtree.h"
63eba147
JA
28#include "list.h"
29
63eba147
JA
30#define BIT_TIME(t) ((double)SECONDS(t) + ((double)NANO_SECONDS(t) / 1.0e9))
31
32#define BIT_START(iop) ((iop)->t.sector)
33#define BIT_END(iop) ((iop)->t.sector + ((iop)->t.bytes >> 9))
5225e788 34#define IOP_READ(iop) ((iop)->t.action & BLK_TC_ACT(BLK_TC_READ))
21e47d90 35#define IOP_RW(iop) (IOP_READ(iop) ? 1 : 0)
63eba147 36
b2ecdd0f
ADB
37#define TO_SEC(nanosec) ((double)(nanosec) / 1.0e9)
38#define TO_MSEC(nanosec) (1000.0 * TO_SEC(nanosec))
39
63eba147 40#if defined(DEBUG)
6eb42155 41#define DBG_PING() dbg_ping()
63eba147
JA
42#define ASSERT(truth) do { \
43 if (!(truth)) { \
44 DBG_PING(); \
45 assert(truth); \
46 } \
47 } while (0)
48
63eba147
JA
49
50#define LIST_DEL(hp) list_del(hp)
63eba147
JA
51#else
52#define ASSERT(truth)
53#define DBG_PING()
63eba147 54#define LIST_DEL(hp) do { \
d76c5b81
AB
55 ASSERT((hp)->next != NULL); \
56 ASSERT(!list_empty(hp)); \
57 list_del(hp); \
63eba147
JA
58 } while (0)
59#endif
60
63eba147
JA
61enum iop_type {
62 IOP_Q = 0,
63 IOP_X = 1,
64 IOP_A = 2,
d76c5b81 65 IOP_I = 3,
095181f2 66 IOP_M = 4,
d76c5b81
AB
67 IOP_D = 5,
68 IOP_C = 6,
69 IOP_R = 7,
70 IOP_L = 8, // IOP_A -> IOP_A + IOP_L
63eba147 71};
d76c5b81 72#define N_IOP_TYPES (IOP_L + 1)
63eba147 73
b2ecdd0f
ADB
74struct file_info {
75 struct file_info *next;
76 FILE *ofp;
6eb42155 77 char oname[1];
b2ecdd0f
ADB
78};
79
6eb42155
ADB
80struct mode {
81 int most_seeks, nmds;
82 long long *modes;
63eba147
JA
83};
84
85struct io;
86struct io_list {
87 struct list_head head;
88 struct io *iop;
89 int cy_users;
90};
91
92struct avg_info {
93 __u64 min, max, total;
94 double avg;
95 int n;
96};
97
98struct avgs_info {
99 struct avg_info q2q;
100 struct avg_info q2c;
101 struct avg_info q2a; /* Q to (A or X) */
102 struct avg_info q2i; /* Q to (I or M) */
103 struct avg_info i2d; /* (I or M) to D */
104 struct avg_info d2c;
105
106 struct avg_info blks; /* Blocks transferred */
107};
108
109struct range_info {
110 struct list_head head; /* on: qranges OR cranges */
111 __u64 start, end;
112};
113
114struct region_info {
115 struct list_head qranges;
116 struct list_head cranges;
117 struct range_info *qr_cur, *cr_cur;
118};
119
63eba147 120struct p_info {
63eba147
JA
121 struct region_info regions;
122 struct avgs_info avgs;
63eba147 123 __u64 last_q;
6eb42155
ADB
124 __u32 pid;
125 char name[1];
63eba147
JA
126};
127
128struct devmap {
129 struct devmap *next;
6eb42155 130 unsigned int host, bus, target, lun, irq, cpu;
63eba147 131 char model[64];
6eb42155 132 char device[32], node[32], pci[32], devno[32];
63eba147
JA
133};
134
21e47d90 135struct stats {
6eb42155 136 __u64 rqm[2], ios[2], sec[2], wait, svctm;
21e47d90 137 double last_qu_change, last_dev_change, tot_qusz, idle_time;
6eb42155 138 int cur_qusz, cur_dev;
21e47d90
ADB
139};
140
4a5cddba
JA
141struct stats_t {
142 double n;
143 double rqm_s[2], ios_s[2], sec_s[2];
144 double avgrq_sz, avgqu_sz, await, svctm, p_util;
145};
146
63eba147 147struct d_info {
6eb42155
ADB
148 struct list_head all_head, hash_head;
149 void *heads;
63eba147 150 struct region_info regions;
63eba147 151 struct devmap *map;
5225e788 152 void *seek_handle;
b2ecdd0f 153 FILE *d2c_ofp, *q2c_ofp;
6eb42155 154 struct avgs_info avgs;
21e47d90 155 struct stats stats, all_stats;
6eb42155
ADB
156 __u64 last_q, n_ds;
157 __u32 device;
63eba147
JA
158};
159
160struct io {
6eb42155 161 struct rb_node rb_node;
d76c5b81
AB
162 struct list_head f_head, c_pending, retry;
163 struct list_head down_list, up_list;
63eba147
JA
164 struct d_info *dip;
165 struct p_info *pip;
6eb42155 166 void *pdu;
d76c5b81
AB
167 struct blk_io_trace t;
168 __u64 bytes_left;
169 int linked, on_retry_list, down_len, up_len;
63eba147 170 enum iop_type type;
d76c5b81 171};
095181f2 172
d76c5b81
AB
173struct bilink {
174 struct list_head down_head, up_head;
175 struct io *diop, *uiop;
63eba147
JA
176};
177
6eb42155
ADB
178/* bt_timeline.c */
179
63eba147 180extern char bt_timeline_version[], *devices, *exes, *input_name, *output_name;
095181f2 181extern char *seek_name, *iostat_name, *d2c_name, *q2c_name, *per_io_name;
63eba147 182extern double range_delta;
095181f2 183extern FILE *ranges_ofp, *avgs_ofp, *iostat_ofp, *per_io_ofp;;
d76c5b81 184extern int verbose, done, time_bounded;
63eba147 185extern unsigned int n_devs;
6eb42155 186extern unsigned long n_traces;
095181f2 187extern struct list_head all_devs, all_procs, retries;
63eba147 188extern struct avgs_info all_avgs;
d76c5b81 189extern __u64 last_q, next_retry_check;
63eba147 190extern struct region_info all_regions;
6eb42155 191extern struct list_head free_ios;
21e47d90 192extern __u64 iostat_interval, iostat_last_stamp;
6eb42155 193extern time_t genesis, last_vtrace;
001b2633 194extern double t_astart, t_aend;
d76c5b81
AB
195#if defined(DEBUG)
196extern int rb_tree_size;
197#endif
63eba147 198
6eb42155 199/* args.c */
63eba147 200void handle_args(int argc, char *argv[]);
6eb42155
ADB
201
202/* dev_map.c */
63eba147 203int dev_map_read(char *fname);
6eb42155 204struct devmap *dev_map_find(__u32 device);
63eba147 205
6eb42155 206/* devs.c */
d76c5b81
AB
207#if defined(DEBUG)
208void dump_rb_trees(void);
209#endif
6eb42155 210void init_dev_heads(void);
095181f2 211struct d_info *dip_add(__u32 device, struct io *iop);
6eb42155
ADB
212void dip_rem(struct io *iop);
213struct d_info *__dip_find(__u32 device);
095181f2 214void dip_foreach_list(struct io *iop, enum iop_type type, struct list_head *hd);
6eb42155
ADB
215void dip_foreach(struct io *iop, enum iop_type type,
216 void (*fnc)(struct io *iop, struct io *this), int rm_after);
217struct io *dip_find_sec(struct d_info *dip, enum iop_type type, __u64 sec);
218void dip_foreach_out(void (*func)(struct d_info *, void *), void *arg);
219
220/* dip_rb.c */
095181f2 221int rb_insert(struct rb_root *root, struct io *iop);
6eb42155
ADB
222struct io *rb_find_sec(struct rb_root *root, __u64 sec);
223void rb_foreach(struct rb_node *n, struct io *iop,
224 void (*fnc)(struct io *iop, struct io *this),
225 struct list_head *head);
226
227/* iostat.c */
21e47d90
ADB
228void iostat_init(void);
229void iostat_insert(struct io *iop);
230void iostat_merge(struct io *iop);
231void iostat_issue(struct io *iop);
6eb42155
ADB
232void iostat_unissue(struct io *iop);
233void iostat_complete(struct io *d_iop, struct io *c_iop);
21e47d90
ADB
234void iostat_check_time(__u64 stamp);
235void iostat_dump_stats(__u64 stamp, int all);
236
6eb42155 237/* latency.c */
b2ecdd0f
ADB
238void latency_init(struct d_info *dip);
239void latency_clean(void);
240void latency_d2c(struct d_info *dip, __u64 tstamp, __u64 latency);
241void latency_q2c(struct d_info *dip, __u64 tstamp, __u64 latency);
242
6eb42155 243/* misc.c */
6eb42155 244int in_devices(struct blk_io_trace *t);
6eb42155
ADB
245void add_file(struct file_info **fipp, FILE *fp, char *oname);
246void clean_files(struct file_info **fipp);
247void dbg_ping(void);
248
d76c5b81
AB
249/* mmap.c */
250void setup_ifile(char *fname);
251void cleanup_ifile(void);
252int next_trace(struct blk_io_trace *t, void **pdu);
253
6eb42155
ADB
254/* output.c */
255int output_avgs(FILE *ofp);
256int output_ranges(FILE *ofp);
257char *make_dev_hdr(char *pad, size_t len, struct d_info *dip);
258
259/* proc.c */
260void add_process(__u32 pid, char *name);
261struct p_info *find_process(__u32 pid, char *name);
262void pip_update_q(struct io *iop);
263void pip_foreach_out(void (*f)(struct p_info *, void *), void *arg);
264
265/* seek.c */
266void *seeki_init(__u32 device);
267void seek_clean(void);
268void seeki_add(void *handle, struct io *iop);
269double seeki_mean(void *handle);
270long long seeki_nseeks(void *handle);
271long long seeki_median(void *handle);
272int seeki_mode(void *handle, struct mode *mp);
273
274/* trace.c */
d76c5b81
AB
275void __dump_iop(FILE *ofp, struct io *iop, int extra_nl);
276void __dump_iop2(FILE *ofp, struct io *a_iop, struct io *l_iop);
277void release_iops(struct list_head *rmhd);
6eb42155 278void add_trace(struct io *iop);
d76c5b81 279void do_retries(__u64 now);
6eb42155 280
095181f2
JA
281/* trace_complete.c */
282void trace_complete(struct io *c_iop);
d76c5b81 283void retry_complete(struct io *c_iop, __u64 now);
095181f2
JA
284
285/* trace_im.c */
d76c5b81
AB
286void run_im(struct io *im_iop, struct io *c_iop, void *param);
287void run_unim(struct io *im_iop, struct list_head *rmhd);
288int ready_im(struct io *im_iop, struct io *c_iop);
095181f2
JA
289void trace_insert(struct io *i_iop);
290void trace_merge(struct io *m_iop);
095181f2
JA
291
292/* trace_issue.c */
d76c5b81
AB
293void run_issue(struct io *d_iop, struct io *c_iop, void *param);
294void run_unissue(struct io *d_iop, struct list_head *rmhd);
295int ready_issue(struct io *d_iop, struct io *c_iop);
095181f2 296void trace_issue(struct io *d_iop);
095181f2
JA
297
298/* trace_queue.c */
d76c5b81
AB
299void run_queue(struct io *q_iop, struct io *c_iop, struct list_head *rmhd);
300int ready_queue(struct io *q_iop, struct io *c_iop);
095181f2 301void trace_queue(struct io *q_iop);
095181f2
JA
302
303/* trace_remap.c */
d76c5b81
AB
304void run_remap(struct io *a_iop, struct io *c_iop, void *param);
305int ready_remap(struct io *a_iop, struct io *c_iop);
095181f2 306void trace_remap(struct io *a_iop);
095181f2
JA
307
308/* trace_requeue.c */
309void trace_requeue(struct io *r_iop);
095181f2 310
63eba147 311#include "inlines.h"