1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * blktrace output analysis: generate a timeline & gather statistics 3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com> 5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This program is free software; you can redistribute it and/or modify 7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * it under the terms of the GNU General Public License as published by 8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * the Free Software Foundation; either version 2 of the License, or 9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * (at your option) any later version. 10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This program is distributed in the hope that it will be useful, 12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of 13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * GNU General Public License for more details. 15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * You should have received a copy of the GNU General Public License 17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * along with this program; if not, write to the Free Software 18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "globals.h" 22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __out(FILE *ofp, __u64 tm, enum iop_type type, 24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 sec, __u32 nsec, int indent) 25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (tm != (__u64)-1) { 27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (indent) 28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " "); 29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "%5d.%09lu %c %10llu+%-4u\n", 30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (int)SECONDS(tm), (unsigned long)NANO_SECONDS(tm), 31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat type2c(type), (unsigned long long)sec, nsec); 32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void display_io_track(FILE *ofp, struct io *iop) 36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "%3d,%-3d: ", MAJOR(iop->t.device), MINOR(iop->t.device)); 38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __out(ofp, iop->t.time, IOP_Q, iop->t.sector, t_sec(&iop->t), 0); 39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (iop->g_time != (__u64)-1) 41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __out(ofp, iop->g_time, IOP_G, iop->t.sector, t_sec(&iop->t),1); 42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (iop->i_time != (__u64)-1) 43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __out(ofp, iop->i_time, IOP_I, iop->t.sector, t_sec(&iop->t),1); 44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (iop->m_time != (__u64)-1) 45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __out(ofp, iop->m_time, IOP_M, iop->t.sector, t_sec(&iop->t),1); 46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __out(ofp, iop->d_time, IOP_D, iop->d_sec, iop->d_nsec, 1); 48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __out(ofp, iop->c_time, IOP_C, iop->c_sec, iop->c_nsec, 1); 49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "\n"); 50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void handle_complete(struct io *c_iop) 53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat LIST_HEAD(head); 55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head *p, *q; 56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 d_time = (__u64)-1; 57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat FILE *pit_fp = c_iop->dip->pit_fp; 58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_blks(c_iop); 60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_cregion(&all_regions, c_iop->t.time); 61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_cregion(&c_iop->dip->regions, c_iop->t.time); 62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (c_iop->pip) 63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_cregion(&c_iop->pip->regions, c_iop->t.time); 64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat aqd_complete(c_iop->dip->aqd_handle, BIT_TIME(c_iop->t.time)); 65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dip_foreach_list(c_iop, IOP_Q, &head); 67e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_for_each_safe(p, q, &head) { 68e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io *q_iop = list_entry(p, struct io, f_head); 69e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 q2c = tdelta(q_iop->t.time, c_iop->t.time); 70e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 71e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat c_iop->bytes_left -= q_iop->t.bytes; 72e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 73e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_q2c(q_iop, q2c); 74e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat latency_q2c(q_iop->dip, q_iop->t.time, q2c); 75e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 76e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (q_iop->d_time != (__u64)-1) { 77e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 d2c = tdelta(q_iop->d_time, c_iop->t.time); 78e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 79e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_d2c(q_iop, d2c); 80e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat latency_d2c(q_iop->dip, c_iop->t.time, d2c); 81e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iostat_complete(q_iop, c_iop); 82e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 83e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat d_time = q_iop->d_time; 84e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 85e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 86e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_io_ofp) { 87e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat q_iop->c_time = c_iop->t.time; 88e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat q_iop->c_sec = c_iop->t.sector; 89e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat q_iop->c_nsec = t_sec(&c_iop->t); 90e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat display_io_track(per_io_ofp, q_iop); 91e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 92e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 93e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (q_iop->dip->pit_fp) { 94e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(pit_fp, "%d.%09lu ", 95e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (int)SECONDS(q_iop->t.time), 96e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long)NANO_SECONDS(q_iop->t.time)); 97e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 98e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 99e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_del(&q_iop->f_head); 100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat io_release(q_iop); 101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_io_ofp) 104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(per_io_ofp, 105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "-----------------------------------------\n"); 106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (c_iop->dip->pit_fp) { 108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(pit_fp, "| %d.%09lu | %d.%09lu\n", 109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (int)SECONDS(d_time), 110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long)NANO_SECONDS(d_time), 111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (int)SECONDS(c_iop->t.time), 112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long)NANO_SECONDS(c_iop->t.time)); 113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid trace_complete(struct io *c_iop) 117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (c_iop->t.bytes == 0) 119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (io_setup(c_iop, IOP_C)) 122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat handle_complete(c_iop); 123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat io_release(c_iop); 125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 126