Lines Matching +full:09 +full:- +full:hdr

2  * Blktrace replay utility - Play traces back
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
70 * @devnm: Device name -- 'sd*'
120 * @tip: Pointer to per-thread information this IO is associated with
140 static int cpus_to_use = -1; // Number of CPUs to use
154 static int no_stalls = 0; // Boolean: Disable pre-stalls
237 * min - Return minimum of two integers
245 * minl - Return minimum of two longs
253 * usage - Display usage string and version
257 fprintf(stderr, "Usage: btreplay -- version %s\n%s", in usage()
262 * is_send_done - Returns true if sender should quit early
263 * @tip: Per-thread information
267 return signal_done || tip->send_done; in is_send_done()
271 * is_reap_done - Returns true if reaper should quit early
272 * @tip: Per-thread information
276 return signal_done || (tip->send_done && tip->naios_out == 0); in is_reap_done()
280 * ts2ns - Convert timespec values to a nanosecond value
285 return ((__u64)(ts->tv_sec) * NS_TICKS) + (__u64)(ts->tv_nsec); in ts2ns()
289 * ts2ns - Convert timeval values to a nanosecond value
293 return ((__u64)(tp->tv_sec)) + ((__u64)(tp->tv_usec) * (__u64)1000); in tv2ns()
297 * touch_memory - Force physical memory to be allocating it
301 * as planned - we see Linux just use a single area to /read/ from
318 * buf_alloc - Returns a page-aligned buffer of the specified size
334 * gettime - Returns current time
338 static int use_clock_gettime = -1; // Which clock to use in gettime()
364 * setup_signal - Set up a signal handler for the specified signum
382 * __set_cv - Increments a variable under condition variable control.
400 * __wait_cv - Waits for a variable under cond var control to hit a value
465 * wait_iter_start - Wait for an iteration to start
468 * non-zero, and then we decrement it and go on.
476 iter_start--; in wait_iter_start()
481 * start_iter - Start an iteration at the replay thread level
499 * get_ncpus - Sets up the global 'ncpus' value
524 ncpus = -1; in get_ncpus()
538 * pin_to_cpu - Pin this thread to a specific CPU
549 assert(0 <= tip->cpu && tip->cpu < ncpus); in pin_to_cpu()
552 CPU_SET_S(tip->cpu, size, cpus); in pin_to_cpu()
557 assert(tip->cpu == sched_getcpu()); in pin_to_cpu()
564 fprintf(tip->vfp, "Pinned to CPU %02d ", tip->cpu); in pin_to_cpu()
566 fprintf(tip->vfp, "%1d", CPU_ISSET_S(i, size, now)); in pin_to_cpu()
567 fprintf(tip->vfp, "\n"); in pin_to_cpu()
578 * add_input_dev - Add a device ('sd*') to the list of devices to handle
587 if (strcmp(dip->devnm, devnm) == 0) in add_input_dev()
592 dip->devnm = strdup(devnm); in add_input_dev()
593 list_add_tail(&dip->head, &input_devs); in add_input_dev()
597 * rem_input_dev - Remove resources associated with this device
601 list_del(&dip->head); in rem_input_dev()
602 free(dip->devnm); in rem_input_dev()
619 if (strstr(ent->d_name, ".replay.") == NULL) in find_input_devs()
622 dsf = strdup(ent->d_name); in find_input_devs()
640 * read_map_devs - Read in a set of device mapping from the provided file.
659 mdp->from_dev = from_dev; in read_map_devs()
660 mdp->to_dev = to_dev; in read_map_devs()
661 list_add_tail(&mdp->head, &map_devs); in read_map_devs()
668 * release_map_devs - Release resources associated with device mappings.
677 list_del(&mdp->head); in release_map_devs()
679 free(mdp->from_dev); in release_map_devs()
680 free(mdp->to_dev); in release_map_devs()
686 * map_dev - Return the mapped device for that specified
698 if (strcmp(from_dev, mdp->from_dev) == 0) in map_dev()
699 return mdp->to_dev; in map_dev()
712 * iocb_init - Initialize the fields of an IOCB
713 * @tip: Per-thread information
718 iocbp->tip = tip; in iocb_init()
719 iocbp->nbytes = 0; in iocb_init()
720 iocbp->iocb.u.c.buf = NULL; in iocb_init()
724 * iocb_setup - Set up an iocb with this AIOs information
733 struct iocb *iop = &iocbp->iocb; in iocb_setup()
739 if (iocbp->nbytes) { in iocb_setup()
740 if (iocbp->nbytes >= n) { in iocb_setup()
741 buf = iop->u.c.buf; in iocb_setup()
745 assert(iop->u.c.buf); in iocb_setup()
746 free(iop->u.c.buf); in iocb_setup()
750 iocbp->nbytes = n; in iocb_setup()
754 io_prep_pread(iop, iocbp->tip->ofd, buf, n, off); in iocb_setup()
757 io_prep_pwrite(iop, iocbp->tip->ofd, buf, n, off); in iocb_setup()
761 iop->data = iocbp; in iocb_setup()
766 * ==== PER-THREAD SET UP & TEAR DOWN =====================================
771 * tip_init - Per thread initialization function
777 INIT_LIST_HEAD(&tip->free_iocbs); in tip_init()
778 INIT_LIST_HEAD(&tip->used_iocbs); in tip_init()
780 pthread_mutex_init(&tip->mutex, NULL); in tip_init()
781 pthread_cond_init(&tip->cond, NULL); in tip_init()
783 if (io_setup(naios, &tip->ctx)) { in tip_init()
788 tip->ofd = -1; in tip_init()
789 tip->naios_out = 0; in tip_init()
790 tip->send_done = tip->reap_done = 0; in tip_init()
791 tip->send_wait = tip->reap_wait = 0; in tip_init()
793 memset(&tip->sub_thread, 0, sizeof(tip->sub_thread)); in tip_init()
794 memset(&tip->rec_thread, 0, sizeof(tip->rec_thread)); in tip_init()
800 list_add_tail(&iocbp->head, &tip->free_iocbs); in tip_init()
802 tip->naios_free = naios; in tip_init()
807 sprintf(fn, "%s/%s.%s.%d.rep", idir, tip->devnm, ibase, in tip_init()
808 tip->cpu); in tip_init()
809 tip->vfp = fopen(fn, "w"); in tip_init()
810 if (!tip->vfp) { in tip_init()
815 setlinebuf(tip->vfp); in tip_init()
818 if (pthread_create(&tip->sub_thread, NULL, replay_sub, tip)) { in tip_init()
824 if (pthread_create(&tip->rec_thread, NULL, replay_rec, tip)) { in tip_init()
832 * tip_release - Release resources associated with this thread
838 assert(tip->send_done); in tip_release()
839 assert(tip->reap_done); in tip_release()
840 assert(list_len(&tip->used_iocbs) == 0); in tip_release()
841 assert(tip->naios_free == naios); in tip_release()
843 if (pthread_join(tip->sub_thread, NULL)) { in tip_release()
847 if (pthread_join(tip->rec_thread, NULL)) { in tip_release()
852 io_destroy(tip->ctx); in tip_release()
854 list_splice(&tip->used_iocbs, &tip->free_iocbs); in tip_release()
855 list_for_each_safe(p, q, &tip->free_iocbs) { in tip_release()
858 list_del(&iocbp->head); in tip_release()
859 if (iocbp->nbytes) in tip_release()
860 free(iocbp->iocb.u.c.buf); in tip_release()
864 pthread_cond_destroy(&tip->cond); in tip_release()
865 pthread_mutex_destroy(&tip->mutex); in tip_release()
869 * add_input_file - Allocate and initialize per-input file structure
877 struct io_file_hdr hdr; in add_input_file() local
883 memset(&hdr, 0, sizeof(hdr)); in add_input_file()
885 tip->cpu = cpu % cpus_to_use; in add_input_file()
886 tip->iterations = def_iterations; in add_input_file()
888 tip->ifd = open(file_name, O_RDONLY); in add_input_file()
889 if (tip->ifd < 0) { in add_input_file()
893 if (fstat(tip->ifd, &buf) < 0) { in add_input_file()
897 if (buf.st_size < (off_t)sizeof(hdr)) { in add_input_file()
903 if (read(tip->ifd, &hdr, sizeof(hdr)) != sizeof(hdr)) { in add_input_file()
908 if (hdr.version != my_version) { in add_input_file()
910 (long long unsigned)hdr.version, in add_input_file()
911 (long long unsigned)hdr.genesis, in add_input_file()
912 (long long unsigned)hdr.nbunches, in add_input_file()
913 (long long unsigned)hdr.total_pkts); in add_input_file()
916 (long)hdr.version, (long)my_version); in add_input_file()
920 if (hdr.nbunches == 0) { in add_input_file()
922 close(tip->ifd); in add_input_file()
927 if (hdr.genesis < genesis) { in add_input_file()
930 du64_to_sec(hdr.genesis), in add_input_file()
931 du64_to_nsec(hdr.genesis)); in add_input_file()
932 genesis = hdr.genesis; in add_input_file()
935 tip->devnm = strdup(devnm); in add_input_file()
936 tip->file_name = strdup(file_name); in add_input_file()
938 list_add_tail(&tip->head, &input_files); in add_input_file()
942 (long long)hdr.genesis); in add_input_file()
946 * rem_input_file - Release resources associated with an input file
947 * @tip: Per-input file information
951 list_del(&tip->head); in rem_input_file()
955 close(tip->ofd); in rem_input_file()
956 close(tip->ifd); in rem_input_file()
957 free(tip->file_name); in rem_input_file()
958 free(tip->devnm); in rem_input_file()
963 * rem_input_files - Remove all input files
975 * __find_input_files - Find input files associated with this device (per cpu)
984 sprintf(full_name, "%s/%s.%s.%d", idir, dip->devnm, ibase, cpu); in __find_input_files()
988 add_input_file(cpu, dip->devnm, full_name); in __find_input_files()
993 fatal(NULL, ERR_ARGS, "No traces found for %s\n", dip->devnm); in __find_input_files()
1002 * find_input_files - Find input files for all devices
1020 * reap_wait_aios - Wait for and return number of outstanding AIOs
1029 pthread_mutex_lock(&tip->mutex); in reap_wait_aios()
1030 while (tip->naios_out == 0) { in reap_wait_aios()
1031 tip->reap_wait = 1; in reap_wait_aios()
1032 if (pthread_cond_wait(&tip->cond, &tip->mutex)) { in reap_wait_aios()
1038 naios = tip->naios_out; in reap_wait_aios()
1039 pthread_mutex_unlock(&tip->mutex); in reap_wait_aios()
1047 * reclaim_ios - Reclaim AIOs completed, recycle IOCBs
1048 * @tip: Per-thread information
1059 ndone = io_getevents(tip->ctx, 1, naios_out, events, NULL); in reclaim_ios()
1071 pthread_mutex_lock(&tip->mutex); in reclaim_ios()
1073 struct iocb_pkt *iocbp = evp->data; in reclaim_ios()
1075 if (evp->res != iocbp->iocb.u.c.nbytes) { in reclaim_ios()
1078 (long)evp->res, (long)evp->res2, in reclaim_ios()
1079 (long)iocbp->iocb.u.c.offset / nb_sec, in reclaim_ios()
1080 (long)iocbp->iocb.u.c.nbytes / nb_sec); in reclaim_ios()
1084 list_move_tail(&iocbp->head, &tip->free_iocbs); in reclaim_ios()
1087 tip->naios_free += ndone; in reclaim_ios()
1088 tip->naios_out -= ndone; in reclaim_ios()
1089 naios_out = minl(naios_out, tip->naios_out); in reclaim_ios()
1091 if (tip->send_wait) { in reclaim_ios()
1092 tip->send_wait = 0; in reclaim_ios()
1093 pthread_cond_signal(&tip->cond); in reclaim_ios()
1095 pthread_mutex_unlock(&tip->mutex); in reclaim_ios()
1105 * replay_rec - Worker thread to reclaim AIOs
1116 assert(tip->send_done); in replay_rec()
1117 tip->reap_done = 1; in replay_rec()
1130 * next_bunch - Retrieve next bunch of AIOs to process
1131 * @tip: Per-thread information
1140 result = read(tip->ifd, &bunch->hdr, sizeof(bunch->hdr)); in next_bunch()
1141 if (result != sizeof(bunch->hdr)) { in next_bunch()
1145 fatal(tip->file_name, ERR_SYSCALL, "Short hdr(%ld)\n", in next_bunch()
1149 assert(bunch->hdr.npkts <= BT_MAX_PKTS); in next_bunch()
1151 count = bunch->hdr.npkts * sizeof(struct io_pkt); in next_bunch()
1152 result = read(tip->ifd, &bunch->pkts, count); in next_bunch()
1154 fatal(tip->file_name, ERR_SYSCALL, "Short pkts(%ld/%ld)\n", in next_bunch()
1163 * nfree_current - Returns current number of AIOs that are free
1173 pthread_mutex_lock(&tip->mutex); in nfree_current()
1174 while (!is_send_done(tip) && ((nfree = tip->naios_free) == 0)) { in nfree_current()
1175 tip->send_wait = 1; in nfree_current()
1176 if (pthread_cond_wait(&tip->cond, &tip->mutex)) { in nfree_current()
1182 pthread_mutex_unlock(&tip->mutex); in nfree_current()
1188 * stall - Stall for the number of nanoseconds requested
1195 long long dreal, tclock = gettime() - rgenesis; in stall()
1200 fprintf(tip->vfp, " stall(%lld.%09lld, %lld.%09lld)\n", in stall()
1205 dreal = oclock - tclock; in stall()
1210 fprintf(tip->vfp, "++ stall(%lld.%09lld) ++\n", in stall()
1218 tclock = gettime() - rgenesis; in stall()
1223 * iocbs_map - Map a set of AIOs onto a set of IOCBs
1224 * @tip: Per-thread information
1237 pthread_mutex_lock(&tip->mutex); in iocbs_map()
1238 assert(ntodo <= list_len(&tip->free_iocbs)); in iocbs_map()
1240 __u32 rw = pkt->rw; in iocbs_map()
1243 if (!pkt->rw && !write_enabled) in iocbs_map()
1247 fprintf(tip->vfp, "\t%10llu + %10llu %c%c\n", in iocbs_map()
1248 (unsigned long long)pkt->sector, in iocbs_map()
1249 (unsigned long long)pkt->nbytes / nb_sec, in iocbs_map()
1251 (rw == 1 && pkt->rw == 0) ? '!' : ' '); in iocbs_map()
1253 iocbp = list_entry(tip->free_iocbs.next, struct iocb_pkt, head); in iocbs_map()
1254 iocb_setup(iocbp, rw, pkt->nbytes, pkt->sector * nb_sec); in iocbs_map()
1256 list_move_tail(&iocbp->head, &tip->used_iocbs); in iocbs_map()
1257 list[i] = &iocbp->iocb; in iocbs_map()
1260 tip->naios_free -= ntodo; in iocbs_map()
1261 assert(tip->naios_free >= 0); in iocbs_map()
1262 pthread_mutex_unlock(&tip->mutex); in iocbs_map()
1266 * process_bunch - Process a bunch of requests
1267 * @tip: Per-thread information
1273 struct iocb *list[bunch->hdr.npkts]; in process_bunch()
1275 assert(0 < bunch->hdr.npkts && bunch->hdr.npkts <= BT_MAX_PKTS); in process_bunch()
1276 while (!is_send_done(tip) && (i < bunch->hdr.npkts)) { in process_bunch()
1278 int ntodo = min(nfree_current(tip), bunch->hdr.npkts - i); in process_bunch()
1281 iocbs_map(tip, list, &bunch->pkts[i], ntodo); in process_bunch()
1283 stall(tip, bunch->hdr.time_stamp - genesis); in process_bunch()
1287 fprintf(tip->vfp, "submit(%d)\n", ntodo); in process_bunch()
1288 ndone = io_submit(tip->ctx, ntodo, list); in process_bunch()
1292 tip->cpu, ntodo, ndone, in process_bunch()
1297 pthread_mutex_lock(&tip->mutex); in process_bunch()
1298 tip->naios_out += ndone; in process_bunch()
1299 assert(tip->naios_out <= naios); in process_bunch()
1300 if (tip->reap_wait) { in process_bunch()
1301 tip->reap_wait = 0; in process_bunch()
1302 pthread_cond_signal(&tip->cond); in process_bunch()
1304 pthread_mutex_unlock(&tip->mutex); in process_bunch()
1307 assert(i <= bunch->hdr.npkts); in process_bunch()
1313 * reset_input_file - Reset the input file for the next iteration
1320 struct io_file_hdr hdr; in reset_input_file() local
1322 lseek(tip->ifd, 0, 0); in reset_input_file()
1324 if (read(tip->ifd, &hdr, sizeof(hdr)) != sizeof(hdr)) { in reset_input_file()
1325 fatal(tip->file_name, ERR_ARGS, "Header reread failed\n"); in reset_input_file()
1331 * replay_sub - Worker thread to submit AIOs that are being replayed
1344 mdev = map_dev(tip->devnm); in replay_sub()
1358 tip->ofd = open(path, O_RDWR | O_DIRECT | oflags); in replay_sub()
1359 if (tip->ofd < 0) { in replay_sub()
1365 while (!is_send_done(tip) && tip->iterations--) { in replay_sub()
1368 fprintf(tip->vfp, "\n=== %d ===\n", tip->iterations); in replay_sub()
1374 tip->send_done = 1; in replay_sub()
1388 "\t[ -c <cpus> : --cpus=<cpus> ] Default: 1\n" \
1389 "\t[ -d <dir> : --input-directory=<dir> ] Default: .\n" \
1390 "\t[ -F : --find-records ] Default: Off\n" \
1391 "\t[ -h : --help ] Default: Off\n" \
1392 "\t[ -i <base> : --input-base=<base> ] Default: replay\n" \
1393 "\t[ -I <iters>: --iterations=<iters> ] Default: 1\n" \
1394 "\t[ -M <file> : --map-devs=<file> ] Default: None\n" \
1395 "\t[ -N : --no-stalls ] Default: Off\n" \
1396 "\t[ -x : --acc-factor ] Default: 1\n" \
1397 "\t[ -v : --verbose ] Default: Off\n" \
1398 "\t[ -V : --version ] Default: Off\n" \
1399 "\t[ -W : --write-enable ] Default: Off\n" \
1412 .name = "input-directory",
1418 .name = "find-records",
1430 .name = "input-base",
1442 .name = "map-devs",
1448 .name = "no-stalls",
1454 .name = "acc-factor",
1472 .name = "write-enable",
1494 while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) != -1) { in handle_args()
1558 fprintf(stderr, "btreplay -- version %s\n", in handle_args()
1601 * set_signal_done - Signal handler, catches signals & sets signal_done
1609 * main -