[PATCH] Add support for writing aggregate bandwidth log
authorJens Axboe <jens.axboe@oracle.com>
Wed, 17 Jan 2007 06:23:11 +0000 (17:23 +1100)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 17 Jan 2007 06:23:11 +0000 (17:23 +1100)
This is the same that is shown while fio is running, it can be useful
for graphing purposes as well.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
eta.c
fio.c
fio.h
init.c
log.c
stat.c

diff --git a/eta.c b/eta.c
index 3ffb1114783892da44cf8c1dd5c382ae9b0037c8..feda8d0f15615e764c1ff0a590f5cfd858aa989f 100644 (file)
--- a/eta.c
+++ b/eta.c
@@ -180,7 +180,7 @@ void print_thread_status(void)
        static struct timeval prev_time;
        static unsigned int r_rate, w_rate;
        unsigned long long io_bytes[2];
        static struct timeval prev_time;
        static unsigned int r_rate, w_rate;
        unsigned long long io_bytes[2];
-       unsigned long mtime;
+       unsigned long mtime, bw_avg_time;
 
        if (temp_stall_ts || terse_output)
                return;
 
        if (temp_stall_ts || terse_output)
                return;
@@ -193,7 +193,10 @@ void print_thread_status(void)
 
        io_bytes[0] = io_bytes[1] = 0;
        nr_pending = nr_running = t_rate = m_rate = 0;
 
        io_bytes[0] = io_bytes[1] = 0;
        nr_pending = nr_running = t_rate = m_rate = 0;
+       bw_avg_time = ULONG_MAX;
        for_each_td(td, i) {
        for_each_td(td, i) {
+               if (td->bw_avg_time < bw_avg_time)
+                       bw_avg_time = td->bw_avg_time;
                if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING||
                    td->runstate == TD_FSYNCING) {
                        nr_running++;
                if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING||
                    td->runstate == TD_FSYNCING) {
                        nr_running++;
@@ -235,10 +238,12 @@ void print_thread_status(void)
        }
 
        mtime = mtime_since_now(&prev_time);
        }
 
        mtime = mtime_since_now(&prev_time);
-       if (mtime > 1000) {
+       if (mtime > bw_avg_time) {
                r_rate = (io_bytes[0] - prev_io_bytes[0]) / mtime;
                w_rate = (io_bytes[1] - prev_io_bytes[1]) / mtime;
                fio_gettime(&prev_time, NULL);
                r_rate = (io_bytes[0] - prev_io_bytes[0]) / mtime;
                w_rate = (io_bytes[1] - prev_io_bytes[1]) / mtime;
                fio_gettime(&prev_time, NULL);
+               add_agg_sample(r_rate, DDIR_READ);
+               add_agg_sample(w_rate, DDIR_WRITE);
                memcpy(prev_io_bytes, io_bytes, sizeof(io_bytes));
        }
 
                memcpy(prev_io_bytes, io_bytes, sizeof(io_bytes));
        }
 
diff --git a/fio.c b/fio.c
index 225aaa4d4550c2ea385f8eaaee70b9b8d1bc321d..4c761c038bd170f16d0d10c094c69e96f7fa503f 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -49,6 +49,8 @@ int temp_stall_ts;
 static volatile int startup_sem;
 static volatile int fio_abort;
 
 static volatile int startup_sem;
 static volatile int fio_abort;
 
+struct io_log *agg_io_log[2];
+
 #define TERMINATE_ALL          (-1)
 #define JOB_START_TIMEOUT      (5 * 1000)
 
 #define TERMINATE_ALL          (-1)
 #define JOB_START_TIMEOUT      (5 * 1000)
 
@@ -998,12 +1000,22 @@ int main(int argc, char *argv[])
                return 1;
        }
 
                return 1;
        }
 
+       if (write_bw_log) {
+               setup_log(&agg_io_log[DDIR_READ]);
+               setup_log(&agg_io_log[DDIR_WRITE]);
+       }
+
        disk_util_timer_arm();
 
        run_threads();
 
        disk_util_timer_arm();
 
        run_threads();
 
-       if (!fio_abort)
+       if (!fio_abort) {
                show_run_stats();
                show_run_stats();
+               if (write_bw_log) {
+                       __finish_log(agg_io_log[DDIR_READ],"agg-read_bw.log");
+                       __finish_log(agg_io_log[DDIR_WRITE],"agg-write_bw.log");
+               }
+       }
 
        return 0;
 }
 
        return 0;
 }
diff --git a/fio.h b/fio.h
index c21440667a51bf6c09db8c39b799901dbdf97446..6e0c5b18cb8fefef632396431164fc3633554491 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -464,7 +464,11 @@ extern void update_io_ticks(void);
 extern void disk_util_timer_arm(void);
 extern void setup_log(struct io_log **);
 extern void finish_log(struct thread_data *, struct io_log *, const char *);
 extern void disk_util_timer_arm(void);
 extern void setup_log(struct io_log **);
 extern void finish_log(struct thread_data *, struct io_log *, const char *);
+extern void __finish_log(struct io_log *, const char *);
 extern int setup_rate(struct thread_data *);
 extern int setup_rate(struct thread_data *);
