2 * blktrace output analysis: generate a timeline & gather statistics
4 * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
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.
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.
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
23 typedef struct io *iop_t;
24 typedef iop_t (*iop_func_t)(__u64 *, struct io*);
26 struct io *iop_q_func(__u64 *timeline, struct io *iop);
27 struct io *iop_x_func(__u64 *timeline, struct io *iop);
28 struct io *iop_a_func(__u64 *timeline, struct io *iop);
29 struct io *iop_m_func(__u64 *timeline, struct io *iop);
30 struct io *iop_i_func(__u64 *timeline, struct io *iop);
31 struct io *iop_d_func(__u64 *timeline, struct io *iop);
32 struct io *iop_c_func(__u64 *timeline, struct io *iop);
33 struct io *iop_y_func(__u64 *timeline, struct io *iop);
35 iop_func_t traverse_func[] = {
46 void __traverse(__u64 *timeline, struct io *iop)
48 while (iop != NULL && !iop->traversed) {
50 iop = traverse_func[iop->type](timeline, iop);
54 void traverse(struct io *iop)
57 __u64 timeline[N_IOP_TYPES];
59 for (i = 0; i < N_IOP_TYPES; i++)
62 __traverse(timeline, iop);
65 void iop_q_update(__u64 *timeline, struct io *iop, __u64 q_time)
67 update_q2c(iop, timeline[IOP_C] - q_time);
69 if (timeline[IOP_A] > 0.0) // IOP_X too
70 update_q2a(iop, timeline[IOP_A] - q_time);
72 update_q2i(iop, timeline[IOP_I] - q_time);
74 update_i2d(iop, timeline[IOP_D] - timeline[IOP_I]);
75 update_d2c(iop, timeline[IOP_C] - timeline[IOP_D]);
78 struct io *iop_q_func(__u64 *timeline, struct io *iop)
80 timeline[IOP_Q] = iop->t.time;
81 iop_q_update(timeline, iop, iop->t.time);
83 if (iop->u.q.qp_type == Q_A)
84 return iop->u.q.qp.q_a;
85 else if (iop->u.q.qp_type == Q_X)
86 return iop->u.q.qp.q_x;
92 struct io *iop_x_func(__u64 *timeline, struct io *iop)
94 timeline[IOP_A] = iop->t.time; // Cover X & A in one slice
98 struct io *iop_a_func(__u64 *timeline, struct io *iop)
100 timeline[IOP_A] = iop->t.time;
104 struct io *iop_m_func(__u64 *timeline, struct io *iop)
106 timeline[IOP_I] = iop->t.time; // Cover M & I in one slice
110 struct io *iop_i_func(__u64 *timeline, struct io *iop)
113 struct io_list *iolp;
115 timeline[IOP_I] = iop->t.time;
116 __list_for_each(p, &iop->u.i.i_qs_head) {
117 iolp = list_entry(p, struct io_list, head);
118 __traverse(timeline, iolp->iop);
124 struct io *iop_d_func(__u64 *timeline, struct io *iop)
127 struct io_list *iolp;
129 timeline[IOP_D] = iop->t.time;
130 __list_for_each(p, &iop->u.d.d_im_head) {
131 iolp = list_entry(p, struct io_list, head);
132 __traverse(timeline, iolp->iop);
138 struct io *iop_c_func(__u64 *timeline, struct io *iop)
140 timeline[IOP_C] = iop->t.time;
144 struct io *iop_y_func(__u64 *timeline, struct io *iop)
146 timeline[IOP_Y] = iop->t.time;
147 __traverse(timeline, iop->u.y.y_c1);
148 __traverse(timeline, iop->u.y.y_c2);