1fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe/* 2fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe * blktrace support code for fio 3fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe */ 4fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe#include <stdio.h> 5fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe#include <stdlib.h> 65e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe#include <sys/stat.h> 75e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe#include <dirent.h> 88c1fdf044083522504685e3009e356c70d003ef0Jens Axboe 901743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe#include "flist.h" 10fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe#include "fio.h" 11fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe#include "blktrace_api.h" 12fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 132da7df1d7d002d11161374ac4f0144521f7be0f0Jens Axboe#define TRACE_FIFO_SIZE 8192 14e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 15e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe/* 16e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe * fifo refill frontend, to avoid reading data in trace sized bites 17e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe */ 18e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboestatic int refill_fifo(struct thread_data *td, struct fifo *fifo, int fd) 19e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe{ 20e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe char buf[TRACE_FIFO_SIZE]; 21f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe unsigned int total; 22e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe int ret; 23e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 24f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe total = sizeof(buf); 25f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe if (total > fifo_room(fifo)) 26f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe total = fifo_room(fifo); 27e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 28f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe ret = read(fd, buf, total); 29f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe if (ret < 0) { 30f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe td_verror(td, errno, "read blktrace file"); 31f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe return -1; 32e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe } 33e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 34f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe if (ret > 0) 35f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe ret = fifo_put(fifo, buf, ret); 36f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe 37bd6f78b2f0b6375383948f126368804612ec0035Jens Axboe dprint(FD_BLKTRACE, "refill: filled %d bytes\n", ret); 38f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe return ret; 39e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe} 40e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 41e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe/* 42e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe * Retrieve 'len' bytes from the fifo, refilling if necessary. 43e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe */ 44e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboestatic int trace_fifo_get(struct thread_data *td, struct fifo *fifo, int fd, 45e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe void *buf, unsigned int len) 46e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe{ 47f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe if (fifo_len(fifo) < len) { 48f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe int ret = refill_fifo(td, fifo, fd); 49e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 50f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe if (ret < 0) 51f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe return ret; 52f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe } 53e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 54e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe return fifo_get(fifo, buf, len); 55e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe} 56e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 578c1fdf044083522504685e3009e356c70d003ef0Jens Axboe/* 588c1fdf044083522504685e3009e356c70d003ef0Jens Axboe * Just discard the pdu by seeking past it. 598c1fdf044083522504685e3009e356c70d003ef0Jens Axboe */ 60f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboestatic int discard_pdu(struct thread_data *td, struct fifo *fifo, int fd, 61f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe struct blk_io_trace *t) 62fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe{ 63fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe if (t->pdu_len == 0) 64fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe return 0; 65fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 66bd6f78b2f0b6375383948f126368804612ec0035Jens Axboe dprint(FD_BLKTRACE, "discard pdu len %u\n", t->pdu_len); 67f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe return trace_fifo_get(td, fifo, fd, NULL, t->pdu_len); 68fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe} 69fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 708c1fdf044083522504685e3009e356c70d003ef0Jens Axboe/* 718c1fdf044083522504685e3009e356c70d003ef0Jens Axboe * Check if this is a blktrace binary data file. We read a single trace 728c1fdf044083522504685e3009e356c70d003ef0Jens Axboe * into memory and check for the magic signature. 738c1fdf044083522504685e3009e356c70d003ef0Jens Axboe */ 74d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboeint is_blktrace(const char *filename, int *need_swap) 75fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe{ 76fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe struct blk_io_trace t; 77fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe int fd, ret; 78fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 79fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe fd = open(filename, O_RDONLY); 804dced40768378754a156bb3327b10df53cf7eb8cJens Axboe if (fd < 0) 81fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe return 0; 82fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 83fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe ret = read(fd, &t, sizeof(t)); 84fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe close(fd); 85fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 86fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe if (ret < 0) { 87fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe perror("read blktrace"); 88fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe return 0; 89fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe } else if (ret != sizeof(t)) { 90fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe log_err("fio: short read on blktrace file\n"); 91fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe return 0; 92fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe } 93fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 94d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe if ((t.magic & 0xffffff00) == BLK_IO_TRACE_MAGIC) { 95d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe *need_swap = 0; 96fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe return 1; 97d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe } 98d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe 99d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe /* 100d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe * Maybe it needs to be endian swapped... 101d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe */ 102d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t.magic = fio_swap32(t.magic); 103d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe if ((t.magic & 0xffffff00) == BLK_IO_TRACE_MAGIC) { 104d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe *need_swap = 1; 105d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe return 1; 106d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe } 107fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 108fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe return 0; 109fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe} 110fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 111d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellansstatic int lookup_device(struct thread_data *td, char *path, unsigned int maj, 112d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans unsigned int min) 1135e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe{ 1145e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe struct dirent *dir; 1155e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe struct stat st; 1165e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe int found = 0; 1175e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe DIR *D; 1185e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 1195e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe D = opendir(path); 1205e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe if (!D) 1215e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe return 0; 1225e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 1235e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe while ((dir = readdir(D)) != NULL) { 1245e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe char full_path[256]; 1255e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 1265e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")) 1275e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe continue; 1285e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 129b9fd788f0e8adacc33316107594e9eb0463743d7Bruce Cran sprintf(full_path, "%s%s%s", path, FIO_OS_PATH_SEPARATOR, dir->d_name); 1305e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe if (lstat(full_path, &st) == -1) { 1315e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe perror("lstat"); 1325e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe break; 1335e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe } 1345e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 1355e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe if (S_ISDIR(st.st_mode)) { 136d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans found = lookup_device(td, full_path, maj, min); 1375e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe if (found) { 1385e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe strcpy(path, full_path); 1395e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe break; 1405e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe } 1415e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe } 1425e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 1435e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe if (!S_ISBLK(st.st_mode)) 1445e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe continue; 1455e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 146d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans /* 147d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans * If replay_redirect is set then always return this device 148d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans * upon lookup which overrides the device lookup based on 149d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans * major minor in the actual blktrace 150d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans */ 151d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans if (td->o.replay_redirect) { 152d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans dprint(FD_BLKTRACE, "device lookup: %d/%d\n overridden" 15325a4e78bf7a20802fc64dc4368a821be7dc529c3Jens Axboe " with: %s\n", maj, min, 154d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans td->o.replay_redirect); 155d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans strcpy(path, td->o.replay_redirect); 156d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans found = 1; 157d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans break; 158d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans } 159d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans 1605e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe if (maj == major(st.st_rdev) && min == minor(st.st_rdev)) { 1615ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe dprint(FD_BLKTRACE, "device lookup: %d/%d\n", maj, min); 1625e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe strcpy(path, full_path); 1635e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe found = 1; 1645e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe break; 1655e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe } 1665e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe } 1675e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 1685e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe closedir(D); 1695e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe return found; 1705e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe} 1715e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 172c69aa91fa88fe1f0372afe2a56c4e79c62fc49e0Jens Axboe#define FMINORBITS 20 173c69aa91fa88fe1f0372afe2a56c4e79c62fc49e0Jens Axboe#define FMINORMASK ((1U << FMINORBITS) - 1) 174c69aa91fa88fe1f0372afe2a56c4e79c62fc49e0Jens Axboe#define FMAJOR(dev) ((unsigned int) ((dev) >> FMINORBITS)) 175c69aa91fa88fe1f0372afe2a56c4e79c62fc49e0Jens Axboe#define FMINOR(dev) ((unsigned int) ((dev) & FMINORMASK)) 176eeb9c2aa5439dd6615ad69324f402f774173f6e5Jens Axboe 17789ac1d48971578ccb0645c292d4a058340aeb909Shaohua Listatic void trace_add_open_close_event(struct thread_data *td, int fileno, enum file_log_act action) 178691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe{ 179691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe struct io_piece *ipo; 180691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe 181691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe ipo = calloc(1, sizeof(*ipo)); 1820d29de831183dfd049c97a03008d425ce21e2fa4Jens Axboe init_ipo(ipo); 183691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe 184691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe ipo->ddir = DDIR_INVAL; 185691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe ipo->fileno = fileno; 18689ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li ipo->file_action = action; 18701743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe flist_add_tail(&ipo->list, &td->io_log_list); 188691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe} 189691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe 19089ac1d48971578ccb0645c292d4a058340aeb909Shaohua Listatic int trace_add_file(struct thread_data *td, __u32 device) 1915e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe{ 19289ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li static unsigned int last_maj, last_min, last_fileno; 193c69aa91fa88fe1f0372afe2a56c4e79c62fc49e0Jens Axboe unsigned int maj = FMAJOR(device); 194c69aa91fa88fe1f0372afe2a56c4e79c62fc49e0Jens Axboe unsigned int min = FMINOR(device); 1955e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe struct fio_file *f; 1965e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe char dev[256]; 1975e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe unsigned int i; 1985e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 1995e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe if (last_maj == maj && last_min == min) 20089ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li return last_fileno; 2015e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 2025e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe last_maj = maj; 2035e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe last_min = min; 2045e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 2055e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe /* 2065e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe * check for this file in our list 2075e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe */ 2085e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe for_each_file(td, f, i) 20989ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li if (f->major == maj && f->minor == min) { 21089ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li last_fileno = f->fileno; 21189ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li return last_fileno; 21289ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li } 2135e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 2145e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe strcpy(dev, "/dev"); 215d1c46c049cfba2028abc45246e2609bcee52d0f3David Nellans if (lookup_device(td, dev, maj, min)) { 216691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe int fileno; 217691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe 218bd6f78b2f0b6375383948f126368804612ec0035Jens Axboe dprint(FD_BLKTRACE, "add devices %s\n", dev); 21949ffb4a2e1ac3026d77d9e1c03edc2753fcec41bJens Axboe fileno = add_file_exclusive(td, dev); 220b53f2c545d8335380b507bd7281178c25d27ddf0Jens Axboe td->o.open_files++; 2215903e7b7907854014478b6febfc5645a203ff59eJens Axboe td->files[fileno]->major = maj; 2225903e7b7907854014478b6febfc5645a203ff59eJens Axboe td->files[fileno]->minor = min; 22389ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li trace_add_open_close_event(td, fileno, FIO_LOG_OPEN_FILE); 22489ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li last_fileno = fileno; 225bd6f78b2f0b6375383948f126368804612ec0035Jens Axboe } 226f01b34ae759afccf39c1bf47972e45d91448e7bbJens Axboe 22789ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li return last_fileno; 2285e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe} 2295e6c20673be9f46332f47ede0e3b657b2cc35ec4Jens Axboe 2308c1fdf044083522504685e3009e356c70d003ef0Jens Axboe/* 2318c1fdf044083522504685e3009e356c70d003ef0Jens Axboe * Store blk_io_trace data in an ipo for later retrieval. 2328c1fdf044083522504685e3009e356c70d003ef0Jens Axboe */ 233fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboestatic void store_ipo(struct thread_data *td, unsigned long long offset, 23489ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li unsigned int bytes, int rw, unsigned long long ttime, 23589ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li int fileno) 236fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe{ 237fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe struct io_piece *ipo = malloc(sizeof(*ipo)); 238fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe 2390d29de831183dfd049c97a03008d425ce21e2fa4Jens Axboe init_ipo(ipo); 2400d29de831183dfd049c97a03008d425ce21e2fa4Jens Axboe 241a2eea81b53fc1a71b91b20d82bcadffdd4ecb6cdJens Axboe /* 242a2eea81b53fc1a71b91b20d82bcadffdd4ecb6cdJens Axboe * the 512 is wrong here, it should be the hardware sector size... 243a2eea81b53fc1a71b91b20d82bcadffdd4ecb6cdJens Axboe */ 244a2eea81b53fc1a71b91b20d82bcadffdd4ecb6cdJens Axboe ipo->offset = offset * 512; 245fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe ipo->len = bytes; 2468c1fdf044083522504685e3009e356c70d003ef0Jens Axboe ipo->delay = ttime / 1000; 247fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe if (rw) 248fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe ipo->ddir = DDIR_WRITE; 249fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe else 250fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe ipo->ddir = DDIR_READ; 25189ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li ipo->fileno = fileno; 252fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe 253bd6f78b2f0b6375383948f126368804612ec0035Jens Axboe dprint(FD_BLKTRACE, "store ddir=%d, off=%llu, len=%lu, delay=%lu\n", 254bd6f78b2f0b6375383948f126368804612ec0035Jens Axboe ipo->ddir, ipo->offset, 255bd6f78b2f0b6375383948f126368804612ec0035Jens Axboe ipo->len, ipo->delay); 256691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe queue_io_piece(td, ipo); 257fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe} 258fdefd987d7ba284c7a9e101911c4b8e72fe326adJens Axboe 2590b9d69ecb14045cf3b2622ae922756b9889b25e6Jens Axboestatic void handle_trace_notify(struct blk_io_trace *t) 260cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe{ 261691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe switch (t->action) { 262691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe case BLK_TN_PROCESS: 263d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe log_info("blktrace: got process notify: %x, %d\n", 264d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->action, t->pid); 265691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe break; 266691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe case BLK_TN_TIMESTAMP: 267d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe log_info("blktrace: got timestamp notify: %x, %d\n", 268d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->action, t->pid); 269691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe break; 270ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe case BLK_TN_MESSAGE: 271ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe break; 272691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe default: 273691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe dprint(FD_BLKTRACE, "unknown trace act %x\n", t->action); 274691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe break; 275691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe } 276691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe} 2775b3023b818d5127504b4889f8f718c3cef62700bJens Axboe 278ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboestatic void handle_trace_discard(struct thread_data *td, struct blk_io_trace *t, 279ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe unsigned long long ttime, unsigned long *ios) 280ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe{ 281ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe struct io_piece *ipo = malloc(sizeof(*ipo)); 28289ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li int fileno; 283ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe 2840d29de831183dfd049c97a03008d425ce21e2fa4Jens Axboe init_ipo(ipo); 28589ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li fileno = trace_add_file(td, t->device); 286ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe 287ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe ios[DDIR_WRITE]++; 288ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe td->o.size += t->bytes; 289ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe 290ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe memset(ipo, 0, sizeof(*ipo)); 291ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe INIT_FLIST_HEAD(&ipo->list); 292ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe 293ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe /* 294ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe * the 512 is wrong here, it should be the hardware sector size... 295ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe */ 296ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe ipo->offset = t->sector * 512; 297ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe ipo->len = t->bytes; 298ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe ipo->delay = ttime / 1000; 299ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe ipo->ddir = DDIR_TRIM; 30089ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li ipo->fileno = fileno; 301ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe 302ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe dprint(FD_BLKTRACE, "store discard, off=%llu, len=%lu, delay=%lu\n", 303ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe ipo->offset, ipo->len, 304ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe ipo->delay); 305ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe queue_io_piece(td, ipo); 306ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe} 307ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe 308691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboestatic void handle_trace_fs(struct thread_data *td, struct blk_io_trace *t, 309691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe unsigned long long ttime, unsigned long *ios, 310691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe unsigned int *bs) 311691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe{ 312691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe int rw; 31389ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li int fileno; 3145b3023b818d5127504b4889f8f718c3cef62700bJens Axboe 31589ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li fileno = trace_add_file(td, t->device); 3165b3023b818d5127504b4889f8f718c3cef62700bJens Axboe 3175b3023b818d5127504b4889f8f718c3cef62700bJens Axboe rw = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; 3185b3023b818d5127504b4889f8f718c3cef62700bJens Axboe 3195b3023b818d5127504b4889f8f718c3cef62700bJens Axboe if (t->bytes > bs[rw]) 3205b3023b818d5127504b4889f8f718c3cef62700bJens Axboe bs[rw] = t->bytes; 3215b3023b818d5127504b4889f8f718c3cef62700bJens Axboe 3225b3023b818d5127504b4889f8f718c3cef62700bJens Axboe ios[rw]++; 3235b3023b818d5127504b4889f8f718c3cef62700bJens Axboe td->o.size += t->bytes; 32489ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li store_ipo(td, t->sector, t->bytes, rw, ttime, fileno); 325cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe} 326cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe 327cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe/* 328691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe * We only care for queue traces, most of the others are side effects 329691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe * due to internal workings of the block layer. 330691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe */ 331691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboestatic void handle_trace(struct thread_data *td, struct blk_io_trace *t, 332691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe unsigned long long ttime, unsigned long *ios, 333691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe unsigned int *bs) 334691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe{ 335691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe if ((t->action & 0xffff) != __BLK_TA_QUEUE) 336691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe return; 337691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe if (t->action & BLK_TC_ACT(BLK_TC_PC)) 338691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe return; 339691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe 340691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe if (t->action & BLK_TC_ACT(BLK_TC_NOTIFY)) 341aec2de209564a6951e6c91d653fc99a75508607dJens Axboe handle_trace_notify(t); 342ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe else if (t->action & BLK_TC_ACT(BLK_TC_DISCARD)) 343ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe handle_trace_discard(td, t, ttime, ios); 344691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe else 345691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe handle_trace_fs(td, t, ttime, ios, bs); 346691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe} 347691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe 348d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboestatic void byteswap_trace(struct blk_io_trace *t) 349d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe{ 350d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->magic = fio_swap32(t->magic); 351d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->sequence = fio_swap32(t->sequence); 352d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->time = fio_swap64(t->time); 353d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->sector = fio_swap64(t->sector); 354d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->bytes = fio_swap32(t->bytes); 355d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->action = fio_swap32(t->action); 356d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->pid = fio_swap32(t->pid); 357d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->device = fio_swap32(t->device); 358d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->cpu = fio_swap32(t->cpu); 359d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->error = fio_swap16(t->error); 360d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe t->pdu_len = fio_swap16(t->pdu_len); 361d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe} 362d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe 363691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe/* 3648c1fdf044083522504685e3009e356c70d003ef0Jens Axboe * Load a blktrace file by reading all the blk_io_trace entries, and storing 3658c1fdf044083522504685e3009e356c70d003ef0Jens Axboe * them as io_pieces like the fio text version would do. 3668c1fdf044083522504685e3009e356c70d003ef0Jens Axboe */ 367d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboeint load_blktrace(struct thread_data *td, const char *filename, int need_swap) 368fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe{ 369a61eddecca21d19f3f4c297400d6c5d93dc29259Jens Axboe unsigned long long ttime, delay; 370fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe struct blk_io_trace t; 3714241ea8fb0606f9bd5b7ed1278d3b7825883acf6Jens Axboe unsigned long ios[2], skipped_writes; 372a61eddecca21d19f3f4c297400d6c5d93dc29259Jens Axboe unsigned int cpu; 373d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe unsigned int rw_bs[2]; 374e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe struct fifo *fifo; 3755903e7b7907854014478b6febfc5645a203ff59eJens Axboe int fd, i, old_state; 37689ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li struct fio_file *f; 377eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe int this_depth, depth; 378fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 379fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe fd = open(filename, O_RDONLY); 380fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe if (fd < 0) { 381fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe td_verror(td, errno, "open blktrace file"); 382fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe return 1; 383fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe } 384fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 385e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe fifo = fifo_alloc(TRACE_FIFO_SIZE); 386e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe 3878edd973d57a311d4c590d7385796bbdf111ed04cJens Axboe old_state = td_bump_runstate(td, TD_SETTING_UP); 3885903e7b7907854014478b6febfc5645a203ff59eJens Axboe 3896df8adaaadb71340b47f2c3e971297b656082ca5Jens Axboe td->o.size = 0; 3906df8adaaadb71340b47f2c3e971297b656082ca5Jens Axboe 391a61eddecca21d19f3f4c297400d6c5d93dc29259Jens Axboe cpu = 0; 392d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe ttime = 0; 393d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe ios[0] = ios[1] = 0; 394d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe rw_bs[0] = rw_bs[1] = 0; 3954241ea8fb0606f9bd5b7ed1278d3b7825883acf6Jens Axboe skipped_writes = 0; 396eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe this_depth = depth = 0; 397fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe do { 398e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe int ret = trace_fifo_get(td, fifo, fd, &t, sizeof(t)); 399fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 400e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe if (ret < 0) 4018c1fdf044083522504685e3009e356c70d003ef0Jens Axboe goto err; 402e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe else if (!ret) 403e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe break; 404e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe else if (ret < (int) sizeof(t)) { 405e28875637094451a3c5ec4071f964c1a02dd8f5bJens Axboe log_err("fio: short fifo get\n"); 406fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe break; 407fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe } 408fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 409d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe if (need_swap) 410d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe byteswap_trace(&t); 411d95b34a61ec3fc305fe53c0132bfe82e2e5fcc04Jens Axboe 412fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe if ((t.magic & 0xffffff00) != BLK_IO_TRACE_MAGIC) { 4135ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe log_err("fio: bad magic in blktrace data: %x\n", 4145ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe t.magic); 4158c1fdf044083522504685e3009e356c70d003ef0Jens Axboe goto err; 416fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe } 417fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe if ((t.magic & 0xff) != BLK_IO_TRACE_VERSION) { 4185ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe log_err("fio: bad blktrace version %d\n", 4195ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe t.magic & 0xff); 4208c1fdf044083522504685e3009e356c70d003ef0Jens Axboe goto err; 421fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe } 422f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe ret = discard_pdu(td, fifo, fd, &t); 423f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe if (ret < 0) { 424fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe td_verror(td, ret, "blktrace lseek"); 4258c1fdf044083522504685e3009e356c70d003ef0Jens Axboe goto err; 426f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe } else if (t.pdu_len != ret) { 427f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe log_err("fio: discarded %d of %d\n", ret, t.pdu_len); 428f12b323f5d5ca40cd966ebbcfbbfcdf0a1fc229eJens Axboe goto err; 429fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe } 430691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe if ((t.action & BLK_TC_ACT(BLK_TC_NOTIFY)) == 0) { 431eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe if ((t.action & 0xffff) == __BLK_TA_QUEUE) 432eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe this_depth++; 433eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe else if ((t.action & 0xffff) == __BLK_TA_COMPLETE) { 434eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe depth = max(depth, this_depth); 435eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe this_depth = 0; 436eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe } 437691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe if (!ttime) { 438691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe ttime = t.time; 439691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe cpu = t.cpu; 440691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe } 441691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe 442691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe delay = 0; 443691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe if (cpu == t.cpu) 444691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe delay = t.time - ttime; 445691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe if ((t.action & BLK_TC_ACT(BLK_TC_WRITE)) && read_only) 446691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe skipped_writes++; 44764bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans else { 44864bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans /* 44964bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans * set delay to zero if no_stall enabled for 45064bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans * fast replay 45164bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans */ 45264bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans if (td->o.no_stall) 45364bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans delay = 0; 45464bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans 455691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe handle_trace(td, &t, delay, ios, rw_bs); 45664bbb86598ada3fa401c61aab5ef6c37bec6d6f3David Nellans } 457691c8fb014da9dd82e999a90b5511423f4eee188Jens Axboe 4588c1fdf044083522504685e3009e356c70d003ef0Jens Axboe ttime = t.time; 459a61eddecca21d19f3f4c297400d6c5d93dc29259Jens Axboe cpu = t.cpu; 460a6edd6383bfa6f85f24080b43722c8af6d80106cJens Axboe } else { 461a6edd6383bfa6f85f24080b43722c8af6d80106cJens Axboe delay = 0; 4624241ea8fb0606f9bd5b7ed1278d3b7825883acf6Jens Axboe handle_trace(td, &t, delay, ios, rw_bs); 463a6edd6383bfa6f85f24080b43722c8af6d80106cJens Axboe } 464fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe } while (1); 465fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe 46685a47ca2eeac70bad992556d077f18752098e44fJens Axboe for (i = 0; i < td->files_index; i++) { 467f01b34ae759afccf39c1bf47972e45d91448e7bbJens Axboe f = td->files[i]; 46889ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li trace_add_open_close_event(td, f->fileno, FIO_LOG_CLOSE_FILE); 46985a47ca2eeac70bad992556d077f18752098e44fJens Axboe } 47089ac1d48971578ccb0645c292d4a058340aeb909Shaohua Li 47138470f85fa4acddab4339db9c8805a19bc87578eJens Axboe fifo_free(fifo); 472fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe close(fd); 4738c1fdf044083522504685e3009e356c70d003ef0Jens Axboe 4748edd973d57a311d4c590d7385796bbdf111ed04cJens Axboe td_restore_runstate(td, old_state); 4755903e7b7907854014478b6febfc5645a203ff59eJens Axboe 476f01b34ae759afccf39c1bf47972e45d91448e7bbJens Axboe if (!td->files_index) { 477f01b34ae759afccf39c1bf47972e45d91448e7bbJens Axboe log_err("fio: did not find replay device(s)\n"); 478f01b34ae759afccf39c1bf47972e45d91448e7bbJens Axboe return 1; 479f01b34ae759afccf39c1bf47972e45d91448e7bbJens Axboe } 480f01b34ae759afccf39c1bf47972e45d91448e7bbJens Axboe 481eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe /* 482eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe * For stacked devices, we don't always get a COMPLETE event so 483eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe * the depth grows to insane values. Limit it to something sane(r). 484eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe */ 485eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe if (!depth || depth > 1024) 486eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe depth = 1024; 487eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe 4884241ea8fb0606f9bd5b7ed1278d3b7825883acf6Jens Axboe if (skipped_writes) 4895ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe log_err("fio: %s skips replay of %lu writes due to read-only\n", 4905ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe td->o.name, skipped_writes); 4914241ea8fb0606f9bd5b7ed1278d3b7825883acf6Jens Axboe 4928c1fdf044083522504685e3009e356c70d003ef0Jens Axboe if (!ios[DDIR_READ] && !ios[DDIR_WRITE]) { 4938c1fdf044083522504685e3009e356c70d003ef0Jens Axboe log_err("fio: found no ios in blktrace data\n"); 4948c1fdf044083522504685e3009e356c70d003ef0Jens Axboe return 1; 495d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe } else if (ios[DDIR_READ] && !ios[DDIR_READ]) { 4968c1fdf044083522504685e3009e356c70d003ef0Jens Axboe td->o.td_ddir = TD_DDIR_READ; 497d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe td->o.max_bs[DDIR_READ] = rw_bs[DDIR_READ]; 498d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe } else if (!ios[DDIR_READ] && ios[DDIR_WRITE]) { 4998c1fdf044083522504685e3009e356c70d003ef0Jens Axboe td->o.td_ddir = TD_DDIR_WRITE; 500d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe td->o.max_bs[DDIR_WRITE] = rw_bs[DDIR_WRITE]; 501d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe } else { 5028c1fdf044083522504685e3009e356c70d003ef0Jens Axboe td->o.td_ddir = TD_DDIR_RW; 503d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe td->o.max_bs[DDIR_READ] = rw_bs[DDIR_READ]; 504d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe td->o.max_bs[DDIR_WRITE] = rw_bs[DDIR_WRITE]; 505d84f8d4931be0c7519bd9f97f9914b07578a9854Jens Axboe } 5068c1fdf044083522504685e3009e356c70d003ef0Jens Axboe 5078c1fdf044083522504685e3009e356c70d003ef0Jens Axboe /* 5088c1fdf044083522504685e3009e356c70d003ef0Jens Axboe * We need to do direct/raw ios to the device, to avoid getting 5098c1fdf044083522504685e3009e356c70d003ef0Jens Axboe * read-ahead in our way. 5108c1fdf044083522504685e3009e356c70d003ef0Jens Axboe */ 5118c1fdf044083522504685e3009e356c70d003ef0Jens Axboe td->o.odirect = 1; 5128c1fdf044083522504685e3009e356c70d003ef0Jens Axboe 513eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe /* 514eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe * we don't know if this option was set or not. it defaults to 1, 515eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe * so we'll just guess that we should override it if it's still 1 516eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe */ 517eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe if (td->o.iodepth != 1) 518eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe td->o.iodepth = depth; 519eb5fdcf1b045242a6bf4a9b225346c80418f3ab1Jens Axboe 520fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe return 0; 5218c1fdf044083522504685e3009e356c70d003ef0Jens Axboeerr: 5228c1fdf044083522504685e3009e356c70d003ef0Jens Axboe close(fd); 52338470f85fa4acddab4339db9c8805a19bc87578eJens Axboe fifo_free(fifo); 5248c1fdf044083522504685e3009e356c70d003ef0Jens Axboe return 1; 525fb7b71a3c99b7ead2055439bfea421579aae2691Jens Axboe} 526