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 | ||
4c48f14e AB |
23 | static inline void __out(FILE *ofp, __u64 tm, enum iop_type type, |
24 | __u64 sec, __u32 nsec, int indent) | |
095181f2 | 25 | { |
4c48f14e AB |
26 | if (tm != (__u64)-1) { |
27 | if (indent) | |
28 | fprintf(ofp, " "); | |
29 | fprintf(ofp, "%5d.%09lu %c %10llu+%-4u\n", | |
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); | |
39 | __out(ofp, iop->i_time, IOP_I, iop->t.sector, t_sec(&iop->t), 1); | |
40 | __out(ofp, iop->gm_time, iop->is_getrq ? IOP_G : IOP_M, | |
41 | iop->t.sector, t_sec(&iop->t), 1); | |
42 | __out(ofp, iop->d_time, IOP_D, iop->d_sec, iop->d_nsec, 1); | |
43 | __out(ofp, iop->c_time, IOP_C, iop->c_sec, iop->c_nsec, 1); | |
44 | fprintf(ofp, "\n"); | |
095181f2 JA |
45 | } |
46 | ||
4c48f14e | 47 | static void handle_complete(struct io *c_iop) |
095181f2 JA |
48 | { |
49 | LIST_HEAD(head); | |
095181f2 | 50 | struct list_head *p, *q; |
095181f2 | 51 | |
4c48f14e AB |
52 | update_blks(c_iop); |
53 | update_cregion(&all_regions, c_iop->t.time); | |
54 | update_cregion(&c_iop->dip->regions, c_iop->t.time); | |
55 | if (c_iop->pip) | |
56 | update_cregion(&c_iop->pip->regions, c_iop->t.time); | |
a6c42403 | 57 | |
4c48f14e AB |
58 | dip_foreach_list(c_iop, IOP_Q, &head); |
59 | list_for_each_safe(p, q, &head) { | |
60 | struct io *q_iop = list_entry(p, struct io, f_head); | |
61 | __u64 q2c = tdelta(q_iop->t.time, c_iop->t.time); | |
62 | __u64 d2c = tdelta(q_iop->d_time, c_iop->t.time); | |
095181f2 | 63 | |
4c48f14e | 64 | c_iop->bytes_left -= q_iop->t.bytes; |
095181f2 | 65 | |
4c48f14e AB |
66 | update_q2c(q_iop, q2c); |
67 | latency_q2c(q_iop->dip, q_iop->t.time, q2c); | |
d76c5b81 | 68 | |
4c48f14e AB |
69 | update_d2c(q_iop, d2c); |
70 | latency_d2c(q_iop->dip, c_iop->t.time, d2c); | |
71 | iostat_complete(q_iop, c_iop); | |
d76c5b81 | 72 | |
4c48f14e AB |
73 | if (per_io_ofp) { |
74 | q_iop->c_time = c_iop->t.time; | |
75 | q_iop->c_sec = c_iop->t.sector; | |
76 | q_iop->c_nsec = t_sec(&c_iop->t); | |
77 | display_io_track(per_io_ofp, q_iop); | |
78 | } | |
d76c5b81 | 79 | |
4c48f14e AB |
80 | LIST_DEL(&q_iop->f_head); |
81 | io_release(q_iop); | |
095181f2 | 82 | } |
095181f2 JA |
83 | } |
84 | ||
d76c5b81 | 85 | void trace_complete(struct io *c_iop) |
095181f2 | 86 | { |
4c48f14e AB |
87 | if (io_setup(c_iop, IOP_C)) |
88 | handle_complete(c_iop); | |
d76c5b81 | 89 | |
4c48f14e | 90 | io_release(c_iop); |
095181f2 | 91 | } |