Major revamping (ver 2.0)
PATCH 1/1 Major revamping (ver 2.0)
After a lot of fighting with maintaining a tree-styled design (each trace having it's own node), it was just getting too cumbersome to work in all circumstances. Taking a clue from blkparse itself, I decided to just keep track of IOs at queue time, and updating fields based upon later traces.
The attached (large) patch works much faster, handles larger test cases with less failures, and is managing some pretty large jobs I'm working on (large Oracle-based DB analysis - 32-way box w/ lots of storage).
I've also added a Q2Q seek distance feature - it's come in handy when comparing results of IO scheduler choice: We can see what the incoming IO seek distances are (at queue time), and then see how the scheduler itself manages things (via merges & sorting) by looking at D2D seek distances generated.
As noted in the subject, I arbitrarily bumped this to version 2.00 as the innards are so different. The documentation (btt/doc/btt.tex) has been updated to reflect some minor output changes. I also fixed a bug dealing with process name notification: there was a problem that if a new PID came up with a name that was previously seen, btt wouldn't keep track of it right. [When running with Oracle, a lot of processes have the same name but different PIDs of course.]
Alan
btt/bt_timeline.c +1 -6
@@ -25,7 +25,7 @@#include <time.h> #include "globals.h" -char bt_timeline_version[] ="0.99.1" ; +char bt_timeline_version[] ="2.00" ;char *devices, *exes, *input_name, *output_name, *seek_name, *bno_dump_name;char *d2c_name, *q2c_name, *per_io_name, *unplug_hist_name;
@@ -40,13 +40,10 @@ LIST_HEAD(all_devs);LIST_HEAD (all_procs);LIST_HEAD (free_ios);LIST_HEAD (free_bilinks); -LIST_HEAD (rmhd); -LIST_HEAD (retries);__u64 q_histo[N_HIST_BKTS ], d_histo[N_HIST_BKTS ];double range_delta =0.1 ;__u64 last_q = (__u64)-1 ; -__u64 next_retry_check =0 ;struct region_info all_regions = { .qranges =LIST_HEAD_INIT (all_regions.qranges),
@@ -90,7 +87,6 @@ int main(int argc, char *argv[])dip_exit ();pip_exit ();io_free_all (); -bilink_free_all ();region_exit (&all_regions);free (input_name);
@@ -120,7 +116,6 @@ int process(void) }io_release (iop); -do_retries (0 );gettimeofday (&tve,NULL );if (verbose) {
btt/devs.c +17 -9
@@ -58,10 +58,7 @@ void __dump_rb_node(struct rb_node *n) struct io *iop = rb_entry(n, struct io, rb_node);dbg_ping (); -if (iop->type ==IOP_A ) -__dump_iop2 (stdout, iop,bilink_first_down (iop,NULL )); -else -__dump_iop (stdout, iop,0 ); +__dump_iop (stdout, iop,0 );if (n->rb_left)__dump_rb_node (n->rb_left);if (n->rb_right)
@@ -92,10 +89,8 @@ void dump_rb_trees(void) dip = list_entry(p, struct d_info, hash_head);printf ("Trees for %3d,%-3d\n" ,MAJOR (dip->device),MINOR (dip->device)); -for (type =IOP_Q ; type <N_IOP_TYPES ; type++) { -if (type !=IOP_L ) -__dump_rb_tree (dip, type); - } +for (type =IOP_Q ; type <N_IOP_TYPES ; type++) +__dump_rb_tree (dip, type); } } }
@@ -133,17 +128,29 @@ void dip_exit(void)__destroy_heads (dip->heads);region_exit (&dip->regions);seeki_exit (dip->seek_handle); +seeki_exit (dip->q2q_handle);bno_dump_exit (dip->bno_dump_handle);unplug_hist_exit (dip->unplug_hist_handle);free (dip); } } +static inline char *mkhandle (char *str,__u32 device,char *post) +{ +int mjr = device >>MINORBITS ; +int mnr = device & ((1 <<MINORBITS ) -1 ); + +sprintf (str,"%03d,%03d%s" , mjr, mnr, post); +return str; +} +struct d_info *dip_add (__u32 device,struct io *iop) {struct d_info *dip =__dip_find (device);if (dip ==NULL ) { +char str[256 ]; + dip =malloc (sizeof (struct d_info ));memset (dip,0 ,sizeof (*dip)); dip->heads =dip_rb_mkhds ();
@@ -151,9 +158,10 @@ struct d_info *dip_add(__u32 device, struct io *iop) dip->device = device; dip->last_q = (__u64)-1 ; dip->map =dev_map_find (device); - dip->seek_handle =seeki_init (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" ));latency_init (dip);list_add_tail (&dip->hash_head, &dev_heads[DEV_HASH (device)]);list_add_tail (&dip->all_head, &all_devs);
btt/doc/btt.tex +56 -267
395 lines not on this page · raw message
btt/globals.h +17 -24
110 lines not on this page · raw message
btt/inlines.h +31 -156
254 lines not on this page · raw message
btt/iostat.c +3 -3
@@ -62,7 +62,7 @@ void dump_hdr(void)void im2d2c_func (struct io *c_iop,struct io *im_iop) { -ADD_STAT (c_iop->dip, wait,tdelta (im_iop, c_iop)); +ADD_STAT (c_iop->dip, wait,tdelta (im_iop->t.time, c_iop->t.time)); }void iostat_init (void )
@@ -247,7 +247,7 @@ void iostat_check_time(__u64 stamp) } } -void iostat_insert (struct io *iop) +void iostat_getrq (struct io *iop) {update_tot_qusz (iop->dip,TO_SEC (iop->t.time));INC_STAT (iop->dip, cur_qusz);
@@ -295,5 +295,5 @@ void iostat_complete(struct io *d_iop, struct io *c_iop)update_idle_time (dip, now,0 );DEC_STAT (dip, cur_dev); -ADD_STAT (dip, svctm,tdelta (d_iop, c_iop)); +ADD_STAT (dip, svctm,tdelta (d_iop->t.time, c_iop->t.time)); }
btt/output.c +63 -48
185 lines not on this page · raw message
btt/proc.c +52 -20
110 lines not on this page · raw message
btt/seek.c +7 -11
@@ -36,19 +36,15 @@ struct seeki {long long last_start, last_end; }; -static FILE *seek_open (__u32 device,char rw) +static FILE *seek_open (char *str,char rw) {FILE *fp;char *oname; -int mjr, mnr;if (seek_name ==NULL )return NULL ; - mjr = device >>MINORBITS ; - mnr = device & ((1 <<MINORBITS ) -1 ); - - oname =malloc (strlen (seek_name)+32 ); -sprintf (oname,"%s_%03d,%03d_%c.dat" , seek_name, mjr, mnr, rw); + oname =malloc (strlen (seek_name) +strlen (str) +32 ); +sprintf (oname,"%s_%s_%c.dat" , seek_name, str, rw);if ((fp =fopen (oname,"w" )) ==NULL )perror (oname);else
@@ -124,13 +120,13 @@ long long seek_dist(struct seeki *sip, struct io *iop)return dist; } -void *seeki_init (__u32 device) +void *seeki_init (char *str) {struct seeki *sip =malloc (sizeof (struct seeki )); - sip->rfp =seek_open (device,'r' ); - sip->wfp =seek_open (device,'w' ); - sip->cfp =seek_open (device,'c' ); + sip->rfp =seek_open (str,'r' ); + sip->wfp =seek_open (str,'w' ); + sip->cfp =seek_open (str,'c' ); sip->tot_seeks =0 ; sip->total_sectors =0.0 ; sip->last_start = sip->last_end =0 ;
btt/trace.c +14 -72
118 lines not on this page · raw message
btt/trace_complete.c +47 -145
217 lines not on this page · raw message
btt/trace_im.c +29 -66
117 lines not on this page · raw message
btt/trace_issue.c +26 -59
97 lines not on this page · raw message
btt/trace_queue.c +13 -49
73 lines not on this page · raw message
btt/trace_remap.c +8 -80
103 lines not on this page · raw message
btt/trace_requeue.c +1 -20
@@ -22,24 +22,5 @@void trace_requeue (struct io *r_iop) { -struct io *d_iop; - -if ((io_setup (r_iop,IOP_R ) ==0 ) || - (d_iop =dip_find_sec (r_iop->dip,IOP_D , -BIT_START (r_iop))) ==NULL ) { -io_release (r_iop); -return ; - } -dip_rem (d_iop); - -# if defined(DEBUG ) -ASSERT (ready_issue (d_iop, r_iop) !=0 ); -# else - (void )ready_issue (d_iop, r_iop); -# endif - -run_unissue (d_iop, r_iop, r_iop); -add_rmhd (r_iop); - -release_iops (); +io_release (r_iop); }
Quoted 15 lines · Alan D. Brunelle
After a lot of fighting with maintaining a tree-styled design (each trace having it's own node), it was just getting too cumbersome to work in all circumstances. Taking a clue from blkparse itself, I decided to just keep track of IOs at queue time, and updating fields based upon later traces.
The attached (large) patch works much faster, handles larger test cases with less failures, and is managing some pretty large jobs I'm working on (large Oracle-based DB analysis - 32-way box w/ lots of storage).
I've also added a Q2Q seek distance feature - it's come in handy when comparing results of IO scheduler choice: We can see what the incoming IO seek distances are (at queue time), and then see how the scheduler itself manages things (via merges & sorting) by looking at D2D seek distances generated.
Quoted 7 lines
As noted in the subject, I arbitrarily bumped this to version 2.00 as the innards are so different. The documentation (btt/doc/btt.tex) has been updated to reflect some minor output changes. I also fixed a bug dealing with process name notification: there was a problem that if a new PID came up with a name that was previously seen, btt wouldn't keep track of it right. [When running with Oracle, a lot of processes have the same name but different PIDs of course.]
Applied (the 2nd full variant).
Signature · 1 line
Jens Axboe