From: Alan D. Brunelle Date: Fri, 13 Feb 2009 17:43:45 +0000 (-0500) Subject: btt general cleanup plus valgrind clean X-Git-Tag: blktrace-1.0.1~21 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=c053af429559c8f4311cd773262ff223097cdcb3;p=blktrace.git btt general cleanup plus valgrind clean Lots of general clean up of code, getting interfaces across different files to be similar (all are no alloc/free), and made it valgrind clean. Signed-off-by: Alan D. Brunelle fp, oname); + add_file(ap->fp, oname); return ap; } -void aqd_exit(void *info) +void aqd_free(void *info) { free(info); } -void aqd_clean(void) -{ - clean_files(&aqd_files); -} - void aqd_issue(void *info, double ts) { if (info) { diff --git a/btt/args.c b/btt/args.c index 0ddd47c..1830125 100644 --- a/btt/args.c +++ b/btt/args.c @@ -228,8 +228,6 @@ static char usage_str[] = \ "[ -z | --q2d-latencies= ]\n" \ "\n"; -static struct file_info *arg_files = NULL; - static void usage(char *prog) { fprintf(stderr, "Usage: %s %s %s", prog, bt_timeline_version, @@ -248,19 +246,32 @@ static FILE *setup_ofile(char *fname) } buf = malloc(SETBUFFER_SIZE); - setbuffer(ofp, buf, SETBUFFER_SIZE); - add_file(&arg_files, ofp, fname); + + add_file(ofp, fname); add_buf(buf); + return ofp; } return NULL; } -void clean_args(void) +static FILE *std_open(char *output_name, char *sfx, char *msg) { - clean_files(&arg_files); + FILE *fp; + char fname[strlen(output_name) + 32]; + + sprintf(fname, "%s.%s", output_name, sfx); + fp = my_fopen(fname, "w"); + if (fp == NULL) { + perror(fname); + exit(1); + } + if (verbose) + printf("Sending %s to %s\n", msg, fname); + + return fp; } void handle_args(int argc, char *argv[]) @@ -276,25 +287,25 @@ void handle_args(int argc, char *argv[]) output_all_data = 1; break; case 'B': - bno_dump_name = strdup(optarg); + bno_dump_name = optarg; break; case 'd': sscanf(optarg, "%lf", &range_delta); break; case 'D': - devices = strdup(optarg); + devices = optarg; break; case 'e': - exes = strdup(optarg); + exes = optarg; break; case 'h': usage(argv[0]); exit(0); case 'i': - input_name = strdup(optarg); + input_name = optarg; break; case 'l': - d2c_name = strdup(optarg); + d2c_name = optarg; break; case 'L': plat_freq = atof(optarg); @@ -303,32 +314,33 @@ void handle_args(int argc, char *argv[]) iostat_name = strdup(optarg); break; case 'm': - sps_name = strdup(optarg); + sps_name = optarg; break; case 'M': if (dev_map_read(optarg)) exit(1); break; case 'o': - output_name = strdup(optarg); + output_name = optarg; break; case 'p': per_io_name = strdup(optarg); break; case 'P': - per_io_trees = strdup(optarg); + per_io_trees = optarg; break; case 'q': - q2c_name = strdup(optarg); + q2c_name = optarg; break; case 'Q': - aqd_name = strdup(optarg); + aqd_name = optarg; break; case 's': - seek_name = strdup(optarg); + seek_name = optarg; break; case 'S': { unsigned int interval; + sscanf(optarg, "%u", &interval); iostat_interval = (__u64)interval * 1000000000LL; break; @@ -342,7 +354,7 @@ void handle_args(int argc, char *argv[]) time_bounded = 1; break; case 'u': - unplug_hist_name = strdup(optarg); + unplug_hist_name = optarg; break; case 'v': verbose = 1; @@ -354,7 +366,7 @@ void handle_args(int argc, char *argv[]) easy_parse_avgs++; break; case 'z': - q2d_name = strdup(optarg); + q2d_name = optarg; break; default: usage(argv[0]); @@ -375,51 +387,16 @@ void handle_args(int argc, char *argv[]) setup_ifile(input_name); if (output_name == NULL) { - ranges_ofp = avgs_ofp = msgs_ofp = stdout; + rngs_ofp = avgs_ofp = msgs_ofp = stdout; easy_parse_avgs = 0; - } - else { - char *fname = malloc(strlen(output_name) + 32); - - sprintf(fname, "%s.dat", output_name); - ranges_ofp = my_fopen(fname, "w"); - if (ranges_ofp == NULL) { - perror(fname); - exit(1); - } - if (verbose) - printf("Sending range data to %s\n", fname); - - sprintf(fname, "%s.avg", output_name); - avgs_ofp = my_fopen(fname, "w"); - if (avgs_ofp == NULL) { - perror(fname); - exit(1); - } - if (verbose) - printf("Sending stats data to %s\n", fname); - - sprintf(fname, "%s.msg", output_name); - msgs_ofp = my_fopen(fname, "w"); - if (msgs_ofp == NULL) { - perror(fname); - exit(1); - } - if (verbose) - printf("Sending K messages to %s\n", fname); - + } else { + rngs_ofp = std_open(output_name, ".dat", "range data"); + avgs_ofp = std_open(output_name, ".avg", "stats data"); + msgs_ofp = std_open(output_name, ".msg", "K messages"); if (easy_parse_avgs) { - sprintf(fname, "%s.xvg", output_name); - xavgs_ofp = my_fopen(fname, "w"); - if (avgs_ofp == NULL) { - perror(fname); - exit(1); - } - if (verbose) - printf("Sending X stats data to %s\n", fname); + xavgs_ofp = std_open(output_name, ".xvg", + "X stats data"); } - - free(fname); } iostat_ofp = setup_ofile(iostat_name); diff --git a/btt/bno_dump.c b/btt/bno_dump.c index 7f7680e..7365300 100644 --- a/btt/bno_dump.c +++ b/btt/bno_dump.c @@ -24,8 +24,6 @@ struct bno_dump { FILE *rfp, *wfp, *cfp; }; -static struct file_info *bno_dump_files = NULL; - static FILE *bno_dump_open(__u32 device, char rwc) { FILE *fp; @@ -40,11 +38,17 @@ static FILE *bno_dump_open(__u32 device, char rwc) if ((fp = my_fopen(oname, "w")) == NULL) perror(oname); else - add_file(&bno_dump_files, fp, oname); + add_file(fp, oname); return fp; } -void *bno_dump_init(__u32 device) +static inline void bno_dump_write(FILE *fp, struct io *iop) +{ + fprintf(fp, "%15.9lf %lld %lld\n", BIT_TIME(iop->t.time), + (long long)BIT_START(iop), (long long)BIT_END(iop)); +} + +void *bno_dump_alloc(__u32 device) { struct bno_dump *bdp; @@ -58,35 +62,21 @@ void *bno_dump_init(__u32 device) return bdp; } -void bno_dump_exit(void *param) +void bno_dump_free(void *param) { - /* - * Associated files will be auto-cleaned by bno_dump_clean - */ free(param); } -static inline void bno_dump_write(FILE *fp, struct io *iop) -{ - fprintf(fp, "%15.9lf %lld %lld\n", - BIT_TIME(iop->t.time), - (long long)BIT_START(iop), (long long)BIT_END(iop)); -} - void bno_dump_add(void *handle, struct io *iop) { -# define RW_FP(bdp, iop) (IOP_READ(iop) ? bdp->rfp : bdp->wfp) struct bno_dump *bdp = handle; if (bdp) { - if (RW_FP(bdp, iop)) - bno_dump_write(RW_FP(bdp, iop), iop); + FILE *fp = IOP_READ(iop) ? bdp->rfp : bdp->wfp; + + if (fp) + bno_dump_write(fp, iop); if (bdp->cfp) bno_dump_write(bdp->cfp, iop); } } - -void bno_dump_clean(void) -{ - clean_files(&bno_dump_files); -} diff --git a/btt/bt_timeline.c b/btt/bt_timeline.c index 9c6ab94..d1fefe3 100644 --- a/btt/bt_timeline.c +++ b/btt/bt_timeline.c @@ -30,7 +30,7 @@ char bt_timeline_version[] = "2.07"; char *devices, *exes, *input_name, *output_name, *seek_name, *bno_dump_name; char *d2c_name, *q2c_name, *per_io_name, *unplug_hist_name; char *sps_name, *aqd_name, *q2d_name, *per_io_trees; -FILE *ranges_ofp, *avgs_ofp, *xavgs_ofp, *per_io_ofp, *msgs_ofp; +FILE *rngs_ofp, *avgs_ofp, *xavgs_ofp, *per_io_ofp, *msgs_ofp; int verbose, done, time_bounded, output_all_data, seek_absolute; int easy_parse_avgs; double t_astart, t_aend; @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) init_dev_heads(); iostat_init(); - if (process() || output_avgs(avgs_ofp) || output_ranges(ranges_ofp)) + if (process() || output_avgs(avgs_ofp) || output_ranges(rngs_ofp)) return 1; if (iostat_ofp) { @@ -72,26 +72,20 @@ int main(int argc, char *argv[]) if (msgs_ofp != stdout) fclose(msgs_ofp); - if (ranges_ofp != stdout) - fclose(ranges_ofp); + if (rngs_ofp != stdout) + fclose(rngs_ofp); if (avgs_ofp != stdout) fclose(avgs_ofp); + if (xavgs_ofp) + fclose(xavgs_ofp); - latency_clean(); - bno_dump_clean(); + dip_cleanup(); dev_map_exit(); dip_exit(); - seek_clean(); pip_exit(); - aqd_clean(); io_free_all(); region_exit(&all_regions); - - free(input_name); - if (output_name) free(output_name); - - clean_args(); - clean_bufs(); + clean_allocs(); return 0; } @@ -117,8 +111,6 @@ int process(void) io_release(iop); gettimeofday(&tve, NULL); - dip_cleanup(); - if (verbose) { double tps, dt_input = tv2dbl(&tve) - tv2dbl(&tvs); diff --git a/btt/devmap.c b/btt/devmap.c index 5841446..9c0348b 100644 --- a/btt/devmap.c +++ b/btt/devmap.c @@ -21,44 +21,49 @@ #include #include "globals.h" -struct devmap *all_devmaps = NULL; +struct devmap { + struct list_head head; + char device[32], devno[32]; +}; -void dev_map_exit(void) +LIST_HEAD(all_devmaps); + +static int dev_map_add(char *line) { struct devmap *dmp; - while ((dmp = all_devmaps) != NULL) { - all_devmaps = dmp->next; + if (strstr(line, "Device") != NULL) + return 1; + + dmp = malloc(sizeof(struct devmap)); + if (sscanf(line, "%s %s", dmp->device, dmp->devno) != 2) { free(dmp); + return 1; } -} -void dev_map_add(struct devmap *dmp) -{ - struct devmap *this = malloc(sizeof(struct devmap)); - - *this = *dmp; - this->next = all_devmaps; - all_devmaps = this; + list_add_tail(&dmp->head, &all_devmaps); + return 0; } -struct devmap *dev_map_find(__u32 device) +char *dev_map_find(__u32 device) { char this[128]; - struct devmap *dmp; + struct list_head *p; sprintf(this, "%u,%u", MAJOR(device), MINOR(device)); - for (dmp = all_devmaps; dmp != NULL; dmp = dmp->next) + __list_for_each(p, &all_devmaps) { + struct devmap *dmp = list_entry(p, struct devmap, head); + if (!strcmp(this, dmp->devno)) - break; + return dmp->device; + } - return dmp; + return NULL; } int dev_map_read(char *fname) { char line[256]; - struct devmap dm; FILE *fp = my_fopen(fname, "r"); if (!fp) { @@ -67,14 +72,21 @@ int dev_map_read(char *fname) } while (fscanf(fp, "%255[a-zA-Z0-9 :.,/_-]\n", line) == 1) { - if (strstr(line, "Device") != NULL) continue; - if (sscanf(line, "%s %s %u %u %u %u %s %s %u %u %s", - &dm.device[0], &dm.model[0], &dm.host, &dm.bus, - &dm.target, &dm.lun, &dm.node[0], &dm.pci[0], - &dm.irq, &dm.cpu, &dm.devno[0]) != 11) + if (dev_map_add(line)) break; - dev_map_add(&dm); } return 0; } + +void dev_map_exit(void) +{ + struct list_head *p, *q; + + list_for_each_safe(p, q, &all_devmaps) { + struct devmap *dmp = list_entry(p, struct devmap, head); + + list_del(&dmp->head); + free(dmp); + } +} diff --git a/btt/devs.c b/btt/devs.c index 9480d61..fc50555 100644 --- a/btt/devs.c +++ b/btt/devs.c @@ -78,16 +78,16 @@ void __dip_exit(struct d_info *dip) list_del(&dip->all_head); __destroy_heads(dip->heads); region_exit(&dip->regions); - seeki_exit(dip->seek_handle); - seeki_exit(dip->q2q_handle); - aqd_exit(dip->aqd_handle); - plat_exit(dip->q2d_plat_handle); - plat_exit(dip->q2c_plat_handle); - plat_exit(dip->d2c_plat_handle); - bno_dump_exit(dip->bno_dump_handle); - unplug_hist_exit(dip->unplug_hist_handle); + seeki_free(dip->seek_handle); + seeki_free(dip->q2q_handle); + aqd_free(dip->aqd_handle); + plat_free(dip->q2d_plat_handle); + plat_free(dip->q2c_plat_handle); + plat_free(dip->d2c_plat_handle); + bno_dump_free(dip->bno_dump_handle); + unplug_hist_free(dip->up_hist_handle); if (output_all_data) - q2d_release(dip->q2d_priv); + q2d_free(dip->q2d_priv); if (dip->pit_fp) fclose(dip->pit_fp); free(dip); @@ -122,7 +122,7 @@ static inline FILE *open_pit(char *str) return fp; } -struct d_info *dip_add(__u32 device, struct io *iop) +struct d_info *dip_alloc(__u32 device, struct io *iop) { struct d_info *dip = __dip_find(device); @@ -135,25 +135,25 @@ struct d_info *dip_add(__u32 device, struct io *iop) region_init(&dip->regions); dip->device = device; dip->last_q = (__u64)-1; - dip->map = dev_map_find(device); - dip->bno_dump_handle = bno_dump_init(device); - dip->unplug_hist_handle = unplug_hist_init(device); - dip->seek_handle = seeki_init(mkhandle(str, device, "_d2d")); - dip->q2q_handle = seeki_init(mkhandle(str, device, "_q2q")); - dip->aqd_handle = aqd_init(mkhandle(str, device, "_aqd")); + dip->devmap = dev_map_find(device); + dip->bno_dump_handle = bno_dump_alloc(device); + dip->up_hist_handle = unplug_hist_alloc(device); + dip->seek_handle = seeki_alloc(mkhandle(str, device, "_d2d")); + dip->q2q_handle = seeki_alloc(mkhandle(str, device, "_q2q")); + dip->aqd_handle = aqd_alloc(mkhandle(str, device, "_aqd")); dip->q2d_plat_handle = - plat_init(mkhandle(str, device, "_q2d_plat")); + plat_alloc(mkhandle(str, device, "_q2d_plat")); dip->q2c_plat_handle = - plat_init(mkhandle(str, device, "_q2c_plat")); + plat_alloc(mkhandle(str, device, "_q2c_plat")); dip->d2c_plat_handle = - plat_init(mkhandle(str, device, "_d2c_plat")); - latency_init(dip); + plat_alloc(mkhandle(str, device, "_d2c_plat")); + latency_alloc(dip); list_add_tail(&dip->hash_head, &dev_heads[DEV_HASH(device)]); list_add_tail(&dip->all_head, &all_devs); dip->start_time = BIT_TIME(iop->t.time); dip->pre_culling = 1; if (output_all_data) - dip->q2d_priv = q2d_init(); + dip->q2d_priv = q2d_alloc(); n_devs++; if (per_io_trees) dip->pit_fp = open_pit(mkhandle(per_io_trees, @@ -173,7 +173,7 @@ struct d_info *dip_add(__u32 device, struct io *iop) return dip; } -void dip_rem(struct io *iop) +void iop_rem_dip(struct io *iop) { if (iop->linked) { dip_rb_rem(iop); @@ -195,8 +195,7 @@ void dip_foreach(struct io *iop, enum iop_type type, list_del(&this->f_head); io_release(this); } - } - else + } else dip_rb_fe(iop->dip, type, iop, fnc, NULL); } @@ -216,8 +215,7 @@ void dip_foreach_out(void (*func)(struct d_info *, void *), void *arg) struct list_head *p; __list_for_each(p, &all_devs) func(list_entry(p, struct d_info, all_head), arg); - } - else { + } else { int i; struct d_info *dip; unsigned int mjr, mnr; diff --git a/btt/globals.h b/btt/globals.h index 36c30c3..caca6ac 100644 --- a/btt/globals.h +++ b/btt/globals.h @@ -60,12 +60,6 @@ enum iop_type { }; #define N_IOP_TYPES (IOP_S + 1) -struct file_info { - struct file_info *next; - FILE *ofp; - char *oname; -}; - struct mode { int most_seeks, nmds; long long *modes; @@ -121,13 +115,6 @@ struct p_info { char *name; }; -struct devmap { - struct devmap *next; - unsigned int host, bus, target, lun, irq, cpu; - char model[64]; - char device[32], node[32], pci[32], devno[32]; -}; - struct stats { __u64 rqm[2], ios[2], sec[2], wait, svctm; double last_qu_change, last_dev_change, tot_qusz, idle_time; @@ -144,8 +131,8 @@ struct d_info { struct list_head all_head, hash_head; void *heads; struct region_info regions; - struct devmap *map; - void *q2q_handle, *seek_handle, *bno_dump_handle, *unplug_hist_handle; + char *devmap; + void *q2q_handle, *seek_handle, *bno_dump_handle, *up_hist_handle; void *q2d_priv, *aqd_handle; void *q2d_plat_handle, *q2c_plat_handle, *d2c_plat_handle; FILE *q2d_ofp, *d2c_ofp, *q2c_ofp, *pit_fp; @@ -184,7 +171,7 @@ extern char *seek_name, *iostat_name, *d2c_name, *q2c_name, *per_io_name; extern char *bno_dump_name, *unplug_hist_name, *sps_name, *aqd_name, *q2d_name; extern char *per_io_trees; extern double range_delta, plat_freq; -extern FILE *ranges_ofp, *avgs_ofp, *xavgs_ofp, *iostat_ofp, *per_io_ofp; +extern FILE *rngs_ofp, *avgs_ofp, *xavgs_ofp, *iostat_ofp, *per_io_ofp; extern FILE *msgs_ofp; extern int verbose, done, time_bounded, output_all_data, seek_absolute; extern int easy_parse_avgs; @@ -205,21 +192,21 @@ void handle_args(int argc, char *argv[]); void clean_args(); /* aqd.c */ -void *aqd_init(char *str); -void aqd_exit(void *info); +void *aqd_alloc(char *str); +void aqd_free(void *info); void aqd_clean(void); void aqd_issue(void *info, double ts); void aqd_complete(void *info, double ts); /* devmap.c */ int dev_map_read(char *fname); -struct devmap *dev_map_find(__u32 device); +char *dev_map_find(__u32 device); void dev_map_exit(void); /* devs.c */ void init_dev_heads(void); -struct d_info *dip_add(__u32 device, struct io *iop); -void dip_rem(struct io *iop); +struct d_info *dip_alloc(__u32 device, struct io *iop); +void iop_rem_dip(struct io *iop); struct d_info *__dip_find(__u32 device); void dip_foreach_list(struct io *iop, enum iop_type type, struct list_head *hd); void dip_foreach(struct io *iop, enum iop_type type, @@ -244,28 +231,25 @@ void iostat_init(void); void iostat_getrq(struct io *iop); void iostat_merge(struct io *iop); void iostat_issue(struct io *iop); -void iostat_unissue(struct io *iop); void iostat_complete(struct io *d_iop, struct io *c_iop); void iostat_check_time(__u64 stamp); void iostat_dump_stats(__u64 stamp, int all); /* latency.c */ -void latency_init(struct d_info *dip); +void latency_alloc(struct d_info *dip); void latency_clean(void); void latency_q2d(struct d_info *dip, __u64 tstamp, __u64 latency); void latency_d2c(struct d_info *dip, __u64 tstamp, __u64 latency); void latency_q2c(struct d_info *dip, __u64 tstamp, __u64 latency); /* misc.c */ -int in_devices(struct blk_io_trace *t); -void add_file(struct file_info **fipp, FILE *fp, char *oname); -void clean_files(struct file_info **fipp); +void add_file(FILE *fp, char *oname); void add_buf(void *buf); -void clean_bufs(void); char *make_dev_hdr(char *pad, size_t len, struct d_info *dip, int add_parens); FILE *my_fopen(const char *path, const char *mode); int my_open(const char *path, int flags); void dbg_ping(void); +void clean_allocs(void); /* mmap.c */ void setup_ifile(char *fname); @@ -278,28 +262,28 @@ int output_avgs(FILE *ofp); int output_ranges(FILE *ofp); /* proc.c */ -void add_process(__u32 pid, char *name); +void process_alloc(__u32 pid, char *name); struct p_info *find_process(__u32 pid, char *name); void pip_update_q(struct io *iop); void pip_foreach_out(void (*f)(struct p_info *, void *), void *arg); void pip_exit(void); /* bno_dump.c */ -void *bno_dump_init(__u32 device); -void bno_dump_exit(void *param); +void *bno_dump_alloc(__u32 device); +void bno_dump_free(void *param); void bno_dump_add(void *handle, struct io *iop); void bno_dump_clean(void); /* plat.c */ -void *plat_init(char *str); -void plat_exit(void *info); +void *plat_alloc(char *str); +void plat_free(void *info); void plat_clean(void); void plat_x2c(void *info, __u64 ts, __u64 latency); /* q2d.c */ void q2d_histo_add(void *priv, __u64 q2d); -void *q2d_init(void); -void q2d_release(void *priv); +void *q2d_alloc(void); +void q2d_free(void *priv); void q2d_display_header(FILE *fp); void q2d_display_dashes(FILE *fp); void q2d_display(FILE *fp, void *priv); @@ -307,8 +291,8 @@ int q2d_ok(void *priv); void q2d_acc(void *a1, void *a2); /* seek.c */ -void *seeki_init(char *str); -void seeki_exit(void *param); +void *seeki_alloc(char *str); +void seeki_free(void *param); void seek_clean(void); void seeki_add(void *handle, struct io *iop); double seeki_mean(void *handle); @@ -338,7 +322,6 @@ int ready_issue(struct io *d_iop, struct io *c_iop); void trace_issue(struct io *d_iop); /* trace_plug.c */ -__u64 get_nio_up(struct io *u_iop); void trace_plug(struct io *p_iop); void trace_unplug_io(struct io *u_iop); void trace_unplug_timer(struct io *u_iop); @@ -357,8 +340,8 @@ void trace_remap(struct io *a_iop); void trace_requeue(struct io *r_iop); /* unplug_hist.c */ -void *unplug_hist_init(__u32 device); -void unplug_hist_exit(void *arg); +void *unplug_hist_alloc(__u32 device); +void unplug_hist_free(void *arg); void unplug_hist_add(struct io *u_iop); #include "inlines.h" diff --git a/btt/inlines.h b/btt/inlines.h index 2af70fb..64b5a2c 100644 --- a/btt/inlines.h +++ b/btt/inlines.h @@ -97,8 +97,7 @@ static inline void avg_update_n(struct avg_info *ap, __u64 t, int n) if (ap->n == 0) { ap->min = ap->max = t; ap->total = (n * t); - } - else { + } else { if (t < ap->min) ap->min = t; else if (t > ap->max) @@ -161,7 +160,7 @@ static inline void io_free_all(void) static inline int io_setup(struct io *iop, enum iop_type type) { iop->type = type; - iop->dip = dip_add(iop->t.device, iop); + iop->dip = dip_alloc(iop->t.device, iop); if (iop->linked) { iop->pip = find_process(iop->t.pid, NULL); iop->bytes_left = iop->t.bytes; @@ -173,7 +172,7 @@ static inline int io_setup(struct io *iop, enum iop_type type) static inline void io_release(struct io *iop) { if (iop->linked) - dip_rem(iop); + iop_rem_dip(iop); if (iop->pdu) free(iop->pdu); diff --git a/btt/iostat.c b/btt/iostat.c index d701e2f..8bcd2e5 100644 --- a/btt/iostat.c +++ b/btt/iostat.c @@ -22,28 +22,28 @@ #include #include "globals.h" -#define INC_STAT(dip, fld) \ - do { \ +#define INC_STAT(dip, fld) \ + do { \ (dip)->stats. fld ++; \ (dip)->all_stats. fld ++; \ } while (0) -#define DEC_STAT(dip, fld) \ - do { \ +#define DEC_STAT(dip, fld) \ + do { \ (dip)->stats. fld --; \ (dip)->all_stats. fld --; \ } while (0) -#define ADD_STAT(dip, fld, val) \ - do { \ - __u64 __v = (val); \ +#define ADD_STAT(dip, fld, val) \ + do { \ + __u64 __v = (val); \ (dip)->stats. fld += __v; \ (dip)->all_stats. fld += __v; \ } while (0) -#define SUB_STAT(dip, fld, val) \ - do { \ - __u64 __v = (val); \ +#define SUB_STAT(dip, fld, val) \ + do { \ + __u64 __v = (val); \ (dip)->stats. fld -= __v; \ (dip)->all_stats. fld -= __v; \ } while (0) @@ -53,21 +53,14 @@ __u64 iostat_interval = 1000000000; char *iostat_name = NULL; FILE *iostat_ofp = NULL; -void dump_hdr(void) +static void dump_hdr(void) { fprintf(iostat_ofp, "Device: rrqm/s wrqm/s r/s w/s " "rsec/s wsec/s rkB/s wkB/s " "avgrq-sz avgqu-sz await svctm %%util Stamp\n"); } -void iostat_init(void) -{ - last_start = (__u64)-1; - if (iostat_ofp) - dump_hdr(); -} - -void update_tot_qusz(struct d_info *dip, double now) +static void update_tot_qusz(struct d_info *dip, double now) { dip->stats.tot_qusz += ((now - dip->stats.last_qu_change) * dip->stats.cur_qusz); @@ -77,7 +70,7 @@ void update_tot_qusz(struct d_info *dip, double now) dip->stats.last_qu_change = dip->all_stats.last_qu_change = now; } -void update_idle_time(struct d_info *dip, double now, int force) +static void update_idle_time(struct d_info *dip, double now, int force) { if (dip->stats.cur_dev == 0 || force) { dip->stats.idle_time += (now - dip->stats.last_dev_change); @@ -97,8 +90,7 @@ void __dump_stats(__u64 stamp, int all, struct d_info *dip, struct stats_t *asp) if (all) { dt = (double)stamp / 1.0e9; sp = &dip->all_stats; - } - else { + } else { dt = (double)(stamp-last_start) / 1.0e9; sp = &dip->stats; } @@ -111,8 +103,7 @@ void __dump_stats(__u64 stamp, int all, struct d_info *dip, struct stats_t *asp) if (nios > 0.0) { avgrq_sz = (double)(sp->sec[0] + sp->sec[1]) / nios; svctm = TO_MSEC(sp->svctm) / nios; - } - else + } else avgrq_sz = svctm = 0.0; await = ((nios + nrqm) > 0.0) ? TO_MSEC(sp->wait) / (nios+nrqm) : 0.0; @@ -167,7 +158,7 @@ void __dump_stats(__u64 stamp, int all, struct d_info *dip, struct stats_t *asp) } } -void __dump_stats_t(__u64 stamp, struct stats_t *asp, int all) +static void __dump_stats_t(__u64 stamp, struct stats_t *asp, int all) { if (asp->n < 2.0) return; // What's the point? @@ -191,6 +182,13 @@ void __dump_stats_t(__u64 stamp, struct stats_t *asp, int all) fprintf(iostat_ofp, "%8.2lf\n", TO_SEC(stamp)); } +void iostat_init(void) +{ + last_start = (__u64)-1; + if (iostat_ofp) + dump_hdr(); +} + void iostat_dump_stats(__u64 stamp, int all) { struct d_info *dip; @@ -207,8 +205,7 @@ void iostat_dump_stats(__u64 stamp, int all) dip = list_entry(p, struct d_info, all_head); __dump_stats(stamp, all, dip, &as); } - } - else { + } else { int i; unsigned int mjr, mnr; char *p = devices; @@ -266,16 +263,6 @@ void iostat_issue(struct io *iop) INC_STAT(dip, cur_dev); } -void iostat_unissue(struct io *iop) -{ - int rw = IOP_RW(iop); - struct d_info *dip = iop->dip; - - DEC_STAT(dip, ios[rw]); - SUB_STAT(dip, sec[rw], iop->t.bytes >> 9); - DEC_STAT(dip, cur_dev); -} - void iostat_complete(struct io *q_iop, struct io *c_iop) { double now = TO_SEC(c_iop->t.time); diff --git a/btt/latency.c b/btt/latency.c index d12f60c..e3ecc26 100644 --- a/btt/latency.c +++ b/btt/latency.c @@ -20,8 +20,6 @@ */ #include "globals.h" -static struct file_info *all_files = NULL; - static inline void latency_out(FILE *ofp, __u64 tstamp, __u64 latency) { if (ofp) @@ -30,37 +28,32 @@ static inline void latency_out(FILE *ofp, __u64 tstamp, __u64 latency) FILE *latency_open(__u32 device, char *name, char *post) { - FILE *fp; - char *oname; - int mjr, mnr; + FILE *fp = NULL; - if (name == NULL) return NULL; + if (name) { + int mjr, mnr; + char oname[strlen(name) + 32]; - mjr = device >> MINORBITS; - mnr = device & ((1 << MINORBITS) - 1); + mjr = device >> MINORBITS; + mnr = device & ((1 << MINORBITS) - 1); - oname = malloc(strlen(name)+32); - sprintf(oname, "%s_%03d,%03d_%s.dat", name, mjr, mnr, post); - if ((fp = my_fopen(oname, "w")) == NULL) - perror(oname); - else - add_file(&all_files, fp, oname); + sprintf(oname, "%s_%03d,%03d_%s.dat", name, mjr, mnr, post); + if ((fp = my_fopen(oname, "w")) == NULL) + perror(oname); + else + add_file(fp, strdup(oname)); + } return fp; } -void latency_init(struct d_info *dip) +void latency_alloc(struct d_info *dip) { dip->q2d_ofp = latency_open(dip->device, q2d_name, "q2d"); dip->d2c_ofp = latency_open(dip->device, d2c_name, "d2c"); dip->q2c_ofp = latency_open(dip->device, q2c_name, "q2c"); } -void latency_clean(void) -{ - clean_files(&all_files); -} - void latency_q2d(struct d_info *dip, __u64 tstamp, __u64 latency) { plat_x2c(dip->q2d_plat_handle, tstamp, latency); diff --git a/btt/misc.c b/btt/misc.c index 4ec2c18..022955d 100644 --- a/btt/misc.c +++ b/btt/misc.c @@ -31,95 +31,51 @@ #define INLINE_DECLARE #include "globals.h" -int in_devices(struct blk_io_trace *t) -{ - int i; - unsigned int mjr, mnr; - char *p = devices; - - if (p == NULL) return 1; /* Allow anything */ +struct file_info { + struct list_head head; + FILE *ofp; + char *oname; +}; - for (;;) { - i = sscanf(p, "%u,%u;", &mjr, &mnr); - if ((mjr == MAJOR(t->device) && (mnr == MINOR(t->device)))) - return 1; +struct buf_info { + struct list_head head; + void *buf; +}; - p = strchr(p, ';'); - if (!p) - break; - p++; - } +LIST_HEAD(files_to_clean); +LIST_HEAD(all_bufs); - return 0; -} - -void add_file(struct file_info **fipp, FILE *fp, char *oname) +static void clean_files(void) { - struct file_info *fip = malloc(sizeof(*fip)); + struct list_head *p, *q; - fip->ofp = fp; - fip->oname = oname; - fip->next = *fipp; - *fipp = fip; -} - -void clean_files(struct file_info **fipp) -{ - struct stat buf; - struct file_info *fip; - - while ((fip = *fipp) != NULL) { - *fipp = fip->next; + list_for_each_safe(p, q, &files_to_clean) { + struct stat buf; + struct file_info *fip = list_entry(p, struct file_info, head); fclose(fip->ofp); if (!stat(fip->oname, &buf) && (buf.st_size == 0)) unlink(fip->oname); + list_del(&fip->head); free(fip->oname); free(fip); } } -struct buf_info { - struct buf_info *next; - void *buf; -} *all_bufs; -void add_buf(void *buf) +static void clean_bufs(void) { - struct buf_info *bip = malloc(sizeof(*bip)); - - bip->buf = buf; - bip->next = all_bufs; - all_bufs = bip; -} + struct list_head *p, *q; -void clean_bufs(void) -{ - struct buf_info *bip; + list_for_each_safe(p, q, &all_bufs) { + struct buf_info *bip = list_entry(p, struct buf_info, head); - while ((bip = all_bufs) != NULL) { - all_bufs = bip->next; + list_del(&bip->head); free(bip->buf); free(bip); } } -char *make_dev_hdr(char *pad, size_t len, struct d_info *dip, int add_parens) -{ - if (dip->map == NULL) { - if (add_parens) - snprintf(pad, len, "(%3d,%3d)", - MAJOR(dip->device), MINOR(dip->device)); - else - snprintf(pad, len, "%d,%d", - MAJOR(dip->device), MINOR(dip->device)); - } - else - snprintf(pad, len, "%s", dip->map->device); - - return pad; -} - /* * Due to the N(devs) parts of a lot of the output features provided * by btt, it will fail opens on large(ish) systems. Here we try to @@ -149,9 +105,47 @@ static int handle_open_failure(void) { if (errno == ENFILE || errno == EMFILE) return increase_limit(RLIMIT_NOFILE, 16); + return 0; } +void add_file(FILE *fp, char *oname) +{ + struct file_info *fip = malloc(sizeof(*fip)); + + fip->ofp = fp; + fip->oname = oname; + list_add_tail(&fip->head, &files_to_clean); +} + +void add_buf(void *buf) +{ + struct buf_info *bip = malloc(sizeof(*bip)); + + bip->buf = buf; + list_add_tail(&bip->head, &all_bufs); +} + +void clean_allocs(void) +{ + clean_files(); + clean_bufs(); +} + +char *make_dev_hdr(char *pad, size_t len, struct d_info *dip, int add_parens) +{ + if (dip->devmap) + snprintf(pad, len, "%s", dip->devmap); + else if (add_parens) + snprintf(pad, len, "(%3d,%3d)", + MAJOR(dip->device), MINOR(dip->device)); + else + snprintf(pad, len, "%d,%d", + MAJOR(dip->device), MINOR(dip->device)); + + return pad; +} + FILE *my_fopen(const char *path, const char *mode) { FILE *fp; diff --git a/btt/mmap.c b/btt/mmap.c index 83cc708..9d4eb3d 100644 --- a/btt/mmap.c +++ b/btt/mmap.c @@ -41,7 +41,10 @@ static long pgsz; int data_is_native = -1; -static inline size_t min_len(size_t a, size_t b) { return a < b ? a : b; } +static inline size_t min_len(size_t a, size_t b) +{ + return a < b ? a : b; +} static inline size_t convert_to_cpu(struct blk_io_trace *t, struct blk_io_trace *tp, @@ -69,8 +72,7 @@ static inline size_t convert_to_cpu(struct blk_io_trace *t, if (tp->pdu_len) { *pdu = malloc(tp->pdu_len); memcpy(*pdu, t+1, tp->pdu_len); - } - else + } else *pdu = NULL; return sizeof(*tp) + tp->pdu_len; @@ -130,8 +132,10 @@ int next_trace(struct blk_io_trace *t, void **pdu) size_t this_len; if ((cur + 512) > cur_max) - if (!move_map()) + if (!move_map()) { + cleanup_ifile(); return 0; + } next_t = cur_map + (cur - cur_min); this_len = convert_to_cpu(next_t, t, pdu); diff --git a/btt/output.c b/btt/output.c index ace1bcd..4e9b360 100644 --- a/btt/output.c +++ b/btt/output.c @@ -139,7 +139,7 @@ void output_q2d_histo(FILE *ofp) { struct __q2d __q2d = { .ofp = ofp, - .q2d_all = q2d_init(), + .q2d_all = q2d_alloc(), .n = 0 }; @@ -156,6 +156,8 @@ void output_q2d_histo(FILE *ofp) q2d_display(ofp, __q2d.q2d_all); fprintf(ofp, "\n"); } + + q2d_free(__q2d.q2d_all); } int n_merges = 0; diff --git a/btt/plat.c b/btt/plat.c index 80716b9..7a9bb2a 100644 --- a/btt/plat.c +++ b/btt/plat.c @@ -27,9 +27,7 @@ struct plat_info { double first_ts, last_ts, tl; }; -static struct file_info *plat_files = NULL; - -void *plat_init(char *str) +void *plat_alloc(char *str) { char *oname; struct plat_info *pp; @@ -46,12 +44,12 @@ void *plat_init(char *str) perror(oname); return NULL; } - add_file(&plat_files, pp->fp, oname); + add_file(pp->fp, oname); return pp; } -void plat_exit(void *info) +void plat_free(void *info) { struct plat_info *pp = info; @@ -66,11 +64,6 @@ void plat_exit(void *info) free(info); } -void plat_clean(void) -{ - clean_files(&plat_files); -} - void plat_x2c(void *info, __u64 ts, __u64 latency) { double now = TO_SEC(ts); @@ -83,8 +76,7 @@ void plat_x2c(void *info, __u64 ts, __u64 latency) pp->first_ts = pp->last_ts = now; pp->nl = 1; pp->tl = lat; - } - else if ((now - pp->first_ts) >= plat_freq) { + } else if ((now - pp->first_ts) >= plat_freq) { double delta = pp->last_ts - pp->first_ts; fprintf(pp->fp, "%lf %lf\n", @@ -93,8 +85,7 @@ void plat_x2c(void *info, __u64 ts, __u64 latency) pp->first_ts = pp->last_ts = now; pp->nl = 1; pp->tl = lat; - } - else { + } else { pp->last_ts = now; pp->nl += 1; pp->tl += lat; diff --git a/btt/proc.c b/btt/proc.c index 55f8e13..aac49cb 100644 --- a/btt/proc.c +++ b/btt/proc.c @@ -33,6 +33,16 @@ struct pn_info { struct rb_root root_pid, root_name; +static void __foreach(struct rb_node *n, void (*f)(struct p_info *, void *), + void *arg) +{ + if (n) { + __foreach(n->rb_left, f, arg); + f(rb_entry(n, struct pn_info, rb_node)->pip, arg); + __foreach(n->rb_right, f, arg); + } +} + static void __destroy(struct rb_node *n, int free_name, int free_pip) { if (n) { @@ -41,7 +51,8 @@ static void __destroy(struct rb_node *n, int free_name, int free_pip) __destroy(n->rb_left, free_name, free_pip); __destroy(n->rb_right, free_name, free_pip); - if (free_name) free(pnp->u.name); + if (free_name) + free(pnp->u.name); if (free_pip) { free(pnp->pip->name); region_exit(&pnp->pip->regions); @@ -186,14 +197,14 @@ struct p_info *find_process(__u32 pid, char *name) name = alloca(256); sprintf(name, "pid%09u", pid); - add_process(pid, name); + process_alloc(pid, name); return __find_process_pid(pid); } return __find_process_name(name); } -void add_process(__u32 pid, char *name) +void process_alloc(__u32 pid, char *name) { struct p_info *pip = find_process(pid, name); @@ -204,7 +215,7 @@ void add_process(__u32 pid, char *name) pip->last_q = (__u64)-1; pip->name = strdup(name); - insert(pip); + insert(pip); } } @@ -221,15 +232,6 @@ void pip_update_q(struct io *iop) } } -void __foreach(struct rb_node *n, void (*f)(struct p_info *, void *), void *arg) -{ - if (n) { - __foreach(n->rb_left, f, arg); - f(rb_entry(n, struct pn_info, rb_node)->pip, arg); - __foreach(n->rb_right, f, arg); - } -} - void pip_foreach_out(void (*f)(struct p_info *, void *), void *arg) { if (exes == NULL) @@ -244,8 +246,7 @@ void pip_foreach_out(void (*f)(struct p_info *, void *), void *arg) if ((next = strchr(exes_save, ',')) != NULL) { *next = '\0'; exes_save = next+1; - } - else + } else exes_save = NULL; pip = __find_process_name(exe); diff --git a/btt/q2d.c b/btt/q2d.c index ae61e20..faeb712 100644 --- a/btt/q2d.c +++ b/btt/q2d.c @@ -54,14 +54,14 @@ void q2d_histo_add(void *priv, __u64 q2d_in) q2dp->nhistos++; } -void *q2d_init(void) +void *q2d_alloc(void) { struct q2d_info *q2dp = malloc(sizeof(*q2dp)); return memset(q2dp, 0, sizeof(*q2dp)); } -void q2d_release(void *priv) +void q2d_free(void *priv) { free(priv); } diff --git a/btt/seek.c b/btt/seek.c index 444013c..4a03fbe 100644 --- a/btt/seek.c +++ b/btt/seek.c @@ -21,8 +21,6 @@ #include #include "globals.h" -static struct file_info *seek_files = NULL; - struct seek_bkt { struct rb_node rb_node; long long sectors; @@ -56,7 +54,7 @@ static FILE *seek_open(char *str, char rw) if ((fp = my_fopen(oname, "w")) == NULL) perror(oname); else - add_file(&seek_files, fp, oname); + add_file(fp, oname); return fp; } @@ -108,8 +106,7 @@ static void sps_emit(struct seeki *sip) if ((sps->nseeks == 1) || (delta < DBL_EPSILON)) { s_p_s = (double)(sps->nseeks); tstamp = sps->t_start; - } - else { + } else { s_p_s = (double)(sps->nseeks) / delta; tstamp = sps->t_start + (delta / 2); @@ -133,15 +130,55 @@ static void sps_add(struct seeki *sip, double t) if (sps->nseeks == 0) { sps->t_start = t; sps->nseeks = 1; - } - else + } else sps->nseeks++; } } -void seek_clean(void) +static int __median(struct rb_node *n, long long sofar, long long target, + long long *rvp) { - clean_files(&seek_files); + struct seek_bkt *sbp; + + sbp = rb_entry(n, struct seek_bkt, rb_node); + if ((sofar + sbp->nseeks) >= target) { + *rvp = sbp->sectors; + return 1; + } + + if (n->rb_left && __median(n->rb_left, sofar, target, rvp)) + return 1; + + if (n->rb_right && __median(n->rb_right, sofar, target, rvp)) + return 1; + + return 0; + +} + +static void __mode(struct rb_node *n, struct mode *mp) +{ + struct seek_bkt *sbp; + + if (n->rb_left) + __mode(n->rb_left, mp); + if (n->rb_right) + __mode(n->rb_right, mp); + + sbp = rb_entry(n, struct seek_bkt, rb_node); + if (mp->modes == NULL) { + mp->modes = malloc(sizeof(long long)); + mp->nmds = 0; + } else if (sbp->nseeks > mp->most_seeks) + mp->nmds = 0; + else if (sbp->nseeks == mp->most_seeks) + mp->modes = realloc(mp->modes, (mp->nmds + 1) * + sizeof(long long)); + else + return; + + mp->most_seeks = sbp->nseeks; + mp->modes[mp->nmds++] = sbp->sectors; } long long seek_dist(struct seeki *sip, struct io *iop) @@ -168,7 +205,7 @@ long long seek_dist(struct seeki *sip, struct io *iop) return dist; } -void *seeki_init(char *str) +void *seeki_alloc(char *str) { struct seeki *sip = malloc(sizeof(struct seeki)); @@ -190,15 +227,14 @@ void *seeki_init(char *str) if ((sip->sps_fp = my_fopen(oname, "w")) == NULL) perror(oname); else - add_file(&seek_files, sip->sps_fp, oname); - } - else + add_file(sip->sps_fp, oname); + } else sip->sps_fp = NULL; return sip; } -void seeki_exit(void *param) +void seeki_free(void *param) { struct seeki *sip = param; @@ -244,27 +280,6 @@ double seeki_mean(void *handle) return sip->total_sectors / sip->tot_seeks; } -int __median(struct rb_node *n, long long sofar, long long target, long - long *rvp) -{ - struct seek_bkt *sbp; - - sbp = rb_entry(n, struct seek_bkt, rb_node); - if ((sofar + sbp->nseeks) >= target) { - *rvp = sbp->sectors; - return 1; - } - - if (n->rb_left && __median(n->rb_left, sofar, target, rvp)) - return 1; - - if (n->rb_right && __median(n->rb_right, sofar, target, rvp)) - return 1; - - return 0; - -} - long long seeki_median(void *handle) { long long rval = 0LL; @@ -277,30 +292,6 @@ long long seeki_median(void *handle) return rval; } -void __mode(struct rb_node *n, struct mode *mp) -{ - struct seek_bkt *sbp; - - if (n->rb_left) __mode(n->rb_left, mp); - if (n->rb_right) __mode(n->rb_right, mp); - - sbp = rb_entry(n, struct seek_bkt, rb_node); - if (mp->modes == NULL) { - mp->modes = malloc(sizeof(long long)); - mp->nmds = 0; - } - else if (sbp->nseeks > mp->most_seeks) - mp->nmds = 0; - else if (sbp->nseeks == mp->most_seeks) - mp->modes = realloc(mp->modes, (mp->nmds + 1) * - sizeof(long long)); - else - return; - - mp->most_seeks = sbp->nseeks; - mp->modes[mp->nmds++] = sbp->sectors; -} - int seeki_mode(void *handle, struct mode *mp) { struct seeki *sip = handle; diff --git a/btt/trace.c b/btt/trace.c index ee5a654..e18a887 100644 --- a/btt/trace.c +++ b/btt/trace.c @@ -76,28 +76,25 @@ void add_trace(struct io *iop) if (iop->t.action & BLK_TC_ACT(BLK_TC_NOTIFY)) { if (iop->t.action == BLK_TN_PROCESS) { if (iop->t.pid == 0) - add_process(0, "kernel"); + process_alloc(0, "kernel"); else { char *slash = strchr(iop->pdu, '/'); if (slash) *slash = '\0'; - add_process(iop->t.pid, iop->pdu); + process_alloc(iop->t.pid, iop->pdu); } - } - else if (iop->t.action == BLK_TN_MESSAGE) + } else if (iop->t.action == BLK_TN_MESSAGE) trace_message(iop); io_release(iop); - } - else if (iop->t.action & BLK_TC_ACT(BLK_TC_PC)) + } else if (iop->t.action & BLK_TC_ACT(BLK_TC_PC)) { io_release(iop); - else { + } else { if (time_bounded) { if (BIT_TIME(iop->t.time) < t_astart) { io_release(iop); return; - } - else if (BIT_TIME(iop->t.time) > t_aend) { + } else if (BIT_TIME(iop->t.time) > t_aend) { io_release(iop); done = 1; return; diff --git a/btt/trace_plug.c b/btt/trace_plug.c index 155e92a..97e2f66 100644 --- a/btt/trace_plug.c +++ b/btt/trace_plug.c @@ -20,7 +20,7 @@ */ #include "globals.h" -__u64 get_nio_up(struct io *u_iop) +static __u64 get_nio_up(struct io *u_iop) { __u64 *val = u_iop->pdu; return be64_to_cpu(*val); diff --git a/btt/unplug_hist.c b/btt/unplug_hist.c index ed33c9c..8fd4285 100644 --- a/btt/unplug_hist.c +++ b/btt/unplug_hist.c @@ -30,7 +30,7 @@ struct hist_bkt { int hist[NBKTS * sizeof(int)]; }; -void *unplug_hist_init(__u32 device) +void *unplug_hist_alloc(__u32 device) { struct hist_bkt *hbp; @@ -48,10 +48,10 @@ void unplug_hist_add(struct io *u_iop) struct d_info *dip; dip = __dip_find(u_iop->t.device); - if (dip && dip->unplug_hist_handle) { + if (dip && dip->up_hist_handle) { __u64 *val = u_iop->pdu; int idx, n_unplugs = be64_to_cpu(*val); - struct hist_bkt *hbp = dip->unplug_hist_handle; + struct hist_bkt *hbp = dip->up_hist_handle; idx = (n_unplugs / BKT_WIDTH); if (idx > EXCESS_BKT) @@ -61,7 +61,7 @@ void unplug_hist_add(struct io *u_iop) } } -void unplug_hist_exit(void *arg) +void unplug_hist_free(void *arg) { if (arg) { FILE *fp; @@ -78,8 +78,7 @@ void unplug_hist_exit(void *arg) fprintf(fp, "%d %d\n", i, hbp->hist[i]); fclose(fp); - } - else + } else perror(oname); free(oname);