Commit | Line | Data |
---|---|---|
095181f2 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 | ||
8b10aae0 | 23 | static inline void __out(FILE *ofp, __u64 tm, enum iop_type type, |
4c48f14e | 24 | __u64 sec, __u32 nsec, int indent) |
095181f2 | 25 | { |
4c48f14e | 26 | if (tm != (__u64)-1) { |
8b10aae0 | 27 | if (indent) |
4c48f14e | 28 | fprintf(ofp, " "); |
8b10aae0 | 29 | fprintf(ofp, "%5d.%09lu %c %10llu+%-4u\n", |
4c48f14e AB |
30 | (int)SECONDS(tm), (unsigned long)NANO_SECONDS(tm), |
31 | type2c(type), (unsigned long long)sec, nsec); | |
a6c42403 | 32 | } |
4c48f14e | 33 | } |
d76c5b81 | 34 | |
4c48f14e AB |
35 | static void display_io_track(FILE *ofp, struct io *iop) |
36 | { | |
37 | fprintf(ofp, "%3d,%-3d: ", MAJOR(iop->t.device), MINOR(iop->t.device)); | |
38 | __out(ofp, iop->t.time, IOP_Q, iop->t.sector, t_sec(&iop->t), 0); | |
ae6d30f4 AB |
39 | |
40 | if (iop->g_time != (__u64)-1) | |
41 | __out(ofp, iop->g_time, IOP_G, iop->t.sector, t_sec(&iop->t),1); | |
42 | if (iop->i_time != (__u64)-1) | |
43 | __out(ofp, iop->i_time, IOP_I, iop->t.sector, t_sec(&iop->t),1); | |
44 | if (iop->m_time != (__u64)-1) | |
d00dcee7 | 45 | __out(ofp, iop->m_time, IOP_M, iop->t.sector, t_sec(&iop->t),1); |
ae6d30f4 | 46 | |
4c48f14e AB |
47 | __out(ofp, iop->d_time, IOP_D, iop->d_sec, iop->d_nsec, 1); |
48 | __out(ofp, iop->c_time, IOP_C, iop->c_sec, iop->c_nsec, 1); | |
49 | fprintf(ofp, "\n"); | |
095181f2 JA |
50 | } |
51 | ||
4c48f14e | 52 | static void handle_complete(struct io *c_iop) |
095181f2 JA |
53 | { |
54 | LIST_HEAD(head); | |
095181f2 | 55 | struct list_head *p, *q; |
a22df989 AB |
56 | __u64 d_time = (__u64)-1; |
57 | FILE *pit_fp = c_iop->dip->pit_fp; | |
dbb8d92d | 58 | double cur = BIT_TIME(c_iop->t.time); |
095181f2 | 59 | |
4c48f14e AB |
60 | update_blks(c_iop); |
61 | update_cregion(&all_regions, c_iop->t.time); | |
62 | update_cregion(&c_iop->dip->regions, c_iop->t.time); | |
63 | if (c_iop->pip) | |
64 | update_cregion(&c_iop->pip->regions, c_iop->t.time); | |
dbb8d92d AB |
65 | aqd_complete(c_iop->dip->aqd_handle, cur); |
66 | rstat_add(c_iop->dip->rstat_handle, cur, c_iop->t.bytes >> 9); | |
a6c42403 | 67 | |
4c48f14e AB |
68 | dip_foreach_list(c_iop, IOP_Q, &head); |
69 | list_for_each_safe(p, q, &head) { | |
70 | struct io *q_iop = list_entry(p, struct io, f_head); | |
71 | __u64 q2c = tdelta(q_iop->t.time, c_iop->t.time); | |
095181f2 | 72 | |
4c48f14e | 73 | c_iop->bytes_left -= q_iop->t.bytes; |
095181f2 | 74 | |
4c48f14e AB |
75 | update_q2c(q_iop, q2c); |
76 | latency_q2c(q_iop->dip, q_iop->t.time, q2c); | |
d76c5b81 | 77 | |
ae6d30f4 AB |
78 | if (q_iop->d_time != (__u64)-1) { |
79 | __u64 d2c = tdelta(q_iop->d_time, c_iop->t.time); | |
80 | ||
81 | update_d2c(q_iop, d2c); | |
82 | latency_d2c(q_iop->dip, c_iop->t.time, d2c); | |
83 | iostat_complete(q_iop, c_iop); | |
a22df989 AB |
84 | |
85 | d_time = q_iop->d_time; | |
ae6d30f4 | 86 | } |
d76c5b81 | 87 | |
4c48f14e AB |
88 | if (per_io_ofp) { |
89 | q_iop->c_time = c_iop->t.time; | |
90 | q_iop->c_sec = c_iop->t.sector; | |
91 | q_iop->c_nsec = t_sec(&c_iop->t); | |
92 | display_io_track(per_io_ofp, q_iop); | |
93 | } | |
d76c5b81 | 94 | |
a22df989 AB |
95 | if (q_iop->dip->pit_fp) { |
96 | fprintf(pit_fp, "%d.%09lu ", | |
97 | (int)SECONDS(q_iop->t.time), | |
98 | (unsigned long)NANO_SECONDS(q_iop->t.time)); | |
99 | } | |
100 | ||
8b10aae0 | 101 | list_del(&q_iop->f_head); |
4c48f14e | 102 | io_release(q_iop); |
095181f2 | 103 | } |
d00dcee7 AB |
104 | |
105 | if (per_io_ofp) | |
106 | fprintf(per_io_ofp, | |
107 | "-----------------------------------------\n"); | |
a22df989 AB |
108 | |
109 | if (c_iop->dip->pit_fp) { | |
110 | fprintf(pit_fp, "| %d.%09lu | %d.%09lu\n", | |
111 | (int)SECONDS(d_time), | |
112 | (unsigned long)NANO_SECONDS(d_time), | |
113 | (int)SECONDS(c_iop->t.time), | |
114 | (unsigned long)NANO_SECONDS(c_iop->t.time)); | |
115 | } | |
095181f2 JA |
116 | } |
117 | ||
d76c5b81 | 118 | void trace_complete(struct io *c_iop) |
095181f2 | 119 | { |
354db430 AB |
120 | if (c_iop->t.bytes == 0) |
121 | return; | |
122 | ||
4c48f14e AB |
123 | if (io_setup(c_iop, IOP_C)) |
124 | handle_complete(c_iop); | |
d76c5b81 | 125 | |
4c48f14e | 126 | io_release(c_iop); |
095181f2 | 127 | } |