1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * block queue tracing parse application 3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Copyright (C) 2005 Jens Axboe <axboe@suse.de> 5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk> 6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This program is free software; you can redistribute it and/or modify 8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * it under the terms of the GNU General Public License as published by 9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * the Free Software Foundation; either version 2 of the License, or 10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * (at your option) any later version. 11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This program is distributed in the hope that it will be useful, 13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of 14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * GNU General Public License for more details. 16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * You should have received a copy of the GNU General Public License 18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * along with this program; if not, write to the Free Software 19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sys/types.h> 23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sys/stat.h> 24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <unistd.h> 25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <stdio.h> 26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <fcntl.h> 27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <stdlib.h> 28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <string.h> 29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <getopt.h> 30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <errno.h> 31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <signal.h> 32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <locale.h> 33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <libgen.h> 34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "blktrace.h" 36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "rbtree.h" 37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "jhash.h" 38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char blkparse_version[] = "1.0.1"; 40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct skip_info { 42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long start, end; 43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct skip_info *prev, *next; 44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct per_dev_info { 47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dev_t dev; 48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *name; 49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int backwards; 51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long events; 52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long first_reported_time; 53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long last_reported_time; 54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long last_read_time; 55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats io_stats; 56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long skips; 57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long seq_skips; 58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int max_depth[2]; 59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int cur_depth[2]; 60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_root rb_track; 62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int nfiles; 64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int ncpus; 65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long *cpu_map; 67e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int cpu_map_max; 68e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 69e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *cpus; 70e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 71e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 72e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 73e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * some duplicated effort here, we can unify this hash and the ppi hash later 74e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 75e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct process_pid_map { 76e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pid_t pid; 77e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char comm[16]; 78e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *hash_next, *list_next; 79e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 80e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 81e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define PPM_HASH_SHIFT (8) 82e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define PPM_HASH_SIZE (1 << PPM_HASH_SHIFT) 83e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define PPM_HASH_MASK (PPM_HASH_SIZE - 1) 84e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct process_pid_map *ppm_hash_table[PPM_HASH_SIZE]; 85e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 86e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct per_process_info { 87e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm; 88e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats io_stats; 89e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *hash_next, *list_next; 90e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int more_than_one; 91e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 92e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 93e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * individual io stats 94e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 95e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long longest_allocation_wait[2]; 96e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long longest_dispatch_wait[2]; 97e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long longest_completion_wait[2]; 98e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 99e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define PPI_HASH_SHIFT (8) 101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define PPI_HASH_SIZE (1 << PPI_HASH_SHIFT) 102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define PPI_HASH_MASK (PPI_HASH_SIZE - 1) 103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct per_process_info *ppi_hash_table[PPI_HASH_SIZE]; 104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct per_process_info *ppi_list; 105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int ppi_list_entries; 106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct option l_opts[] = { 108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "act-mask", 110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'a' 113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "set-mask", 116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'A' 119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "batch", 122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'b' 125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "input-directory", 128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'D' 131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "dump-binary", 134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'd' 137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "format", 140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'f' 143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "format-spec", 146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'F' 149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "hash-by-name", 152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'h' 155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "input", 158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'i' 161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "no-msgs", 164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'M' 167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "output", 170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'o' 173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "no-text-output", 176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'O' 179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "quiet", 182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'q' 185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "per-program-stats", 188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 's' 191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "track-ios", 194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 't' 197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "stopwatch", 200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'w' 203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "verbose", 206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'v' 209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "version", 212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'V' 215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = NULL, 218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * for sorting the displayed output 223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct trace { 225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *bit; 226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node rb_node; 227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *next; 228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long read_sequence; 229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct rb_root rb_sort_root; 232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long rb_sort_entries; 233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct trace *trace_list; 235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * allocation cache 238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct blk_io_trace *bit_alloc_list; 240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct trace *t_alloc_list; 241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * for tracking individual ios 244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct io_track { 246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node rb_node; 247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm; 249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 sector; 250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long allocation_time; 251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long queue_time; 252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long dispatch_time; 253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long completion_time; 254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int ndevices; 257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct per_dev_info *devices; 258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *get_dev_name(struct per_dev_info *, char *, int); 259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int trace_rb_insert_last(struct per_dev_info *, struct trace *); 260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San MehatFILE *ofp = NULL; 262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *output_name; 263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *input_dir; 264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long long genesis_time; 266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long long last_allowed_time; 267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long long stopwatch_start; /* start from zero by default */ 268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long long stopwatch_end = -1ULL; /* "infinity" */ 269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long read_sequence; 270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int per_process_stats; 272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int per_device_and_cpu_stats = 1; 273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int track_ios; 274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int ppi_hash_by_pid = 1; 275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int verbose; 276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned int act_mask = -1U; 277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int stats_printed; 278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int bin_output_msgs = 1; 279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint data_is_native = -1; 280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic FILE *dump_fp; 282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *dump_binary; 283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned int t_alloc_cache; 285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned int bit_alloc_cache; 286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define RB_BATCH_DEFAULT (512) 288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned int rb_batch = RB_BATCH_DEFAULT; 289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int pipeline; 291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *pipename; 292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int text_output = 1; 294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define is_done() (*(volatile int *)(&done)) 296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic volatile int done; 297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct timespec abs_start_time; 299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long long start_timestamp; 300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int have_drv_data = 0; 302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define JHASH_RANDOM (0x3af5f2ee) 304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define CPUS_PER_LONG (8 * sizeof(unsigned long)) 306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define CPU_IDX(cpu) ((cpu) / CPUS_PER_LONG) 307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define CPU_BIT(cpu) ((cpu) & (CPUS_PER_LONG - 1)) 308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void output_binary(void *buf, int len) 310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (dump_binary) { 312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat size_t n = fwrite(buf, len, 1, dump_fp); 313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (n != 1) { 314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror(dump_binary); 315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fclose(dump_fp); 316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_binary = NULL; 317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void resize_cpu_info(struct per_dev_info *pdi, int cpu) 322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *cpus = pdi->cpus; 324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int ncpus = pdi->ncpus; 325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int new_count = cpu + 1; 326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int new_space, size; 327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *new_start; 328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat size = new_count * sizeof(struct per_cpu_info); 330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpus = realloc(cpus, size); 331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!cpus) { 332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char name[20]; 333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Out of memory, CPU info for device %s (%d)\n", 334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat get_dev_name(pdi, name, sizeof(name)), size); 335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exit(1); 336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat new_start = (char *)cpus + (ncpus * sizeof(struct per_cpu_info)); 339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat new_space = (new_count - ncpus) * sizeof(struct per_cpu_info); 340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(new_start, 0, new_space); 341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->ncpus = new_count; 343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cpus = cpus; 344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (new_count = 0; new_count < pdi->ncpus; new_count++) { 346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci = &pdi->cpus[new_count]; 347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pci->fd) { 349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->fd = -1; 350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(&pci->rb_last, 0, sizeof(pci->rb_last)); 351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->rb_last_entries = 0; 352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->last_sequence = -1; 353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct per_cpu_info *get_cpu_info(struct per_dev_info *pdi, int cpu) 358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci; 360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (cpu >= pdi->ncpus) 362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat resize_cpu_info(pdi, cpu); 363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci = &pdi->cpus[cpu]; 365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->cpu = cpu; 366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return pci; 367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int resize_devices(char *name) 371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int size = (ndevices + 1) * sizeof(struct per_dev_info); 373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat devices = realloc(devices, size); 375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!devices) { 376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Out of memory, device %s (%d)\n", name, size); 377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(&devices[ndevices], 0, sizeof(struct per_dev_info)); 380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat devices[ndevices].name = name; 381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ndevices++; 382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 384e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 385e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct per_dev_info *get_dev_info(dev_t dev) 386e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 387e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi; 388e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i; 389e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 390e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0; i < ndevices; i++) { 391e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!devices[i].dev) 392e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat devices[i].dev = dev; 393e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (devices[i].dev == dev) 394e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return &devices[i]; 395e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 396e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 397e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (resize_devices(NULL)) 398e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 399e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 400e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi = &devices[ndevices - 1]; 401e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->dev = dev; 402e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->first_reported_time = 0; 403e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->last_read_time = 0; 404e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 405e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return pdi; 406e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 407e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 408e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void insert_skip(struct per_cpu_info *pci, unsigned long start, 409e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long end) 410e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 411e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct skip_info *sip; 412e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 413e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (sip = pci->skips_tail; sip != NULL; sip = sip->prev) { 414e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (end == (sip->start - 1)) { 415e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->start = start; 416e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 417e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else if (start == (sip->end + 1)) { 418e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->end = end; 419e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 420e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 421e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 422e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 423e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip = malloc(sizeof(struct skip_info)); 424e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->start = start; 425e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->end = end; 426e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->prev = sip->next = NULL; 427e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pci->skips_tail == NULL) 428e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->skips_head = pci->skips_tail = sip; 429e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 430e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->prev = pci->skips_tail; 431e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->skips_tail->next = sip; 432e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->skips_tail = sip; 433e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 434e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 435e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 436e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void remove_sip(struct per_cpu_info *pci, struct skip_info *sip) 437e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 438e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sip->prev == NULL) { 439e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sip->next == NULL) 440e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->skips_head = pci->skips_tail = NULL; 441e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 442e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->skips_head = sip->next; 443e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->next->prev = NULL; 444e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 445e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else if (sip->next == NULL) { 446e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->skips_tail = sip->prev; 447e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->prev->next = NULL; 448e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 449e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->prev->next = sip->next; 450e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->next->prev = sip->prev; 451e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 452e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 453e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->prev = sip->next = NULL; 454e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(sip); 455e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 456e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 457e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define IN_SKIP(sip,seq) (((sip)->start <= (seq)) && ((seq) <= sip->end)) 458e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int check_current_skips(struct per_cpu_info *pci, unsigned long seq) 459e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 460e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct skip_info *sip; 461e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 462e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (sip = pci->skips_tail; sip != NULL; sip = sip->prev) { 463e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (IN_SKIP(sip, seq)) { 464e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sip->start == seq) { 465e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sip->end == seq) 466e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat remove_sip(pci, sip); 467e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 468e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->start += 1; 469e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else if (sip->end == seq) 470e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->end -= 1; 471e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 472e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->end = seq - 1; 473e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat insert_skip(pci, seq + 1, sip->end); 474e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 475e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 476e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 477e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 478e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 479e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 480e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 481e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 482e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void collect_pdi_skips(struct per_dev_info *pdi) 483e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 484e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct skip_info *sip; 485e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int cpu; 486e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 487e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->skips = 0; 488e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->seq_skips = 0; 489e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 490e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (cpu = 0; cpu < pdi->ncpus; cpu++) { 491e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci = &pdi->cpus[cpu]; 492e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 493e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (sip = pci->skips_head; sip != NULL; sip = sip->next) { 494e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->skips++; 495e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->seq_skips += (sip->end - sip->start + 1); 496e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose) 497e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr,"(%d,%d): skipping %lu -> %lu\n", 498e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat MAJOR(pdi->dev), MINOR(pdi->dev), 499e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sip->start, sip->end); 500e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 501e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 502e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 503e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 504e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void cpu_mark_online(struct per_dev_info *pdi, unsigned int cpu) 505e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 506e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (cpu >= pdi->cpu_map_max || !pdi->cpu_map) { 507e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int new_max = (cpu + CPUS_PER_LONG) & ~(CPUS_PER_LONG - 1); 508e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long *map = malloc(new_max / sizeof(long)); 509e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 510e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(map, 0, new_max / sizeof(long)); 511e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 512e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->cpu_map) { 513e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memcpy(map, pdi->cpu_map, pdi->cpu_map_max / sizeof(long)); 514e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(pdi->cpu_map); 515e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 516e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 517e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cpu_map = map; 518e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cpu_map_max = new_max; 519e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 520e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 521e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cpu_map[CPU_IDX(cpu)] |= (1UL << CPU_BIT(cpu)); 522e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 523e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 524e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void cpu_mark_offline(struct per_dev_info *pdi, int cpu) 525e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 526e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cpu_map[CPU_IDX(cpu)] &= ~(1UL << CPU_BIT(cpu)); 527e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 528e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 529e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int cpu_is_online(struct per_dev_info *pdi, int cpu) 530e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 531e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return (pdi->cpu_map[CPU_IDX(cpu)] & (1UL << CPU_BIT(cpu))) != 0; 532e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 533e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 534e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int ppm_hash_pid(pid_t pid) 535e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 536e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return jhash_1word(pid, JHASH_RANDOM) & PPM_HASH_MASK; 537e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 538e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 539e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct process_pid_map *find_ppm(pid_t pid) 540e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 541e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat const int hash_idx = ppm_hash_pid(pid); 542e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm; 543e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 544e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppm = ppm_hash_table[hash_idx]; 545e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (ppm) { 546e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppm->pid == pid) 547e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ppm; 548e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 549e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppm = ppm->hash_next; 550e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 551e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 552e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 553e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 554e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 555e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct process_pid_map *add_ppm_hash(pid_t pid, const char *name) 556e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 557e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat const int hash_idx = ppm_hash_pid(pid); 558e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm; 559e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 560e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppm = find_ppm(pid); 561e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!ppm) { 562e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppm = malloc(sizeof(*ppm)); 563e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(ppm, 0, sizeof(*ppm)); 564e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppm->pid = pid; 565e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat strcpy(ppm->comm, name); 566e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppm->hash_next = ppm_hash_table[hash_idx]; 567e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppm_hash_table[hash_idx] = ppm; 568e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 569e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 570e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ppm; 571e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 572e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 573e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void handle_notify(struct blk_io_trace *bit) 574e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 575e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat void *payload = (caddr_t) bit + sizeof(*bit); 576e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u32 two32[2]; 577e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 578e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat switch (bit->action) { 579e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case BLK_TN_PROCESS: 580e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat add_ppm_hash(bit->pid, payload); 581e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 582e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 583e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case BLK_TN_TIMESTAMP: 584e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->pdu_len != sizeof(two32)) 585e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 586e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memcpy(two32, payload, sizeof(two32)); 587e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!data_is_native) { 588e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat two32[0] = be32_to_cpu(two32[0]); 589e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat two32[1] = be32_to_cpu(two32[1]); 590e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 591e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat start_timestamp = bit->time; 592e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_sec = two32[0]; 593e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_nsec = two32[1]; 594e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (abs_start_time.tv_nsec < 0) { 595e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_sec--; 596e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_nsec += 1000000000; 597e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 598e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 599e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 600e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 601e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case BLK_TN_MESSAGE: 602e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->pdu_len > 0) { 603e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char msg[bit->pdu_len+1]; 604e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 605e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memcpy(msg, (char *)payload, bit->pdu_len); 606e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msg[bit->pdu_len] = '\0'; 607e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 608e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, 609e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "%3d,%-3d %2d %8s %5d.%09lu %5u %2s %3s %s\n", 610e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat MAJOR(bit->device), MINOR(bit->device), 611e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit->cpu, "0", (int) SECONDS(bit->time), 612e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long) NANO_SECONDS(bit->time), 613e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 0, "m", "N", msg); 614e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 615e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 616e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 617e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat default: 618e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* Ignore unknown notify events */ 619e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ; 620e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 621e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 622e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 623e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatchar *find_process_name(pid_t pid) 624e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 625e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm = find_ppm(pid); 626e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 627e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppm) 628e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ppm->comm; 629e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 630e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 631e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 632e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 633e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int ppi_hash_pid(pid_t pid) 634e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 635e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return jhash_1word(pid, JHASH_RANDOM) & PPI_HASH_MASK; 636e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 637e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 638e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int ppi_hash_name(const char *name) 639e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 640e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return jhash(name, 16, JHASH_RANDOM) & PPI_HASH_MASK; 641e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 642e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 643e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int ppi_hash(struct per_process_info *ppi) 644e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 645e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm = ppi->ppm; 646e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 647e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppi_hash_by_pid) 648e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ppi_hash_pid(ppm->pid); 649e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 650e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ppi_hash_name(ppm->comm); 651e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 652e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 653e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void add_ppi_to_hash(struct per_process_info *ppi) 654e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 655e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat const int hash_idx = ppi_hash(ppi); 656e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 657e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->hash_next = ppi_hash_table[hash_idx]; 658e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi_hash_table[hash_idx] = ppi; 659e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 660e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 661e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void add_ppi_to_list(struct per_process_info *ppi) 662e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 663e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->list_next = ppi_list; 664e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi_list = ppi; 665e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi_list_entries++; 666e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 667e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 668e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct per_process_info *find_ppi_by_name(char *name) 669e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 670e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat const int hash_idx = ppi_hash_name(name); 671e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi; 672e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 673e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppi_hash_table[hash_idx]; 674e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (ppi) { 675e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm = ppi->ppm; 676e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 677e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!strcmp(ppm->comm, name)) 678e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ppi; 679e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 680e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppi->hash_next; 681e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 682e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 683e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 684e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 685e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 686e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct per_process_info *find_ppi_by_pid(pid_t pid) 687e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 688e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat const int hash_idx = ppi_hash_pid(pid); 689e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi; 690e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 691e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppi_hash_table[hash_idx]; 692e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (ppi) { 693e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm = ppi->ppm; 694e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 695e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppm->pid == pid) 696e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ppi; 697e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 698e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppi->hash_next; 699e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 700e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 701e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 702e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 703e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 704e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct per_process_info *find_ppi(pid_t pid) 705e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 706e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi; 707e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *name; 708e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 709e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppi_hash_by_pid) 710e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return find_ppi_by_pid(pid); 711e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 712e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat name = find_process_name(pid); 713e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!name) 714e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 715e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 716e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = find_ppi_by_name(name); 717e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppi && ppi->ppm->pid != pid) 718e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->more_than_one = 1; 719e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 720e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ppi; 721e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 722e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 723e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 724e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * struct trace and blktrace allocation cache, we do potentially 725e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * millions of mallocs for these structures while only using at most 726e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * a few thousand at the time 727e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 728e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void t_free(struct trace *t) 729e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 730e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (t_alloc_cache < 1024) { 731e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t->next = t_alloc_list; 732e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t_alloc_list = t; 733e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t_alloc_cache++; 734e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else 735e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(t); 736e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 737e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 738e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct trace *t_alloc(void) 739e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 740e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *t = t_alloc_list; 741e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 742e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (t) { 743e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t_alloc_list = t->next; 744e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t_alloc_cache--; 745e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return t; 746e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 747e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 748e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return malloc(sizeof(*t)); 749e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 750e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 751e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void bit_free(struct blk_io_trace *bit) 752e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 753e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit_alloc_cache < 1024 && !bit->pdu_len) { 754e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 755e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * abuse a 64-bit field for a next pointer for the free item 756e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 757e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit->time = (__u64) (unsigned long) bit_alloc_list; 758e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_alloc_list = (struct blk_io_trace *) bit; 759e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_alloc_cache++; 760e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else 761e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(bit); 762e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 763e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 764e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct blk_io_trace *bit_alloc(void) 765e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 766e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *bit = bit_alloc_list; 767e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 768e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit) { 769e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_alloc_list = (struct blk_io_trace *) (unsigned long) \ 770e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit->time; 771e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_alloc_cache--; 772e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return bit; 773e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 774e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 775e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return malloc(sizeof(*bit)); 776e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 777e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 778e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __put_trace_last(struct per_dev_info *pdi, struct trace *t) 779e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 780e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci = get_cpu_info(pdi, t->bit->cpu); 781e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 782e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_erase(&t->rb_node, &pci->rb_last); 783e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->rb_last_entries--; 784e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 785e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_free(t->bit); 786e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t_free(t); 787e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 788e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 789e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void put_trace(struct per_dev_info *pdi, struct trace *t) 790e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 791e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_erase(&t->rb_node, &rb_sort_root); 792e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_sort_entries--; 793e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 794e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat trace_rb_insert_last(pdi, t); 795e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 796e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 797e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int trace_rb_insert(struct trace *t, struct rb_root *root) 798e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 799e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node **p = &root->rb_node; 800e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *parent = NULL; 801e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *__t; 802e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 803e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (*p) { 804e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat parent = *p; 805e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 806e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __t = rb_entry(parent, struct trace, rb_node); 807e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 808e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (t->bit->time < __t->bit->time) 809e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_left; 810e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (t->bit->time > __t->bit->time) 811e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_right; 812e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (t->bit->device < __t->bit->device) 813e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_left; 814e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (t->bit->device > __t->bit->device) 815e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_right; 816e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (t->bit->sequence < __t->bit->sequence) 817e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_left; 818e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else /* >= sequence */ 819e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_right; 820e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 821e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 822e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_link_node(&t->rb_node, parent, p); 823e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_insert_color(&t->rb_node, root); 824e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 825e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 826e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 827e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int trace_rb_insert_sort(struct trace *t) 828e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 829e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!trace_rb_insert(t, &rb_sort_root)) { 830e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_sort_entries++; 831e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 832e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 833e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 834e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 835e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 836e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 837e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int trace_rb_insert_last(struct per_dev_info *pdi, struct trace *t) 838e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 839e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci = get_cpu_info(pdi, t->bit->cpu); 840e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 841e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (trace_rb_insert(t, &pci->rb_last)) 842e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 843e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 844e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->rb_last_entries++; 845e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 846e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pci->rb_last_entries > rb_batch * pdi->nfiles) { 847e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *n = rb_first(&pci->rb_last); 848e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 849e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t = rb_entry(n, struct trace, rb_node); 850e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __put_trace_last(pdi, t); 851e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 852e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 853e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 854e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 855e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 856e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct trace *trace_rb_find(dev_t device, unsigned long sequence, 857e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_root *root, int order) 858e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 859e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *n = root->rb_node; 860e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *prev = NULL; 861e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *__t; 862e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 863e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (n) { 864e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __t = rb_entry(n, struct trace, rb_node); 865e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat prev = n; 866e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 867e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (device < __t->bit->device) 868e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_left; 869e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (device > __t->bit->device) 870e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_right; 871e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (sequence < __t->bit->sequence) 872e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_left; 873e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (sequence > __t->bit->sequence) 874e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_right; 875e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 876e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return __t; 877e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 878e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 879e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 880e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * hack - the list may not be sequence ordered because some 881e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * events don't have sequence and time matched. so we end up 882e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * being a little off in the rb lookup here, because we don't 883e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * know the time we are looking for. compensate by browsing 884e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * a little ahead from the last entry to find the match 885e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 886e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (order && prev) { 887e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int max = 5; 888e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 889e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (((n = rb_next(prev)) != NULL) && max--) { 890e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __t = rb_entry(n, struct trace, rb_node); 891e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 892e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (__t->bit->device == device && 893e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __t->bit->sequence == sequence) 894e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return __t; 895e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 896e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat prev = n; 897e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 898e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 899e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 900e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 901e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 902e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 903e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct trace *trace_rb_find_last(struct per_dev_info *pdi, 904e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, 905e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long seq) 906e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 907e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return trace_rb_find(pdi->dev, seq, &pci->rb_last, 0); 908e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 909e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 910e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int track_rb_insert(struct per_dev_info *pdi,struct io_track *iot) 911e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 912e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node **p = &pdi->rb_track.rb_node; 913e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *parent = NULL; 914e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *__iot; 915e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 916e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (*p) { 917e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat parent = *p; 918e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __iot = rb_entry(parent, struct io_track, rb_node); 919e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 920e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (iot->sector < __iot->sector) 921e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_left; 922e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (iot->sector > __iot->sector) 923e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_right; 924e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 925e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, 926e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "sector alias (%Lu) on device %d,%d!\n", 927e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long long) iot->sector, 928e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat MAJOR(pdi->dev), MINOR(pdi->dev)); 929e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 930e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 931e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 932e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 933e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_link_node(&iot->rb_node, parent, p); 934e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_insert_color(&iot->rb_node, &pdi->rb_track); 935e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 936e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 937e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 938e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct io_track *__find_track(struct per_dev_info *pdi, __u64 sector) 939e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 940e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *n = pdi->rb_track.rb_node; 941e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *__iot; 942e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 943e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (n) { 944e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __iot = rb_entry(n, struct io_track, rb_node); 945e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 946e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sector < __iot->sector) 947e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_left; 948e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (sector > __iot->sector) 949e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_right; 950e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 951e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return __iot; 952e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 953e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 954e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 955e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 956e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 957e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct io_track *find_track(struct per_dev_info *pdi, pid_t pid, 958e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 sector) 959e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 960e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *iot; 961e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 962e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot = __find_track(pdi, sector); 963e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!iot) { 964e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot = malloc(sizeof(*iot)); 965e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->ppm = find_ppm(pid); 966e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!iot->ppm) 967e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->ppm = add_ppm_hash(pid, "unknown"); 968e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->sector = sector; 969e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat track_rb_insert(pdi, iot); 970e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 971e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 972e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return iot; 973e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 974e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 975e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_track_frontmerge(struct per_dev_info *pdi, 976e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t) 977e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 978e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *iot; 979e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 980e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!track_ios) 981e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 982e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 983e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot = __find_track(pdi, t->sector + t_sec(t)); 984e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!iot) { 985e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose) 986e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "merge not found for (%d,%d): %llu\n", 987e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat MAJOR(pdi->dev), MINOR(pdi->dev), 988e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long long) t->sector + t_sec(t)); 989e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 990e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 991e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 992e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_erase(&iot->rb_node, &pdi->rb_track); 993e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->sector -= t_sec(t); 994e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat track_rb_insert(pdi, iot); 995e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 996e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 997e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_track_getrq(struct per_dev_info *pdi, struct blk_io_trace *t) 998e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 999e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *iot; 1000e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1001e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!track_ios) 1002e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 1003e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1004e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot = find_track(pdi, t->pid, t->sector); 1005e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->allocation_time = t->time; 1006e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1007e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1008e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int is_remapper(struct per_dev_info *pdi) 1009e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1010e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int major = MAJOR(pdi->dev); 1011e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1012e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return (major == 253 || major == 9); 1013e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1014e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1015e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1016e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * for md/dm setups, the interesting cycle is Q -> C. So track queueing 1017e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * time here, as dispatch time 1018e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1019e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_track_queue(struct per_dev_info *pdi, struct blk_io_trace *t) 1020e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1021e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *iot; 1022e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1023e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!track_ios) 1024e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 1025e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!is_remapper(pdi)) 1026e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 1027e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1028e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot = find_track(pdi, t->pid, t->sector); 1029e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->dispatch_time = t->time; 1030e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1031e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1032e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1033e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * return time between rq allocation and insertion 1034e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1035e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long long log_track_insert(struct per_dev_info *pdi, 1036e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t) 1037e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1038e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long elapsed; 1039e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *iot; 1040e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1041e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!track_ios) 1042e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 1043e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1044e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot = find_track(pdi, t->pid, t->sector); 1045e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->queue_time = t->time; 1046e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1047e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!iot->allocation_time) 1048e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 1049e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1050e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elapsed = iot->queue_time - iot->allocation_time; 1051e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1052e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1053e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi = find_ppi(iot->ppm->pid); 1054e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; 1055e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1056e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppi && elapsed > ppi->longest_allocation_wait[w]) 1057e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->longest_allocation_wait[w] = elapsed; 1058e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1059e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1060e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return elapsed; 1061e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1062e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1063e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1064e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * return time between queue and issue 1065e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1066e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long long log_track_issue(struct per_dev_info *pdi, 1067e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t) 1068e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1069e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long elapsed; 1070e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *iot; 1071e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1072e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!track_ios) 1073e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 1074e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if ((t->action & BLK_TC_ACT(BLK_TC_FS)) == 0) 1075e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 1076e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1077e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot = __find_track(pdi, t->sector); 1078e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!iot) { 1079e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose) 1080e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "issue not found for (%d,%d): %llu\n", 1081e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat MAJOR(pdi->dev), MINOR(pdi->dev), 1082e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long long) t->sector); 1083e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 1084e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1085e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1086e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->dispatch_time = t->time; 1087e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elapsed = iot->dispatch_time - iot->queue_time; 1088e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1089e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1090e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi = find_ppi(iot->ppm->pid); 1091e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; 1092e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1093e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppi && elapsed > ppi->longest_dispatch_wait[w]) 1094e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->longest_dispatch_wait[w] = elapsed; 1095e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1096e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1097e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return elapsed; 1098e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1099e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * return time between dispatch and complete 1102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned long long log_track_complete(struct per_dev_info *pdi, 1104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t) 1105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long elapsed; 1107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_track *iot; 1108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!track_ios) 1110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 1111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot = __find_track(pdi, t->sector); 1113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!iot) { 1114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose) 1115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr,"complete not found for (%d,%d): %llu\n", 1116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat MAJOR(pdi->dev), MINOR(pdi->dev), 1117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long long) t->sector); 1118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 1119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iot->completion_time = t->time; 1122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elapsed = iot->completion_time - iot->dispatch_time; 1123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi = find_ppi(iot->ppm->pid); 1126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; 1127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppi && elapsed > ppi->longest_completion_wait[w]) 1129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->longest_completion_wait[w] = elapsed; 1130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 1133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * kill the trace, we don't need it after completion 1134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_erase(&iot->rb_node, &pdi->rb_track); 1136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(iot); 1137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return elapsed; 1139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct io_stats *find_process_io_stats(pid_t pid) 1143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi = find_ppi(pid); 1145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!ppi) { 1147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = malloc(sizeof(*ppi)); 1148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(ppi, 0, sizeof(*ppi)); 1149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->ppm = find_ppm(pid); 1150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!ppi->ppm) 1151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->ppm = add_ppm_hash(pid, "unknown"); 1152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat add_ppi_to_hash(ppi); 1153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat add_ppi_to_list(ppi); 1154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return &ppi->io_stats; 1157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *get_dev_name(struct per_dev_info *pdi, char *buffer, int size) 1160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->name) 1162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat snprintf(buffer, size, "%s", pdi->name); 1163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 1164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat snprintf(buffer, size, "%d,%d",MAJOR(pdi->dev),MINOR(pdi->dev)); 1165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return buffer; 1166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void check_time(struct per_dev_info *pdi, struct blk_io_trace *bit) 1169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long this = bit->time; 1171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long last = pdi->last_reported_time; 1172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->backwards = (this < last) ? 'B' : ' '; 1174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->last_reported_time = this; 1175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_m(struct io_stats *ios, struct blk_io_trace *t, 1178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int rw) 1179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) { 1181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->mwrites++; 1182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->mwrite_kb += t_kb(t); 1183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 1184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->mreads++; 1185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->mread_kb += t_kb(t); 1186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_m(struct blk_io_trace *t, struct per_cpu_info *pci, 1190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int rw) 1191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_m(&pci->io_stats, t, rw); 1193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_m(ios, t, rw); 1198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_pc_queue(struct io_stats *ios, 1202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t, int rw) 1203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) { 1205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->qwrites_pc++; 1206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->qwrite_kb_pc += t_kb(t); 1207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 1208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->qreads_pc++; 1209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->qread_kb += t_kb(t); 1210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_pc_queue(struct blk_io_trace *t, 1214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, int rw) 1215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_pc_queue(&pci->io_stats, t, rw); 1217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_pc_queue(ios, t, rw); 1222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_pc_issue(struct io_stats *ios, int rw, 1226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int bytes) 1227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) { 1229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iwrites_pc++; 1230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iwrite_kb_pc += bytes >> 10; 1231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 1232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->ireads_pc++; 1233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iread_kb_pc += bytes >> 10; 1234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_pc_issue(struct blk_io_trace *t, 1238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, int rw) 1239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_pc_issue(&pci->io_stats, rw, t->bytes); 1241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_pc_issue(ios, rw, t->bytes); 1246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_pc_requeue(struct io_stats *ios, 1250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t, int rw) 1251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) { 1253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->wrqueue_pc++; 1254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iwrite_kb_pc -= t_kb(t); 1255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 1256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->rrqueue_pc++; 1257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iread_kb_pc -= t_kb(t); 1258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_pc_requeue(struct blk_io_trace *t, 1262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, int rw) 1263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_pc_requeue(&pci->io_stats, t, rw); 1265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_pc_requeue(ios, t, rw); 1270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_pc_c(struct io_stats *ios, int rw) 1274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) 1276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->cwrites_pc++; 1277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 1278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->creads_pc++; 1279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_pc_c(struct blk_io_trace *t, 1282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, int rw) 1283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_pc_c(&pci->io_stats, rw); 1285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_pc_c(ios, rw); 1290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_queue(struct io_stats *ios, struct blk_io_trace *t, 1294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int rw) 1295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) { 1297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->qwrites++; 1298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->qwrite_kb += t_kb(t); 1299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 1300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->qreads++; 1301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->qread_kb += t_kb(t); 1302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_queue(struct blk_io_trace *t, 1306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, int rw) 1307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_queue(&pci->io_stats, t, rw); 1309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_queue(ios, t, rw); 1314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_c(struct io_stats *ios, int rw, int bytes) 1318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) { 1320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->cwrites++; 1321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->cwrite_kb += bytes >> 10; 1322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 1323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->creads++; 1324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->cread_kb += bytes >> 10; 1325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_c(struct blk_io_trace *t, struct per_cpu_info *pci, 1329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int rw, int bytes) 1330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_c(&pci->io_stats, rw, bytes); 1332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_c(ios, rw, bytes); 1337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_issue(struct io_stats *ios, int rw, 1341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int bytes) 1342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) { 1344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iwrites++; 1345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iwrite_kb += bytes >> 10; 1346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 1347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->ireads++; 1348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iread_kb += bytes >> 10; 1349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_issue(struct blk_io_trace *t, 1353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, int rw) 1354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_issue(&pci->io_stats, rw, t->bytes); 1356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_issue(ios, rw, t->bytes); 1361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_unplug(struct io_stats *ios, int timer) 1365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (timer) 1367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->timer_unplugs++; 1368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 1369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->io_unplugs++; 1370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_unplug(struct blk_io_trace *t, 1373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, int timer) 1374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_unplug(&pci->io_stats, timer); 1376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_unplug(ios, timer); 1381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1384e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __account_requeue(struct io_stats *ios, 1385e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t, int rw) 1386e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1387e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) { 1388e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->wrqueue++; 1389e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iwrite_kb -= t_kb(t); 1390e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 1391e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->rrqueue++; 1392e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->iread_kb -= t_kb(t); 1393e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1394e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1395e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1396e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void account_requeue(struct blk_io_trace *t, 1397e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci, int rw) 1398e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1399e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_requeue(&pci->io_stats, t, rw); 1400e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1401e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) { 1402e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats *ios = find_process_io_stats(t->pid); 1403e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1404e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __account_requeue(ios, t, rw); 1405e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1406e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1407e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1408e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_complete(struct per_dev_info *pdi, struct per_cpu_info *pci, 1409e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t, char *act) 1410e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1411e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, log_track_complete(pdi, t), 0, NULL); 1412e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1413e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1414e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_insert(struct per_dev_info *pdi, struct per_cpu_info *pci, 1415e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t, char *act) 1416e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1417e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, log_track_insert(pdi, t), 0, NULL); 1418e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1419e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1420e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_queue(struct per_cpu_info *pci, struct blk_io_trace *t, 1421e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *act) 1422e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1423e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, -1, 0, NULL); 1424e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1425e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1426e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_issue(struct per_dev_info *pdi, struct per_cpu_info *pci, 1427e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t, char *act) 1428e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1429e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, log_track_issue(pdi, t), 0, NULL); 1430e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1431e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1432e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_merge(struct per_dev_info *pdi, struct per_cpu_info *pci, 1433e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *t, char *act) 1434e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1435e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (act[0] == 'F') 1436e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_track_frontmerge(pdi, t); 1437e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1438e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, -1ULL, 0, NULL); 1439e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1440e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1441e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_action(struct per_cpu_info *pci, struct blk_io_trace *t, 1442e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *act) 1443e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1444e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, -1ULL, 0, NULL); 1445e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1446e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1447e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_generic(struct per_cpu_info *pci, struct blk_io_trace *t, 1448e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *act) 1449e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1450e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, -1ULL, 0, NULL); 1451e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1452e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1453e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_unplug(struct per_cpu_info *pci, struct blk_io_trace *t, 1454e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *act) 1455e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1456e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, -1ULL, 0, NULL); 1457e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1458e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1459e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_split(struct per_cpu_info *pci, struct blk_io_trace *t, 1460e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *act) 1461e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1462e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, -1ULL, 0, NULL); 1463e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1464e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1465e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void log_pc(struct per_cpu_info *pci, struct blk_io_trace *t, char *act) 1466e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1467e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned char *buf = (unsigned char *) t + sizeof(*t); 1468e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1469e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_fmt(act, pci, t, -1ULL, t->pdu_len, buf); 1470e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1471e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1472e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void dump_trace_pc(struct blk_io_trace *t, struct per_dev_info *pdi, 1473e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci) 1474e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1475e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; 1476e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int act = t->action & 0xffff; 1477e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1478e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat switch (act) { 1479e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_QUEUE: 1480e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_generic(pci, t, "Q"); 1481e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_pc_queue(t, pci, w); 1482e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1483e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_GETRQ: 1484e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_generic(pci, t, "G"); 1485e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1486e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_SLEEPRQ: 1487e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_generic(pci, t, "S"); 1488e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1489e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_REQUEUE: 1490e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 1491e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * can happen if we miss traces, don't let it go 1492e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * below zero 1493e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1494e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->cur_depth[w]) 1495e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cur_depth[w]--; 1496e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_pc_requeue(t, pci, w); 1497e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_generic(pci, t, "R"); 1498e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1499e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_ISSUE: 1500e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_pc_issue(t, pci, w); 1501e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cur_depth[w]++; 1502e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->cur_depth[w] > pdi->max_depth[w]) 1503e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->max_depth[w] = pdi->cur_depth[w]; 1504e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_pc(pci, t, "D"); 1505e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1506e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_COMPLETE: 1507e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->cur_depth[w]) 1508e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cur_depth[w]--; 1509e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_pc(pci, t, "C"); 1510e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_pc_c(t, pci, w); 1511e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1512e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_INSERT: 1513e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_pc(pci, t, "I"); 1514e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1515e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat default: 1516e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Bad pc action %x\n", act); 1517e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1518e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1519e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1520e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1521e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void dump_trace_fs(struct blk_io_trace *t, struct per_dev_info *pdi, 1522e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci) 1523e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1524e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; 1525e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int act = t->action & 0xffff; 1526e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1527e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat switch (act) { 1528e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_QUEUE: 1529e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_track_queue(pdi, t); 1530e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_queue(t, pci, w); 1531e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_queue(pci, t, "Q"); 1532e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1533e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_INSERT: 1534e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_insert(pdi, pci, t, "I"); 1535e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1536e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_BACKMERGE: 1537e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_m(t, pci, w); 1538e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_merge(pdi, pci, t, "M"); 1539e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1540e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_FRONTMERGE: 1541e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_m(t, pci, w); 1542e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_merge(pdi, pci, t, "F"); 1543e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1544e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_GETRQ: 1545e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_track_getrq(pdi, t); 1546e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_generic(pci, t, "G"); 1547e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1548e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_SLEEPRQ: 1549e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_generic(pci, t, "S"); 1550e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1551e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_REQUEUE: 1552e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 1553e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * can happen if we miss traces, don't let it go 1554e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * below zero 1555e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1556e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->cur_depth[w]) 1557e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cur_depth[w]--; 1558e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_requeue(t, pci, w); 1559e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_queue(pci, t, "R"); 1560e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1561e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_ISSUE: 1562e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_issue(t, pci, w); 1563e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cur_depth[w]++; 1564e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->cur_depth[w] > pdi->max_depth[w]) 1565e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->max_depth[w] = pdi->cur_depth[w]; 1566e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_issue(pdi, pci, t, "D"); 1567e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1568e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_COMPLETE: 1569e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->cur_depth[w]) 1570e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->cur_depth[w]--; 1571e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_c(t, pci, w, t->bytes); 1572e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_complete(pdi, pci, t, "C"); 1573e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1574e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_PLUG: 1575e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_action(pci, t, "P"); 1576e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1577e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_UNPLUG_IO: 1578e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_unplug(t, pci, 0); 1579e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_unplug(pci, t, "U"); 1580e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1581e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_UNPLUG_TIMER: 1582e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat account_unplug(t, pci, 1); 1583e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_unplug(pci, t, "UT"); 1584e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1585e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_SPLIT: 1586e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_split(pci, t, "X"); 1587e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1588e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_BOUNCE: 1589e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_generic(pci, t, "B"); 1590e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1591e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_REMAP: 1592e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat log_generic(pci, t, "A"); 1593e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1594e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case __BLK_TA_DRV_DATA: 1595e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat have_drv_data = 1; 1596e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* dump to binary file only */ 1597e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1598e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat default: 1599e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Bad fs action %x\n", t->action); 1600e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1601e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1602e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1603e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1604e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void dump_trace(struct blk_io_trace *t, struct per_cpu_info *pci, 1605e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi) 1606e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1607e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (text_output) { 1608e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (t->action == BLK_TN_MESSAGE) 1609e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat handle_notify(t); 1610e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (t->action & BLK_TC_ACT(BLK_TC_PC)) 1611e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_trace_pc(t, pdi, pci); 1612e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 1613e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_trace_fs(t, pdi, pci); 1614e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1615e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1616e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pdi->events) 1617e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->first_reported_time = t->time; 1618e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1619e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->events++; 1620e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1621e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bin_output_msgs || 1622e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat !(t->action & BLK_TC_ACT(BLK_TC_NOTIFY) && 1623e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t->action == BLK_TN_MESSAGE)) 1624e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat output_binary(t, sizeof(*t) + t->pdu_len); 1625e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1626e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1627e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1628e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * print in a proper way, not too small and not too big. if more than 1629e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1000,000K, turn into M and so on 1630e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1631e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *size_cnv(char *dst, unsigned long long num, int in_kb) 1632e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1633e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char suff[] = { '\0', 'K', 'M', 'G', 'P' }; 1634e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int i = 0; 1635e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1636e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (in_kb) 1637e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat i++; 1638e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1639e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (num > 1000 * 1000ULL && (i < sizeof(suff) - 1)) { 1640e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat i++; 1641e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat num /= 1000; 1642e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1643e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1644e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sprintf(dst, "%'8Lu%c", num, suff[i]); 1645e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return dst; 1646e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1647e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1648e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void dump_io_stats(struct per_dev_info *pdi, struct io_stats *ios, 1649e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *msg) 1650e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1651e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat static char x[256], y[256]; 1652e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1653e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "%s\n", msg); 1654e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1655e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Reads Queued: %s, %siB\t", size_cnv(x, ios->qreads, 0), size_cnv(y, ios->qread_kb, 1)); 1656e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Writes Queued: %s, %siB\n", size_cnv(x, ios->qwrites, 0), size_cnv(y, ios->qwrite_kb, 1)); 1657e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Read Dispatches: %s, %siB\t", size_cnv(x, ios->ireads, 0), size_cnv(y, ios->iread_kb, 1)); 1658e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Write Dispatches: %s, %siB\n", size_cnv(x, ios->iwrites, 0), size_cnv(y, ios->iwrite_kb, 1)); 1659e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Reads Requeued: %s\t\t", size_cnv(x, ios->rrqueue, 0)); 1660e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Writes Requeued: %s\n", size_cnv(x, ios->wrqueue, 0)); 1661e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Reads Completed: %s, %siB\t", size_cnv(x, ios->creads, 0), size_cnv(y, ios->cread_kb, 1)); 1662e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Writes Completed: %s, %siB\n", size_cnv(x, ios->cwrites, 0), size_cnv(y, ios->cwrite_kb, 1)); 1663e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Read Merges: %s, %siB\t", size_cnv(x, ios->mreads, 0), size_cnv(y, ios->mread_kb, 1)); 1664e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Write Merges: %s, %siB\n", size_cnv(x, ios->mwrites, 0), size_cnv(y, ios->mwrite_kb, 1)); 1665e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi) { 1666e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Read depth: %'8u%8c\t", pdi->max_depth[0], ' '); 1667e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Write depth: %'8u\n", pdi->max_depth[1]); 1668e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1669e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ios->qreads_pc || ios->qwrites_pc || ios->ireads_pc || ios->iwrites_pc || 1670e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios->rrqueue_pc || ios->wrqueue_pc || ios->creads_pc || ios->cwrites_pc) { 1671e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " PC Reads Queued: %s, %siB\t", size_cnv(x, ios->qreads_pc, 0), size_cnv(y, ios->qread_kb_pc, 1)); 1672e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " PC Writes Queued: %s, %siB\n", size_cnv(x, ios->qwrites_pc, 0), size_cnv(y, ios->qwrite_kb_pc, 1)); 1673e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " PC Read Disp.: %s, %siB\t", size_cnv(x, ios->ireads_pc, 0), size_cnv(y, ios->iread_kb_pc, 1)); 1674e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " PC Write Disp.: %s, %siB\n", size_cnv(x, ios->iwrites_pc, 0), size_cnv(y, ios->iwrite_kb_pc, 1)); 1675e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " PC Reads Req.: %s\t\t", size_cnv(x, ios->rrqueue_pc, 0)); 1676e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " PC Writes Req.: %s\n", size_cnv(x, ios->wrqueue_pc, 0)); 1677e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " PC Reads Compl.: %s\t\t", size_cnv(x, ios->creads_pc, 0)); 1678e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " PC Writes Compl.: %s\n", size_cnv(x, ios->cwrites, 0)); 1679e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1680e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " IO unplugs: %'8lu%8c\t", ios->io_unplugs, ' '); 1681e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Timer unplugs: %'8lu\n", ios->timer_unplugs); 1682e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1683e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1684e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void dump_wait_stats(struct per_process_info *ppi) 1685e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1686e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long rawait = ppi->longest_allocation_wait[0] / 1000; 1687e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long rdwait = ppi->longest_dispatch_wait[0] / 1000; 1688e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long rcwait = ppi->longest_completion_wait[0] / 1000; 1689e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long wawait = ppi->longest_allocation_wait[1] / 1000; 1690e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long wdwait = ppi->longest_dispatch_wait[1] / 1000; 1691e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long wcwait = ppi->longest_completion_wait[1] / 1000; 1692e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1693e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Allocation wait: %'8lu%8c\t", rawait, ' '); 1694e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Allocation wait: %'8lu\n", wawait); 1695e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Dispatch wait: %'8lu%8c\t", rdwait, ' '); 1696e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Dispatch wait: %'8lu\n", wdwait); 1697e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Completion wait: %'8lu%8c\t", rcwait, ' '); 1698e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, " Completion wait: %'8lu\n", wcwait); 1699e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1700e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1701e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int ppi_name_compare(const void *p1, const void *p2) 1702e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1703e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi1 = *((struct per_process_info **) p1); 1704e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi2 = *((struct per_process_info **) p2); 1705e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int res; 1706e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1707e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat res = strverscmp(ppi1->ppm->comm, ppi2->ppm->comm); 1708e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!res) 1709e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat res = ppi1->ppm->pid > ppi2->ppm->pid; 1710e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1711e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return res; 1712e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1713e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1714e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void sort_process_list(void) 1715e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1716e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info **ppis; 1717e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi; 1718e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i = 0; 1719e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1720e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppis = malloc(ppi_list_entries * sizeof(struct per_process_info *)); 1721e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1722e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppi_list; 1723e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (ppi) { 1724e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppis[i++] = ppi; 1725e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppi->list_next; 1726e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1727e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1728e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat qsort(ppis, ppi_list_entries, sizeof(ppi), ppi_name_compare); 1729e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1730e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat i = ppi_list_entries - 1; 1731e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi_list = NULL; 1732e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (i >= 0) { 1733e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppis[i]; 1734e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1735e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi->list_next = ppi_list; 1736e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi_list = ppi; 1737e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat i--; 1738e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1739e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1740e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(ppis); 1741e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1742e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1743e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void show_process_stats(void) 1744e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1745e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_process_info *ppi; 1746e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1747e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sort_process_list(); 1748e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1749e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppi_list; 1750e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (ppi) { 1751e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct process_pid_map *ppm = ppi->ppm; 1752e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char name[64]; 1753e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1754e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ppi->more_than_one) 1755e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sprintf(name, "%s (%u, ...)", ppm->comm, ppm->pid); 1756e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 1757e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sprintf(name, "%s (%u)", ppm->comm, ppm->pid); 1758e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1759e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_io_stats(NULL, &ppi->io_stats, name); 1760e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_wait_stats(ppi); 1761e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi = ppi->list_next; 1762e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1763e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1764e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "\n"); 1765e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1766e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1767e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void show_device_and_cpu_stats(void) 1768e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1769e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi; 1770e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci; 1771e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_stats total, *ios; 1772e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long rrate, wrate, msec; 1773e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i, j, pci_events; 1774e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char line[3 + 8/*cpu*/ + 2 + 32/*dev*/ + 3]; 1775e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char name[32]; 1776e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat double ratio; 1777e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1778e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (pdi = devices, i = 0; i < ndevices; i++, pdi++) { 1779e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1780e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(&total, 0, sizeof(total)); 1781e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci_events = 0; 1782e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1783e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (i > 0) 1784e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "\n"); 1785e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1786e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (pci = pdi->cpus, j = 0; j < pdi->ncpus; j++, pci++) { 1787e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pci->nelems) 1788e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue; 1789e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1790e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ios = &pci->io_stats; 1791e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.qreads += ios->qreads; 1792e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.qwrites += ios->qwrites; 1793e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.creads += ios->creads; 1794e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.cwrites += ios->cwrites; 1795e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.mreads += ios->mreads; 1796e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.mwrites += ios->mwrites; 1797e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.ireads += ios->ireads; 1798e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.iwrites += ios->iwrites; 1799e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.rrqueue += ios->rrqueue; 1800e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.wrqueue += ios->wrqueue; 1801e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.qread_kb += ios->qread_kb; 1802e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.qwrite_kb += ios->qwrite_kb; 1803e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.cread_kb += ios->cread_kb; 1804e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.cwrite_kb += ios->cwrite_kb; 1805e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.iread_kb += ios->iread_kb; 1806e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.iwrite_kb += ios->iwrite_kb; 1807e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.mread_kb += ios->mread_kb; 1808e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.mwrite_kb += ios->mwrite_kb; 1809e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1810e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.qreads_pc += ios->qreads_pc; 1811e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.qwrites_pc += ios->qwrites_pc; 1812e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.creads_pc += ios->creads_pc; 1813e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.cwrites_pc += ios->cwrites_pc; 1814e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.ireads_pc += ios->ireads_pc; 1815e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.iwrites_pc += ios->iwrites_pc; 1816e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.rrqueue_pc += ios->rrqueue_pc; 1817e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.wrqueue_pc += ios->wrqueue_pc; 1818e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.qread_kb_pc += ios->qread_kb_pc; 1819e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.qwrite_kb_pc += ios->qwrite_kb_pc; 1820e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.iread_kb_pc += ios->iread_kb_pc; 1821e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.iwrite_kb_pc += ios->iwrite_kb_pc; 1822e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1823e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.timer_unplugs += ios->timer_unplugs; 1824e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total.io_unplugs += ios->io_unplugs; 1825e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1826e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat snprintf(line, sizeof(line) - 1, "CPU%d (%s):", 1827e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat j, get_dev_name(pdi, name, sizeof(name))); 1828e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_io_stats(pdi, ios, line); 1829e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci_events++; 1830e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1831e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1832e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pci_events > 1) { 1833e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "\n"); 1834e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat snprintf(line, sizeof(line) - 1, "Total (%s):", 1835e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat get_dev_name(pdi, name, sizeof(name))); 1836e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_io_stats(NULL, &total, line); 1837e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1838e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1839e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat wrate = rrate = 0; 1840e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msec = (pdi->last_reported_time - pdi->first_reported_time) / 1000000; 1841e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (msec) { 1842e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rrate = 1000 * total.cread_kb / msec; 1843e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat wrate = 1000 * total.cwrite_kb / msec; 1844e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1845e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1846e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "\nThroughput (R/W): %'LuKiB/s / %'LuKiB/s\n", 1847e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rrate, wrate); 1848e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "Events (%s): %'Lu entries\n", 1849e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat get_dev_name(pdi, line, sizeof(line)), pdi->events); 1850e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1851e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat collect_pdi_skips(pdi); 1852e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pdi->skips && !pdi->events) 1853e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ratio = 0.0; 1854e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 1855e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ratio = 100.0 * ((double)pdi->seq_skips / 1856e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (double)(pdi->events + pdi->seq_skips)); 1857e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(ofp, "Skips: %'lu forward (%'llu - %5.1lf%%)\n", 1858e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->skips, pdi->seq_skips, ratio); 1859e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1860e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1861e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1862e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void find_genesis(void) 1863e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1864e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *t = trace_list; 1865e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1866e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat genesis_time = -1ULL; 1867e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (t != NULL) { 1868e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (t->bit->time < genesis_time) 1869e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat genesis_time = t->bit->time; 1870e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1871e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t = t->next; 1872e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1873e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1874e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* The time stamp record will usually be the first 1875e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * record in the trace, but not always. 1876e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1877e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (start_timestamp 1878e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat && start_timestamp != genesis_time) { 1879e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat long delta = genesis_time - start_timestamp; 1880e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1881e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_sec += SECONDS(delta); 1882e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_nsec += NANO_SECONDS(delta); 1883e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (abs_start_time.tv_nsec < 0) { 1884e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_nsec += 1000000000; 1885e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_sec -= 1; 1886e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else 1887e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (abs_start_time.tv_nsec > 1000000000) { 1888e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_nsec -= 1000000000; 1889e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat abs_start_time.tv_sec += 1; 1890e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1891e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1892e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1893e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1894e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int check_stopwatch(struct blk_io_trace *bit) 1895e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1896e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->time < stopwatch_end && 1897e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit->time >= stopwatch_start) 1898e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 1899e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1900e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 1901e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1902e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1903e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1904e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * return youngest entry read 1905e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1906e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int sort_entries(unsigned long long *youngest) 1907e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1908e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi = NULL; 1909e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci = NULL; 1910e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *t; 1911e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1912e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!genesis_time) 1913e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat find_genesis(); 1914e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1915e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *youngest = 0; 1916e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while ((t = trace_list) != NULL) { 1917e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *bit = t->bit; 1918e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1919e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat trace_list = t->next; 1920e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1921e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit->time -= genesis_time; 1922e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1923e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->time < *youngest || !*youngest) 1924e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *youngest = bit->time; 1925e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1926e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pdi || pdi->dev != bit->device) { 1927e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi = get_dev_info(bit->device); 1928e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci = NULL; 1929e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1930e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1931e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pci || pci->cpu != bit->cpu) 1932e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci = get_cpu_info(pdi, bit->cpu); 1933e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1934e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->sequence < pci->smallest_seq_read) 1935e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->smallest_seq_read = bit->sequence; 1936e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1937e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (check_stopwatch(bit)) { 1938e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_free(bit); 1939e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t_free(t); 1940e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue; 1941e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1942e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1943e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (trace_rb_insert_sort(t)) 1944e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 1945e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1946e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1947e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 1948e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1949e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1950e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1951e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * to continue, we must have traces from all online cpus in the tree 1952e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1953e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int check_cpu_map(struct per_dev_info *pdi) 1954e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1955e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long *cpu_map; 1956e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *n; 1957e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *__t; 1958e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int i; 1959e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int ret, cpu; 1960e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1961e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 1962e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * create a map of the cpus we have traces for 1963e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1964e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu_map = malloc(pdi->cpu_map_max / sizeof(long)); 1965e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = rb_first(&rb_sort_root); 1966e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (n) { 1967e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __t = rb_entry(n, struct trace, rb_node); 1968e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu = __t->bit->cpu; 1969e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1970e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu_map[CPU_IDX(cpu)] |= (1UL << CPU_BIT(cpu)); 1971e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = rb_next(n); 1972e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1973e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1974e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 1975e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * we can't continue if pdi->cpu_map has entries set that we don't 1976e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * have in the sort rbtree. the opposite is not a problem, though 1977e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1978e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = 0; 1979e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0; i < pdi->cpu_map_max / CPUS_PER_LONG; i++) { 1980e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdi->cpu_map[i] & ~(cpu_map[i])) { 1981e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = 1; 1982e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1983e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1984e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1985e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1986e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(cpu_map); 1987e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ret; 1988e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1989e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1990e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int check_sequence(struct per_dev_info *pdi, struct trace *t, int force) 1991e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1992e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *bit = t->bit; 1993e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long expected_sequence; 1994e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci; 1995e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *__t; 1996e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1997e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci = get_cpu_info(pdi, bit->cpu); 1998e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat expected_sequence = pci->last_sequence + 1; 1999e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2000e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!expected_sequence) { 2001e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 2002e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1 should be the first entry, just allow it 2003e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2004e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->sequence == 1) 2005e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2006e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->sequence == pci->smallest_seq_read) 2007e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2008e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2009e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return check_cpu_map(pdi); 2010e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2011e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2012e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->sequence == expected_sequence) 2013e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2014e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2015e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 2016e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * we may not have seen that sequence yet. if we are not doing 2017e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * the final run, break and wait for more entries. 2018e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2019e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (expected_sequence < pci->smallest_seq_read) { 2020e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __t = trace_rb_find_last(pdi, pci, expected_sequence); 2021e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!__t) 2022e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto skip; 2023e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2024e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __put_trace_last(pdi, __t); 2025e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2026e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else if (!force) { 2027e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2028e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 2029e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatskip: 2030e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (check_current_skips(pci, bit->sequence)) 2031e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2032e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2033e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (expected_sequence < bit->sequence) 2034e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat insert_skip(pci, expected_sequence, bit->sequence - 1); 2035e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2036e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2037e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2038e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2039e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void show_entries_rb(int force) 2040e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2041e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi = NULL; 2042e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci = NULL; 2043e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *bit; 2044e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *n; 2045e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *t; 2046e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2047e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while ((n = rb_first(&rb_sort_root)) != NULL) { 2048e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (is_done() && !force && !pipeline) 2049e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2050e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2051e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t = rb_entry(n, struct trace, rb_node); 2052e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit = t->bit; 2053e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2054e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (read_sequence - t->read_sequence < 1 && !force) 2055e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2056e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2057e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pdi || pdi->dev != bit->device) { 2058e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi = get_dev_info(bit->device); 2059e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci = NULL; 2060e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2061e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2062e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pdi) { 2063e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Unknown device ID? (%d,%d)\n", 2064e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat MAJOR(bit->device), MINOR(bit->device)); 2065e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2066e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2067e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2068e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (check_sequence(pdi, t, force)) 2069e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2070e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2071e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!force && bit->time > last_allowed_time) 2072e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2073e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2074e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat check_time(pdi, bit); 2075e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2076e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pci || pci->cpu != bit->cpu) 2077e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci = get_cpu_info(pdi, bit->cpu); 2078e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2079e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->last_sequence = bit->sequence; 2080e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2081e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->nelems++; 2082e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2083e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->action & (act_mask << BLK_TC_SHIFT)) 2084e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_trace(bit, pci, pdi); 2085e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2086e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat put_trace(pdi, t); 2087e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2088e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2089e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2090e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int read_data(int fd, void *buffer, int bytes, int block, int *fdblock) 2091e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2092e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int ret, bytes_left, fl; 2093e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat void *p; 2094e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2095e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (block != *fdblock) { 2096e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fl = fcntl(fd, F_GETFL); 2097e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2098e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!block) { 2099e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *fdblock = 0; 2100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fcntl(fd, F_SETFL, fl | O_NONBLOCK); 2101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 2102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *fdblock = 1; 2103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fcntl(fd, F_SETFL, fl & ~O_NONBLOCK); 2104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bytes_left = bytes; 2108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = buffer; 2109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (bytes_left > 0) { 2110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = read(fd, p, bytes_left); 2111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!ret) 2112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (ret < 0) { 2114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (errno != EAGAIN) { 2115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror("read"); 2116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 2117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 2120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * never do partial reads. we can return if we 2121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * didn't read anything and we should not block, 2122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * otherwise wait for data 2123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if ((bytes_left == bytes) && !block) 2125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat usleep(10); 2128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue; 2129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 2130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p += ret; 2131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bytes_left -= ret; 2132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline __u16 get_pdulen(struct blk_io_trace *bit) 2139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (data_is_native) 2141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return bit->pdu_len; 2142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return __bswap_16(bit->pdu_len); 2144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline __u32 get_magic(struct blk_io_trace *bit) 2147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (data_is_native) 2149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return bit->magic; 2150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return __bswap_32(bit->magic); 2152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int read_events(int fd, int always_block, int *fdblock) 2155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi = NULL; 2157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int events = 0; 2158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (!is_done() && events < rb_batch) { 2160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *bit; 2161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *t; 2162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int pdu_len, should_block, ret; 2163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u32 magic; 2164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit = bit_alloc(); 2166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat should_block = !events || always_block; 2168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = read_data(fd, bit, sizeof(*bit), should_block, fdblock); 2170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ret) { 2171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_free(bit); 2172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!events && ret < 0) 2173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat events = ret; 2174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 2178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * look at first trace to check whether we need to convert 2179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * data in the future 2180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (data_is_native == -1 && check_data_endianness(bit->magic)) 2182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat magic = get_magic(bit); 2185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if ((magic & 0xffffff00) != BLK_IO_TRACE_MAGIC) { 2186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Bad magic %x\n", magic); 2187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdu_len = get_pdulen(bit); 2191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdu_len) { 2192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat void *ptr = realloc(bit, sizeof(*bit) + pdu_len); 2193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (read_data(fd, ptr + sizeof(*bit), pdu_len, 1, fdblock)) { 2195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_free(ptr); 2196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit = ptr; 2200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat trace_to_cpu(bit); 2203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verify_trace(bit)) { 2205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_free(bit); 2206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue; 2207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 2210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * not a real trace, so grab and handle it here 2211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) && bit->action != BLK_TN_MESSAGE) { 2213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat handle_notify(bit); 2214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat output_binary(bit, sizeof(*bit) + bit->pdu_len); 2215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue; 2216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t = t_alloc(); 2219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(t, 0, sizeof(*t)); 2220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t->bit = bit; 2221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t->read_sequence = read_sequence; 2222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t->next = trace_list; 2224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat trace_list = t; 2225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pdi || pdi->dev != bit->device) 2227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi = get_dev_info(bit->device); 2228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->time > pdi->last_read_time) 2230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->last_read_time = bit->time; 2231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat events++; 2233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return events; 2236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 2239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Managing input streams 2240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct ms_stream { 2243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct ms_stream *next; 2244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *first, *last; 2245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi; 2246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int cpu; 2247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 2248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define MS_HASH(d, c) ((MAJOR(d) & 0xff) ^ (MINOR(d) & 0xff) ^ (cpu & 0xff)) 2250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct ms_stream *ms_head; 2252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct ms_stream *ms_hash[256]; 2253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void ms_sort(struct ms_stream *msp); 2255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int ms_prime(struct ms_stream *msp); 2256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct trace *ms_peek(struct ms_stream *msp) 2258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return (msp == NULL) ? NULL : msp->first; 2260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline __u64 ms_peek_time(struct ms_stream *msp) 2263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ms_peek(msp)->bit->time; 2265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void ms_resort(struct ms_stream *msp) 2268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (msp->next && ms_peek_time(msp) > ms_peek_time(msp->next)) { 2270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_head = msp->next; 2271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->next = NULL; 2272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_sort(msp); 2273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void ms_deq(struct ms_stream *msp) 2277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->first = msp->first->next; 2279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!msp->first) { 2280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->last = NULL; 2281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!ms_prime(msp)) { 2282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_head = msp->next; 2283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->next = NULL; 2284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 2285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_resort(msp); 2289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void ms_sort(struct ms_stream *msp) 2292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 msp_t = ms_peek_time(msp); 2294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct ms_stream *this_msp = ms_head; 2295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (this_msp == NULL) 2297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_head = msp; 2298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (msp_t < ms_peek_time(this_msp)) { 2299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->next = this_msp; 2300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_head = msp; 2301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 2303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (this_msp->next && ms_peek_time(this_msp->next) < msp_t) 2304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this_msp = this_msp->next; 2305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->next = this_msp->next; 2307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this_msp->next = msp; 2308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int ms_prime(struct ms_stream *msp) 2312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u32 magic; 2314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned int i; 2315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *t; 2316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi = msp->pdi; 2317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci = get_cpu_info(pdi, msp->cpu); 2318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *bit = NULL; 2319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int ret, pdu_len, ndone = 0; 2320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0; !is_done() && pci->fd >= 0 && i < rb_batch; i++) { 2322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit = bit_alloc(); 2323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = read_data(pci->fd, bit, sizeof(*bit), 1, &pci->fdblock); 2324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ret) 2325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto err; 2326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (data_is_native == -1 && check_data_endianness(bit->magic)) 2328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto err; 2329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat magic = get_magic(bit); 2331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if ((magic & 0xffffff00) != BLK_IO_TRACE_MAGIC) { 2332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Bad magic %x\n", magic); 2333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto err; 2334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdu_len = get_pdulen(bit); 2338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pdu_len) { 2339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat void *ptr = realloc(bit, sizeof(*bit) + pdu_len); 2340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = read_data(pci->fd, ptr + sizeof(*bit), pdu_len, 2341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1, &pci->fdblock); 2342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ret) { 2343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(ptr); 2344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit = NULL; 2345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto err; 2346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit = ptr; 2349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat trace_to_cpu(bit); 2352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verify_trace(bit)) 2353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto err; 2354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) && bit->action != BLK_TN_MESSAGE) { 2356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat handle_notify(bit); 2357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat output_binary(bit, sizeof(*bit) + bit->pdu_len); 2358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_free(bit); 2359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat i -= 1; 2361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue; 2362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit->time > pdi->last_read_time) 2365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->last_read_time = bit->time; 2366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t = t_alloc(); 2368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(t, 0, sizeof(*t)); 2369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t->bit = bit; 2370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (msp->first == NULL) 2372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->first = msp->last = t; 2373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 2374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->last->next = t; 2375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->last = t; 2376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ndone++; 2379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ndone; 2382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehaterr: 2384e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bit) bit_free(bit); 2385e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2386e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu_mark_offline(pdi, pci->cpu); 2387e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat close(pci->fd); 2388e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->fd = -1; 2389e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2390e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ndone; 2391e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2392e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2393e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct ms_stream *ms_alloc(struct per_dev_info *pdi, int cpu) 2394e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2395e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct ms_stream *msp = malloc(sizeof(*msp)); 2396e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2397e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->next = NULL; 2398e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->first = msp->last = NULL; 2399e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->pdi = pdi; 2400e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat msp->cpu = cpu; 2401e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2402e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ms_prime(msp)) 2403e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_sort(msp); 2404e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2405e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return msp; 2406e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2407e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2408e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int setup_file(struct per_dev_info *pdi, int cpu) 2409e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2410e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int len = 0; 2411e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct stat st; 2412e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *p, *dname; 2413e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci = get_cpu_info(pdi, cpu); 2414e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2415e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->cpu = cpu; 2416e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->fdblock = -1; 2417e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2418e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = strdup(pdi->name); 2419e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dname = dirname(p); 2420e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (strcmp(dname, ".")) { 2421e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat input_dir = dname; 2422e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = strdup(pdi->name); 2423e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat strcpy(pdi->name, basename(p)); 2424e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2425e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(p); 2426e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2427e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (input_dir) 2428e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat len = sprintf(pci->fname, "%s/", input_dir); 2429e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2430e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat snprintf(pci->fname + len, sizeof(pci->fname)-1-len, 2431e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "%s.blktrace.%d", pdi->name, pci->cpu); 2432e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (stat(pci->fname, &st) < 0) 2433e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2434e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!st.st_size) 2435e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2436e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2437e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->fd = open(pci->fname, O_RDONLY); 2438e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pci->fd < 0) { 2439e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror(pci->fname); 2440e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2441e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2442e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2443e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat printf("Input file %s added\n", pci->fname); 2444e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu_mark_online(pdi, pci->cpu); 2445e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2446e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->nfiles++; 2447e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_alloc(pdi, pci->cpu); 2448e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2449e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2450e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2451e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2452e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int handle(struct ms_stream *msp) 2453e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2454e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct trace *t; 2455e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi; 2456e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_cpu_info *pci; 2457e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct blk_io_trace *bit; 2458e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2459e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t = ms_peek(msp); 2460e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2461e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit = t->bit; 2462e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi = msp->pdi; 2463e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci = get_cpu_info(pdi, msp->cpu); 2464e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pci->nelems++; 2465e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit->time -= genesis_time; 2466e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2467e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (t->bit->time > stopwatch_end) 2468e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2469e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2470e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi->last_reported_time = bit->time; 2471e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if ((bit->action & (act_mask << BLK_TC_SHIFT))&& 2472e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t->bit->time >= stopwatch_start) 2473e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_trace(bit, pci, pdi); 2474e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2475e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ms_deq(msp); 2476e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2477e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (text_output) 2478e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat trace_rb_insert_last(pdi, t); 2479e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 2480e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bit_free(t->bit); 2481e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t_free(t); 2482e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2483e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2484e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2485e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2486e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2487e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 2488e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Check if we need to sanitize the name. We allow 'foo', or if foo.blktrace.X 2489e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * is given, then strip back down to 'foo' to avoid missing files. 2490e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2491e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int name_fixup(char *name) 2492e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2493e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *b; 2494e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2495e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!name) 2496e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2497e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2498e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat b = strstr(name, ".blktrace."); 2499e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (b) 2500e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *b = '\0'; 2501e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2502e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2503e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2504e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2505e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int do_file(void) 2506e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2507e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i, cpu, ret; 2508e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct per_dev_info *pdi; 2509e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2510e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 2511e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * first prepare all files for reading 2512e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2513e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0; i < ndevices; i++) { 2514e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pdi = &devices[i]; 2515e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = name_fixup(pdi->name); 2516e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ret) 2517e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ret; 2518e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2519e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (cpu = 0; setup_file(pdi, cpu); cpu++) 2520e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ; 2521e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2522e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2523e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 2524e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Get the initial time stamp 2525e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2526e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ms_head) 2527e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat genesis_time = ms_peek_time(ms_head); 2528e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2529e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 2530e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Keep processing traces while any are left 2531e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2532e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (!is_done() && ms_head && handle(ms_head)) 2533e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ; 2534e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2535e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2536e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2537e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2538e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void do_pipe(int fd) 2539e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2540e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat unsigned long long youngest; 2541e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int events, fdblock; 2542e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2543e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat last_allowed_time = -1ULL; 2544e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fdblock = -1; 2545e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while ((events = read_events(fd, 0, &fdblock)) > 0) { 2546e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat read_sequence++; 2547e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2548e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#if 0 2549e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat smallest_seq_read = -1U; 2550e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#endif 2551e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2552e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sort_entries(&youngest)) 2553e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2554e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2555e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (youngest > stopwatch_end) 2556e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2557e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2558e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat show_entries_rb(0); 2559e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2560e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2561e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rb_sort_entries) 2562e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat show_entries_rb(1); 2563e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2564e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2565e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int do_fifo(void) 2566e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2567e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int fd; 2568e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2569e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!strcmp(pipename, "-")) 2570e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fd = dup(STDIN_FILENO); 2571e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 2572e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fd = open(pipename, O_RDONLY); 2573e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2574e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (fd == -1) { 2575e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror("dup stdin"); 2576e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return -1; 2577e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2578e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2579e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat do_pipe(fd); 2580e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat close(fd); 2581e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2582e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2583e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2584e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void show_stats(void) 2585e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2586e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!ofp) 2587e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 2588e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (stats_printed) 2589e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 2590e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2591e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat stats_printed = 1; 2592e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2593e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_process_stats) 2594e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat show_process_stats(); 2595e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2596e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (per_device_and_cpu_stats) 2597e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat show_device_and_cpu_stats(); 2598e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2599e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fflush(ofp); 2600e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2601e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2602e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void handle_sigint(__attribute__((__unused__)) int sig) 2603e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2604e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat done = 1; 2605e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2606e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2607e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 2608e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Extract start and duration times from a string, allowing 2609e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * us to specify a time interval of interest within a trace. 2610e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Format: "duration" (start is zero) or "start:duration". 2611e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 2612e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int find_stopwatch_interval(char *string) 2613e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2614e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat double value; 2615e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *sp; 2616e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2617e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat value = strtod(string, &sp); 2618e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sp == string) { 2619e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr,"Invalid stopwatch timer: %s\n", string); 2620e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2621e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2622e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (*sp == ':') { 2623e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat stopwatch_start = DOUBLE_TO_NANO_ULL(value); 2624e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat string = sp + 1; 2625e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat value = strtod(string, &sp); 2626e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sp == string || *sp != '\0') { 2627e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr,"Invalid stopwatch duration time: %s\n", 2628e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat string); 2629e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2630e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2631e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else if (*sp != '\0') { 2632e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr,"Invalid stopwatch start timer: %s\n", string); 2633e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2634e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2635e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat stopwatch_end = DOUBLE_TO_NANO_ULL(value); 2636e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (stopwatch_end <= stopwatch_start) { 2637e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Invalid stopwatch interval: %Lu -> %Lu\n", 2638e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat stopwatch_start, stopwatch_end); 2639e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2640e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2641e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2642e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2643e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2644e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2645e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int is_pipe(const char *str) 2646e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2647e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct stat st; 2648e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2649e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!strcmp(str, "-")) 2650e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2651e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!stat(str, &st) && S_ISFIFO(st.st_mode)) 2652e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2653e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2654e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2655e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2656e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2657e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define S_OPTS "a:A:b:D:d:f:F:hi:o:Oqstw:vVM" 2658e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char usage_str[] = "\n\n" \ 2659e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "-i <file> | --input=<file>\n" \ 2660e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -a <action field> | --act-mask=<action field> ]\n" \ 2661e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -A <action mask> | --set-mask=<action mask> ]\n" \ 2662e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -b <traces> | --batch=<traces> ]\n" \ 2663e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -d <file> | --dump-binary=<file> ]\n" \ 2664e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -D <dir> | --input-directory=<dir> ]\n" \ 2665e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -f <format> | --format=<format> ]\n" \ 2666e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -F <spec> | --format-spec=<spec> ]\n" \ 2667e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -h | --hash-by-name ]\n" \ 2668e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -o <file> | --output=<file> ]\n" \ 2669e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -O | --no-text-output ]\n" \ 2670e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -q | --quiet ]\n" \ 2671e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -s | --per-program-stats ]\n" \ 2672e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -t | --track-ios ]\n" \ 2673e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -w <time> | --stopwatch=<time> ]\n" \ 2674e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -M | --no-msgs\n" \ 2675e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -v | --verbose ]\n" \ 2676e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "[ -V | --version ]\n\n" \ 2677e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-b stdin read batching\n" \ 2678e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-d Output file. If specified, binary data is written to file\n" \ 2679e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-D Directory to prepend to input file names\n" \ 2680e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-f Output format. Customize the output format. The format field\n" \ 2681e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t identifies can be found in the documentation\n" \ 2682e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-F Format specification. Can be found in the documentation\n" \ 2683e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-h Hash processes by name, not pid\n" \ 2684e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-i Input file containing trace data, or '-' for stdin\n" \ 2685e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-o Output file. If not given, output is stdout\n" \ 2686e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-O Do NOT output text data\n" \ 2687e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-q Quiet. Don't display any stats at the end of the trace\n" \ 2688e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-s Show per-program io statistics\n" \ 2689e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-t Track individual ios. Will tell you the time a request took\n" \ 2690e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t to get queued, to get dispatched, and to get completed\n" \ 2691e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-w Only parse data between the given time interval in seconds.\n" \ 2692e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t If 'start' isn't given, blkparse defaults the start time to 0\n" \ 2693e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-M Do not output messages to binary file\n" \ 2694e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-v More verbose for marginal errors\n" \ 2695e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t-V Print program version info\n\n"; 2696e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2697e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void usage(char *prog) 2698e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2699e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Usage: %s %s %s", prog, blkparse_version, usage_str); 2700e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2701e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2702e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint main(int argc, char *argv[]) 2703e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 2704e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i, c, ret, mode; 2705e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int act_mask_tmp = 0; 2706e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *ofp_buffer = NULL; 2707e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *bin_ofp_buffer = NULL; 2708e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2709e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) != -1) { 2710e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat switch (c) { 2711e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'a': 2712e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat i = find_mask_map(optarg); 2713e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (i < 0) { 2714e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr,"Invalid action mask %s\n", 2715e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat optarg); 2716e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2717e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2718e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat act_mask_tmp |= i; 2719e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2720e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2721e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'A': 2722e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if ((sscanf(optarg, "%x", &i) != 1) || 2723e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat !valid_act_opt(i)) { 2724e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, 2725e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "Invalid set action mask %s/0x%x\n", 2726e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat optarg, i); 2727e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2728e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2729e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat act_mask_tmp = i; 2730e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2731e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'i': 2732e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (is_pipe(optarg) && !pipeline) { 2733e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pipeline = 1; 2734e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pipename = strdup(optarg); 2735e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else if (resize_devices(optarg) != 0) 2736e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2737e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2738e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'D': 2739e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat input_dir = optarg; 2740e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2741e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'o': 2742e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat output_name = optarg; 2743e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2744e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'O': 2745e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat text_output = 0; 2746e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2747e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'b': 2748e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_batch = atoi(optarg); 2749e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rb_batch <= 0) 2750e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_batch = RB_BATCH_DEFAULT; 2751e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2752e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 's': 2753e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat per_process_stats = 1; 2754e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2755e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 't': 2756e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat track_ios = 1; 2757e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2758e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'q': 2759e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat per_device_and_cpu_stats = 0; 2760e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2761e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'w': 2762e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (find_stopwatch_interval(optarg) != 0) 2763e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2764e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2765e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'f': 2766e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat set_all_format_specs(optarg); 2767e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2768e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'F': 2769e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (add_format_spec(optarg) != 0) 2770e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2771e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2772e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'h': 2773e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ppi_hash_by_pid = 0; 2774e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2775e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'v': 2776e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat verbose++; 2777e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2778e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'V': 2779e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat printf("%s version %s\n", argv[0], blkparse_version); 2780e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 2781e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'd': 2782e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_binary = optarg; 2783e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2784e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'M': 2785e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bin_output_msgs = 0; 2786e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 2787e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat default: 2788e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat usage(argv[0]); 2789e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2790e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2791e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2792e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2793e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (optind < argc) { 2794e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (is_pipe(argv[optind]) && !pipeline) { 2795e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pipeline = 1; 2796e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pipename = strdup(argv[optind]); 2797e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else if (resize_devices(argv[optind]) != 0) 2798e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2799e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat optind++; 2800e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2801e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2802e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pipeline && !ndevices) { 2803e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat usage(argv[0]); 2804e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2805e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2806e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2807e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (act_mask_tmp != 0) 2808e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat act_mask = act_mask_tmp; 2809e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2810e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(&rb_sort_root, 0, sizeof(rb_sort_root)); 2811e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2812e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat signal(SIGINT, handle_sigint); 2813e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat signal(SIGHUP, handle_sigint); 2814e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat signal(SIGTERM, handle_sigint); 2815e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2816e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat setlocale(LC_NUMERIC, "en_US"); 2817e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2818e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (text_output) { 2819e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!output_name) { 2820e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ofp = fdopen(STDOUT_FILENO, "w"); 2821e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat mode = _IOLBF; 2822e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else { 2823e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char ofname[128]; 2824e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2825e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat snprintf(ofname, sizeof(ofname) - 1, "%s", output_name); 2826e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ofp = fopen(ofname, "w"); 2827e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat mode = _IOFBF; 2828e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2829e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2830e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!ofp) { 2831e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror("fopen"); 2832e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2833e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2834e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2835e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ofp_buffer = malloc(4096); 2836e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (setvbuf(ofp, ofp_buffer, mode, 4096)) { 2837e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror("setvbuf"); 2838e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2839e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2840e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2841e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2842e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (dump_binary) { 2843e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_fp = fopen(dump_binary, "w"); 2844e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!dump_fp) { 2845e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror(dump_binary); 2846e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dump_binary = NULL; 2847e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2848e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2849e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat bin_ofp_buffer = malloc(128 * 1024); 2850e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (setvbuf(dump_fp, bin_ofp_buffer, _IOFBF, 128 * 1024)) { 2851e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror("setvbuf binary"); 2852e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 2853e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2854e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2855e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2856e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pipeline) 2857e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = do_fifo(); 2858e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 2859e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ret = do_file(); 2860e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2861e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!ret) 2862e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat show_stats(); 2863e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2864e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (have_drv_data && !dump_binary) 2865e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat printf("\ndiscarded traces containing low-level device driver " 2866e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "specific data (only available in binary output)\n"); 2867e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 2868e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ofp_buffer) { 2869e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fflush(ofp); 2870e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(ofp_buffer); 2871e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2872e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (bin_ofp_buffer) { 2873e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fflush(dump_fp); 2874e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(bin_ofp_buffer); 2875e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 2876e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ret; 2877e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 2878