[PATCH] BTT patch: (1/3) 'iostat' totals
[blktrace.git] / btt / trace.c
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 "globals.h"
22
6eb42155 23void im2d_func(struct io *d_iop, struct io *im_iop)
63eba147 24{
6eb42155 25 update_i2d(im_iop, d_iop->t.time - im_iop->t.time);
63eba147
JA
26}
27
6eb42155 28void q2c_func(struct io *c_iop, struct io *q_iop)
63eba147 29{
6eb42155 30 __u64 q2c = c_iop->t.time - q_iop->t.time;
63eba147 31
6eb42155
ADB
32 update_q2c(q_iop, q2c);
33 latency_q2c(q_iop->dip, q_iop->t.time, q2c);
63eba147
JA
34}
35
6eb42155 36static inline void handle_im(struct io *im_iop)
63eba147
JA
37{
38 struct io *q_iop;
63eba147 39
6eb42155
ADB
40 q_iop = dip_find_sec(im_iop->dip, IOP_Q, BIT_START(im_iop));
41 if (q_iop)
42 update_q2i(q_iop, im_iop->t.time - q_iop->t.time);
63eba147
JA
43}
44
6eb42155 45void handle_queue(struct io *q_iop)
63eba147 46{
6eb42155
ADB
47 io_setup(q_iop, IOP_Q, 1);
48 update_lq(&last_q, &all_avgs.q2q, q_iop->t.time);
49 update_qregion(&all_regions, q_iop->t.time);
50 dip_update_q(q_iop->dip, q_iop);
51 pip_update_q(q_iop);
63eba147
JA
52}
53
6eb42155 54void handle_remap(struct io *a_iop)
63eba147
JA
55{
56 struct io *q_iop;
6eb42155
ADB
57 struct blk_io_trace_remap *rp = a_iop->pdu;
58 struct d_info *dip = __dip_find(be32_to_cpu(rp->device));
63eba147 59
6eb42155 60 io_setup(a_iop, IOP_A, 0);
b22050b5
AB
61 if (dip) {
62 q_iop = dip_find_sec(dip, IOP_Q, be64_to_cpu(rp->sector));
63 if (q_iop)
64 update_q2a(q_iop, a_iop->t.time - q_iop->t.time);
65 }
6eb42155 66 io_release(a_iop);
63eba147
JA
67}
68
6eb42155 69void handle_insert(struct io *i_iop)
63eba147 70{
6eb42155
ADB
71 io_setup(i_iop, IOP_I, 1);
72 iostat_insert(i_iop);
73 handle_im(i_iop);
63eba147
JA
74}
75
6eb42155 76void handle_merge(struct io *m_iop)
63eba147 77{
6eb42155
ADB
78 io_setup(m_iop, IOP_M, 1);
79 iostat_merge(m_iop);
80 handle_im(m_iop);
63eba147
JA
81}
82
6eb42155 83void handle_issue(struct io *d_iop)
63eba147 84{
6eb42155
ADB
85 io_setup(d_iop, IOP_D, 1);
86 d_iop->dip->n_ds++;
63eba147 87
6eb42155
ADB
88 dip_foreach(d_iop, IOP_I, im2d_func, 0);
89 dip_foreach(d_iop, IOP_M, im2d_func, 0);
63eba147 90
6eb42155
ADB
91 if (seek_name)
92 seeki_add(d_iop->dip->seek_handle, d_iop);
93 iostat_issue(d_iop);
63eba147
JA
94}
95
6eb42155 96void handle_complete(struct io *c_iop)
63eba147 97{
6eb42155 98 struct io *d_iop;
63eba147 99
6eb42155
ADB
100 io_setup(c_iop, IOP_C, 0);
101 update_blks(c_iop);
102 update_cregion(&all_regions, c_iop->t.time);
103 update_cregion(&c_iop->dip->regions, c_iop->t.time);
104 if (c_iop->pip)
105 update_cregion(&c_iop->pip->regions, c_iop->t.time);
63eba147 106
6eb42155
ADB
107 d_iop = dip_find_sec(c_iop->dip, IOP_D, BIT_START(c_iop));
108 if (d_iop) {
109 __u64 d2c = c_iop->t.time - d_iop->t.time;
110 update_d2c(d_iop, d2c);
111 latency_d2c(d_iop->dip, c_iop->t.time, d2c);
112 iostat_complete(d_iop, c_iop);
113 dip_foreach(d_iop, IOP_I, NULL, 1);
114 dip_foreach(d_iop, IOP_M, NULL, 1);
115 io_release(d_iop);
63eba147 116 }
97d13fb0 117
6eb42155
ADB
118 dip_foreach(c_iop, IOP_Q, q2c_func, 1);
119 io_release(c_iop);
63eba147
JA
120}
121
6eb42155 122void rq_im2d_func(struct io *d_iop, struct io *im_iop)
63eba147 123{
6eb42155 124 unupdate_i2d(im_iop, d_iop->t.time - im_iop->t.time);
63eba147
JA
125}
126
127/*
128 * Careful surgery
129 * (1) Need to remove D & its I & M's
6eb42155
ADB
130 * (2) Need to leave I's Q and M's Q's
131 * (3) XXX: Need to downward adjust stats, but we don't carry PREVIOUS
132 * XXX: min/maxes?! We'll just adjust what we can, and hope that
133 * XXX: the min/maxes are "pretty close". (REQUEUEs are rare, right?)
63eba147 134 */
6eb42155 135void handle_requeue(struct io *r_iop)
63eba147
JA
136{
137 struct io *d_iop;
63eba147 138
6eb42155
ADB
139 io_setup(r_iop, IOP_R, 0);
140 d_iop = dip_find_sec(r_iop->dip, IOP_D, BIT_START(r_iop));
63eba147 141 if (d_iop) {
6eb42155
ADB
142 dip_foreach(d_iop, IOP_I, rq_im2d_func, 1);
143 dip_foreach(d_iop, IOP_M, rq_im2d_func, 1);
144 iostat_unissue(d_iop);
145 io_release(d_iop);
63eba147 146 }
6eb42155 147 io_release(r_iop);
63eba147
JA
148}
149
150void __add_trace(struct io *iop)
151{
6eb42155 152 time_t now = time(NULL);
63eba147 153
6eb42155 154 n_traces++;
21e47d90 155 iostat_check_time(iop->t.time);
6eb42155
ADB
156
157 if (verbose && ((now - last_vtrace) > 0)) {
158 printf("%10lu t\r", n_traces);
63eba147 159 if ((n_traces % 1000000) == 0) printf("\n");
6eb42155
ADB
160 fflush(stdout);
161 last_vtrace = now;
63eba147
JA
162 }
163
164 switch (iop->t.action & 0xffff) {
6eb42155
ADB
165 case __BLK_TA_QUEUE: handle_queue(iop); break;
166 case __BLK_TA_BACKMERGE: handle_merge(iop); break;
167 case __BLK_TA_FRONTMERGE: handle_merge(iop); break;
168 case __BLK_TA_ISSUE: handle_issue(iop); break;
169 case __BLK_TA_COMPLETE: handle_complete(iop); break;
170 case __BLK_TA_INSERT: handle_insert(iop); break;
171 case __BLK_TA_REMAP: handle_remap(iop); break;
172 case __BLK_TA_REQUEUE: handle_requeue(iop); break;
173 default: io_release(iop); break;
63eba147
JA
174 }
175}
176
177void add_trace(struct io *iop)
178{
179 if (iop->t.action & BLK_TC_ACT(BLK_TC_NOTIFY)) {
180 char *slash = strchr(iop->pdu, '/');
181
182 if (slash)
183 *slash = '\0';
6eb42155 184
63eba147 185 add_process(iop->t.pid, iop->pdu);
6eb42155 186 io_release(iop);
63eba147 187 }
f8d501e1 188 else if (iop->t.action & BLK_TC_ACT(BLK_TC_PC))
6eb42155 189 io_release(iop);
63eba147
JA
190 else
191 __add_trace(iop);
192}