+extern struct io_log *agg_io_log[2];
+extern int write_bw_log;
+extern void add_agg_sample(unsigned long, enum fio_ddir);
 
 /*
  * Time functions
 
 /*
  * Time functions
diff --git a/init.c b/init.c
index e0e1d9f0ab6ed358348fb7c21e5a0e56b103ad57..365a8b2cc0a97651eaf5cad0fd6e7f5db089d43f 100644 (file)
--- a/init.c
+++ b/init.c
@@ -532,7 +532,7 @@ FILE *f_out = NULL;
 FILE *f_err = NULL;
 
 static int write_lat_log = 0;
 FILE *f_err = NULL;
 
 static int write_lat_log = 0;
-static int write_bw_log = 0;
+int write_bw_log = 0;
 
 /*
  * Return a free job structure.
 
 /*
  * Return a free job structure.
diff --git a/log.c b/log.c
index a4f4c7801d0fa92671bd4b67ee8798b7f0f88924..a705e5021415ad7069e169ba06906435724d1f37 100644 (file)
--- a/log.c
+++ b/log.c
@@ -218,14 +218,12 @@ void setup_log(struct io_log **log)
        *log = l;
 }
 
        *log = l;
 }
 
-void finish_log(struct thread_data *td, struct io_log *log, const char *name)
+void __finish_log(struct io_log *log, const char *name)
 {
 {
-       char file_name[256];
-       FILE *f;
        unsigned int i;
        unsigned int i;
+       FILE *f;
 
 
-       snprintf(file_name, 200, "client%d_%s.log", td->thread_number, name);
-       f = fopen(file_name, "w");
+       f = fopen(name, "w");
        if (!f) {
                perror("fopen log");
                return;
        if (!f) {
                perror("fopen log");
                return;
@@ -238,3 +236,11 @@ void finish_log(struct thread_data *td, struct io_log *log, const char *name)
        free(log->log);
        free(log);
 }
        free(log->log);
        free(log);
 }
+
+void finish_log(struct thread_data *td, struct io_log *log, const char *name)
+{
+       char file_name[256];
+
+       snprintf(file_name, 200, "client%d_%s.log", td->thread_number, name);
+       __finish_log(log, file_name);
+}
diff --git a/stat.c b/stat.c
index d8b065ec48550b60a16fd6361d014031082337ca..636955e25c7d6d175db84bfb5c0beae117aa82cd 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -381,7 +381,7 @@ static void show_thread_status(struct thread_data *td,
        if (!(td->io_bytes[0] + td->io_bytes[1]) && !td->error)
                return;
 
        if (!(td->io_bytes[0] + td->io_bytes[1]) && !td->error)
                return;
 
-       fprintf(f_out, "%s: (groupid=%d): err=%2d:\n",td->name, td->groupid, td->error);
+       fprintf(f_out, "%s: (groupid=%d): err=%2d: pid=%d\n",td->name, td->groupid, td->error, td->pid);
 
        show_ddir_status(td, rs, td->ddir);
        if (td->io_bytes[td->ddir ^ 1])
 
        show_ddir_status(td, rs, td->ddir);
        if (td->io_bytes[td->ddir ^ 1])
@@ -574,8 +574,8 @@ static inline void add_stat_sample(struct io_stat *is, unsigned long data)
        is->samples++;
 }
 
        is->samples++;
 }
 
-static void add_log_sample(struct thread_data *td, struct io_log *iolog,
-                          unsigned long val, enum fio_ddir ddir)
+static void __add_log_sample(struct io_log *iolog, unsigned long val,
+                            enum fio_ddir ddir, unsigned long time)
 {
        if (iolog->nr_samples == iolog->max_samples) {
                int new_size = sizeof(struct io_sample) * iolog->max_samples*2;
 {
        if (iolog->nr_samples == iolog->max_samples) {
                int new_size = sizeof(struct io_sample) * iolog->max_samples*2;
@@ -585,11 +585,24 @@ static void add_log_sample(struct thread_data *td, struct io_log *iolog,
        }
 
        iolog->log[iolog->nr_samples].val = val;
        }
 
        iolog->log[iolog->nr_samples].val = val;
-       iolog->log[iolog->nr_samples].time = mtime_since_now(&td->epoch);
+       iolog->log[iolog->nr_samples].time = time;
        iolog->log[iolog->nr_samples].ddir = ddir;
        iolog->nr_samples++;
 }
 
        iolog->log[iolog->nr_samples].ddir = ddir;
        iolog->nr_samples++;
 }
 
+static void add_log_sample(struct thread_data *td, struct io_log *iolog,
+                          unsigned long val, enum fio_ddir ddir)
+{
+       __add_log_sample(iolog, val, ddir, mtime_since_now(&td->epoch));
+}
+
+void add_agg_sample(unsigned long val, enum fio_ddir ddir)
+{
+       struct io_log *iolog = agg_io_log[ddir];
+
+       __add_log_sample(iolog, val, ddir, mtime_since_genesis());
+}
+
 void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
                     unsigned long msec)
 {
 void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
                     unsigned long msec)
 {