Recent changes (master)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following changes since commit 7351f402b131fc4ad4e25bd2609a255a1ab4e97c:

  Merge branch 'next' (2013-04-08 09:46:54 +0200)

are available in the git repository at:

  git://git.kernel.dk/fio.git master

Jens Axboe (3):
      server: bump protocol version
      parse: add posval support to FIO_OPT_INT
      options: make unit_base be posval[] based

Steven Noonan (4):
      num2str: add arguments to represent values in terms of bytes/bits
      implement 'unit_base' option to select between KB and Kbit et. al.
      stats: show summary bandwidth in terms of kb_base
      stat.c: make 'bw' summary line respect 'unit_base' option

 client.c      |    3 ++
 engines/net.c |    2 +-
 eta.c         |   11 +++++----
 fio.h         |    3 +-
 init.c        |    7 ++++++
 ioengine.h    |    1 +
 lib/num2str.c |   25 +++++++++++++++++-----
 options.c     |   21 +++++++++++++++++++
 parse.c       |   18 ++++++++++++++++
 server.c      |    2 +
 server.h      |    2 +-
 stat.c        |   62 ++++++++++++++++++++++++++++++++++----------------------
 stat.h        |    3 ++
 13 files changed, 122 insertions(+), 38 deletions(-)

---

Diff of recent changes:

diff --git a/client.c b/client.c
index 0dc620d..7915268 100644
--- a/client.c
+++ b/client.c
@@ -651,6 +651,7 @@ static void convert_ts(struct thread_stat *dst, struct thread_stat *src)
 	dst->total_err_count	= le64_to_cpu(src->total_err_count);
 	dst->first_error	= le32_to_cpu(src->first_error);
 	dst->kb_base		= le32_to_cpu(src->kb_base);
+	dst->unit_base		= le32_to_cpu(src->unit_base);
 }
 
 static void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
@@ -667,6 +668,7 @@ static void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
 	}
 
 	dst->kb_base	= le32_to_cpu(src->kb_base);
+	dst->unit_base	= le32_to_cpu(src->unit_base);
 	dst->groupid	= le32_to_cpu(src->groupid);
 	dst->unified_rw_rep	= le32_to_cpu(src->unified_rw_rep);
 }
@@ -774,6 +776,7 @@ static void convert_jobs_eta(struct jobs_eta *je)
 	je->elapsed_sec		= le64_to_cpu(je->elapsed_sec);
 	je->eta_sec		= le64_to_cpu(je->eta_sec);
 	je->is_pow2		= le32_to_cpu(je->is_pow2);
+	je->unit_base   = le32_to_cpu(je->unit_base);
 }
 
 static void sum_jobs_eta(struct jobs_eta *dst, struct jobs_eta *je)
diff --git a/engines/net.c b/engines/net.c
index 624ff15..31f7151 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -970,7 +970,7 @@ static struct ioengine_ops ioengine_rw = {
 	.options		= options,
 	.option_struct_size	= sizeof(struct netio_options),
 	.flags			= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
-				  FIO_PIPEIO,
+				  FIO_PIPEIO | FIO_BIT_BASED,
 };
 
 static int str_hostname_cb(void *data, const char *input)
diff --git a/eta.c b/eta.c
index f90d428..50d229c 100644
--- a/eta.c
+++ b/eta.c
@@ -319,6 +319,7 @@ int calc_thread_status(struct jobs_eta *je, int force)
 		unified_rw_rep += td->o.unified_rw_rep;
 		if (is_power_of_2(td->o.kb_base))
 			je->is_pow2 = 1;
+		je->unit_base = td->o.unit_base;
 		if (td->o.bw_avg_time < bw_avg_time)
 			bw_avg_time = td->o.bw_avg_time;
 		if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING
@@ -449,9 +450,9 @@ void display_thread_status(struct jobs_eta *je)
 	if (je->m_rate || je->t_rate) {
 		char *tr, *mr;
 
-		mr = num2str(je->m_rate, 4, 0, je->is_pow2);
-		tr = num2str(je->t_rate, 4, 0, je->is_pow2);
-		p += sprintf(p, ", CR=%s/%s KB/s", tr, mr);
+		mr = num2str(je->m_rate, 4, 0, je->is_pow2, 8);
+		tr = num2str(je->t_rate, 4, 0, je->is_pow2, 8);
+		p += sprintf(p, ", CR=%s/%s /s", tr, mr);
 		free(tr);
 		free(mr);
 	} else if (je->m_iops || je->t_iops)
@@ -474,8 +475,8 @@ void display_thread_status(struct jobs_eta *je)
 
 		for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++) {
 			rate_str[ddir] = num2str(je->rate[ddir], 5,
-						1024, je->is_pow2);
-			iops_str[ddir] = num2str(je->iops[ddir], 4, 1, 0);
+						1024, je->is_pow2, je->unit_base);
+			iops_str[ddir] = num2str(je->iops[ddir], 4, 1, 0, 0);
 		}
 
 		left = sizeof(output) - (p - output) - 1;
diff --git a/fio.h b/fio.h
index db594ab..e74bdb3 100644
--- a/fio.h
+++ b/fio.h
@@ -108,6 +108,7 @@ struct thread_options {
 	enum td_ddir td_ddir;
 	unsigned int rw_seq;
 	unsigned int kb_base;
+	unsigned int unit_base;
 	unsigned int ddir_seq_nr;
 	long ddir_seq_add;
 	unsigned int iodepth;
@@ -686,7 +687,7 @@ extern void fio_options_mem_dupe(struct thread_data *);
 extern void options_mem_dupe(void *data, struct fio_option *options);
 extern void td_fill_rand_seeds(struct thread_data *);
 extern void add_job_opts(const char **);
-extern char *num2str(unsigned long, int, int, int);
+extern char *num2str(unsigned long, int, int, int, int);
 extern int ioengine_load(struct thread_data *);
 
 #define FIO_GETOPT_JOB		0x89000000
diff --git a/init.c b/init.c
index 92b3e5b..44c74e3 100644
--- a/init.c
+++ b/init.c
@@ -560,6 +560,13 @@ static int fixup_options(struct thread_data *td)
 		}
 	}
 
+	if (!o->unit_base) {
+		if (td->io_ops->flags & FIO_BIT_BASED)
+			o->unit_base = 1;
+		else
+			o->unit_base = 8;
+	}
+
 #ifndef CONFIG_FDATASYNC
 	if (o->fdatasync_blocks) {
 		log_info("fio: this platform does not support fdatasync()"
diff --git a/ioengine.h b/ioengine.h
index 7299636..d15d15e 100644
--- a/ioengine.h
+++ b/ioengine.h
@@ -153,6 +153,7 @@ enum fio_ioengine_flags {
 	FIO_PIPEIO	= 1 << 7,	/* input/output no seekable */
 	FIO_BARRIER	= 1 << 8,	/* engine supports barriers */
 	FIO_MEMALIGN	= 1 << 9,	/* engine wants aligned memory */
+	FIO_BIT_BASED	= 1 << 10,	/* engine uses a bit base (e.g. uses Kbit as opposed to KB) */
 };
 
 /*
diff --git a/lib/num2str.c b/lib/num2str.c
index 559cbeb..a104192 100644
--- a/lib/num2str.c
+++ b/lib/num2str.c
@@ -5,12 +5,13 @@
 /*
  * Cheesy number->string conversion, complete with carry rounding error.
  */
-char *num2str(unsigned long num, int maxlen, int base, int pow2)
+char *num2str(unsigned long num, int maxlen, int base, int pow2, int unit_base)
 {
-	char postfix[] = { ' ', 'K', 'M', 'G', 'P', 'E' };
-	unsigned int thousand[] = { 1000, 1024 };
+	const char *postfix[] = { "", "K", "M", "G", "P", "E" };
+	const char *byte_postfix[] = { "", "B", "bit" };
+	const unsigned int thousand[] = { 1000, 1024 };
 	unsigned int modulo, decimals;
-	int post_index, carry = 0;
+	int byte_post_index = 0, post_index, carry = 0;
 	char tmp[32];
 	char *buf;
 
@@ -19,6 +20,16 @@ char *num2str(unsigned long num, int maxlen, int base, int pow2)
 	for (post_index = 0; base > 1; post_index++)
 		base /= thousand[!!pow2];
 
+	switch (unit_base) {
+	case 1:
+		byte_post_index = 2;
+		num *= 8;
+		break;
+	case 8:
+		byte_post_index = 1;
+		break;
+	}
+
 	modulo = -1U;
 	while (post_index < sizeof(postfix)) {
 		sprintf(tmp, "%lu", num);
@@ -33,7 +44,8 @@ char *num2str(unsigned long num, int maxlen, int base, int pow2)
 
 	if (modulo == -1U) {
 done:
-		sprintf(buf, "%lu%c", num, postfix[post_index]);
+		sprintf(buf, "%lu%s%s", num, postfix[post_index],
+			byte_postfix[byte_post_index]);
 		return buf;
 	}
 
@@ -53,6 +65,7 @@ done:
 		modulo = (modulo + 9) / 10;
 	} while (1);
 
-	sprintf(buf, "%lu.%u%c", num, modulo, postfix[post_index]);
+	sprintf(buf, "%lu.%u%s%s", num, modulo, postfix[post_index],
+		byte_postfix[byte_post_index]);
 	return buf;
 }
diff --git a/options.c b/options.c
index bca217f..6cd1e92 100644
--- a/options.c
+++ b/options.c
@@ -1149,6 +1149,27 @@ static struct fio_option options[FIO_MAX_OPTS] = {
 		.help	= "How many bytes per KB for reporting (1000 or 1024)",
 	},
 	{
+		.name	= "unit_base",
+		.type	= FIO_OPT_INT,
+		.off1	= td_var_offset(unit_base),
+		.prio	= 1,
+		.posval = {
+			  { .ival = "0",
+			    .oval = 0,
+			    .help = "Auto-detect",
+			  },
+			  { .ival = "8",
+			    .oval = 8,
+			    .help = "Normal (byte based)",
+			  },
+			  { .ival = "1",
+			    .oval = 1,
+			    .help = "Bit based",
+			  },
+		},
+		.help	= "Bit multiple of result summary data (8 for byte, 1 for bit)",
+	},
+	{
 		.name	= "lockfile",
 		.type	= FIO_OPT_STR,
 		.off1	= td_var_offset(file_lock_mode),
diff --git a/parse.c b/parse.c
index 5b8e10f..dddcb8e 100644
--- a/parse.c
+++ b/parse.c
@@ -465,6 +465,24 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 					" (%u min)\n", ull, o->minval);
 			return 1;
 		}
+		if (o->posval[0].ival) {
+			posval_sort(o, posval);
+
+			ret = 1;
+			for (i = 0; i < PARSE_MAX_VP; i++) {
+				vp = &posval[i];
+				if (!vp->ival || vp->ival[0] == '\0')
+					continue;
+				if (vp->oval == ull) {
+					ret = 0;
+					break;
+				}
+			}
+			if (ret) {
+				log_err("value %d not in allowed range\n",ull);
+				return 1;
+			}
+		}
 
 		if (fn)
 			ret = fn(data, &ull);
diff --git a/server.c b/server.c
index d4676dd..f239d43 100644
--- a/server.c
+++ b/server.c
@@ -648,6 +648,7 @@ static void convert_gs(struct group_run_stats *dst, struct group_run_stats *src)
 	}
 
 	dst->kb_base	= cpu_to_le32(src->kb_base);
+	dst->unit_base	= cpu_to_le32(src->unit_base);
 	dst->groupid	= cpu_to_le32(src->groupid);
 	dst->unified_rw_rep	= cpu_to_le32(src->unified_rw_rep);
 }
@@ -730,6 +731,7 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
 	p.ts.total_err_count	= cpu_to_le64(ts->total_err_count);
 	p.ts.first_error	= cpu_to_le32(ts->first_error);
 	p.ts.kb_base		= cpu_to_le32(ts->kb_base);
+	p.ts.unit_base		= cpu_to_le32(ts->unit_base);
 
 	convert_gs(&p.rs, rs);
 
diff --git a/server.h b/server.h
index 15b802b..da11671 100644
--- a/server.h
+++ b/server.h
@@ -36,7 +36,7 @@ struct fio_net_int_cmd {
 };
 
 enum {
-	FIO_SERVER_VER		= 10,
+	FIO_SERVER_VER		= 11,
 
 	FIO_SERVER_MAX_PDU	= 1024,
 
diff --git a/stat.c b/stat.c
index 38c5d02..ab2f808 100644
--- a/stat.c
+++ b/stat.c
@@ -276,12 +276,12 @@ void show_group_stats(struct group_run_stats *rs)
 		if (!rs->max_run[i])
 			continue;
 
-		p1 = num2str(rs->io_kb[i], 6, rs->kb_base, i2p);
-		p2 = num2str(rs->agg[i], 6, rs->kb_base, i2p);
-		p3 = num2str(rs->min_bw[i], 6, rs->kb_base, i2p);
-		p4 = num2str(rs->max_bw[i], 6, rs->kb_base, i2p);
+		p1 = num2str(rs->io_kb[i], 6, rs->kb_base, i2p, 8);
+		p2 = num2str(rs->agg[i], 6, rs->kb_base, i2p, rs->unit_base);
+		p3 = num2str(rs->min_bw[i], 6, rs->kb_base, i2p, rs->unit_base);
+		p4 = num2str(rs->max_bw[i], 6, rs->kb_base, i2p, rs->unit_base);
 
-		log_info("%s: io=%sB, aggrb=%sB/s, minb=%sB/s, maxb=%sB/s,"
+		log_info("%s: io=%s, aggrb=%s/s, minb=%s/s, maxb=%s/s,"
 			 " mint=%llumsec, maxt=%llumsec\n",
 				rs->unified_rw_rep ? "  MIXED" : ddir_str[i],
 				p1, p2, p3, p4, rs->min_run[i], rs->max_run[i]);
@@ -379,13 +379,13 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts,
 	runt = ts->runtime[ddir];
 
 	bw = (1000 * ts->io_bytes[ddir]) / runt;
-	io_p = num2str(ts->io_bytes[ddir], 6, 1, i2p);
-	bw_p = num2str(bw, 6, 1, i2p);
+	io_p = num2str(ts->io_bytes[ddir], 6, 1, i2p, 8);
+	bw_p = num2str(bw, 6, 1, i2p, ts->unit_base);
 
 	iops = (1000 * (uint64_t)ts->total_io_u[ddir]) / runt;
-	iops_p = num2str(iops, 6, 1, 0);
+	iops_p = num2str(iops, 6, 1, 0, 0);
 
-	log_info("  %s: io=%sB, bw=%sB/s, iops=%s, runt=%6llumsec\n",
+	log_info("  %s: io=%s, bw=%s/s, iops=%s, runt=%6llumsec\n",
 				rs->unified_rw_rep ? "mixed" : ddir_str[ddir],
 				io_p, bw_p, iops_p, ts->runtime[ddir]);
 
@@ -400,8 +400,8 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts,
 		if (!usec_to_msec(&min, &max, &mean, &dev))
 			base = "(msec)";
 
-		minp = num2str(min, 6, 1, 0);
-		maxp = num2str(max, 6, 1, 0);
+		minp = num2str(min, 6, 1, 0, 0);
+		maxp = num2str(max, 6, 1, 0, 0);
 
 		log_info("    slat %s: min=%s, max=%s, avg=%5.02f,"
 			 " stdev=%5.02f\n", base, minp, maxp, mean, dev);
@@ -416,8 +416,8 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts,
 		if (!usec_to_msec(&min, &max, &mean, &dev))
 			base = "(msec)";
 
-		minp = num2str(min, 6, 1, 0);
-		maxp = num2str(max, 6, 1, 0);
+		minp = num2str(min, 6, 1, 0, 0);
+		maxp = num2str(max, 6, 1, 0, 0);
 
 		log_info("    clat %s: min=%s, max=%s, avg=%5.02f,"
 			 " stdev=%5.02f\n", base, minp, maxp, mean, dev);
@@ -432,8 +432,8 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts,
 		if (!usec_to_msec(&min, &max, &mean, &dev))
 			base = "(msec)";
 
-		minp = num2str(min, 6, 1, 0);
-		maxp = num2str(max, 6, 1, 0);
+		minp = num2str(min, 6, 1, 0, 0);
+		maxp = num2str(max, 6, 1, 0, 0);
 
 		log_info("     lat %s: min=%s, max=%s, avg=%5.02f,"
 			 " stdev=%5.02f\n", base, minp, maxp, mean, dev);
@@ -448,8 +448,15 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts,
 					ts->percentile_precision);
 	}
 	if (calc_lat(&ts->bw_stat[ddir], &min, &max, &mean, &dev)) {
-		double p_of_agg = 100.0;
-		const char *bw_str = "KB";
+		double p_of_agg = 100.0, fkb_base = (double)rs->kb_base;
+		const char *bw_str = (rs->unit_base == 1 ? "Kbit" : "KB");
+
+		if (rs->unit_base == 1) {
+			min *= 8.0;
+			max *= 8.0;
+			mean *= 8.0;
+			dev *= 8.0;
+		}
 
 		if (rs->agg[ddir]) {
 			p_of_agg = mean * 100 / (double) rs->agg[ddir];
@@ -457,15 +464,15 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts,
 				p_of_agg = 100.0;
 		}
 
-		if (mean > 999999.9) {
-			min /= 1000.0;
-			max /= 1000.0;
-			mean /= 1000.0;
-			dev /= 1000.0;
-			bw_str = "MB";
+		if (mean > fkb_base * fkb_base) {
+			min /= fkb_base;
+			max /= fkb_base;
+			mean /= fkb_base;
+			dev /= fkb_base;
+			bw_str = (rs->unit_base == 1 ? "Mbit" : "MB");
 		}
 
-		log_info("    bw (%s/s)  : min=%5lu, max=%5lu, per=%3.2f%%,"
+		log_info("    bw (%-4s/s): min=%5lu, max=%5lu, per=%3.2f%%,"
 			 " avg=%5.02f, stdev=%5.02f\n", bw_str, min, max,
 							p_of_agg, mean, dev);
 	}
@@ -1169,6 +1176,7 @@ void show_run_stats(void)
 	struct thread_stat *threadstats, *ts;
 	int i, j, nr_ts, last_ts, idx;
 	int kb_base_warned = 0;
+	int unit_base_warned = 0;
 	struct json_object *root = NULL;
 	struct json_array *array = NULL;
 
@@ -1240,11 +1248,16 @@ void show_run_stats(void)
 			ts->pid = td->pid;
 
 			ts->kb_base = td->o.kb_base;
+			ts->unit_base = td->o.unit_base;
 			ts->unified_rw_rep = td->o.unified_rw_rep;
 		} else if (ts->kb_base != td->o.kb_base && !kb_base_warned) {
 			log_info("fio: kb_base differs for jobs in group, using"
 				 " %u as the base\n", ts->kb_base);
 			kb_base_warned = 1;
+		} else if (ts->unit_base != td->o.unit_base && !unit_base_warned) {
+			log_info("fio: unit_base differs for jobs in group, using"
+				 " %u as the base\n", ts->unit_base);
+			unit_base_warned = 1;
 		}
 
 		ts->continue_on_error = td->o.continue_on_error;
@@ -1270,6 +1283,7 @@ void show_run_stats(void)
 		ts = &threadstats[i];
 		rs = &runstats[ts->groupid];
 		rs->kb_base = ts->kb_base;
+		rs->unit_base = ts->unit_base;
 		rs->unified_rw_rep += ts->unified_rw_rep;
 
 		for (j = 0; j < DDIR_RWDIR_CNT; j++) {
diff --git a/stat.h b/stat.h
index 98ae4c8..f23abfa 100644
--- a/stat.h
+++ b/stat.h
@@ -7,6 +7,7 @@ struct group_run_stats {
 	uint64_t io_kb[DDIR_RWDIR_CNT];
 	uint64_t agg[DDIR_RWDIR_CNT];
 	uint32_t kb_base;
+	uint32_t unit_base;
 	uint32_t groupid;
 	uint32_t unified_rw_rep;
 };
@@ -170,6 +171,7 @@ struct thread_stat {
 	uint32_t first_error;
 
 	uint32_t kb_base;
+	uint32_t unit_base;
 };
 
 struct jobs_eta {
@@ -184,6 +186,7 @@ struct jobs_eta {
 	uint64_t elapsed_sec;
 	uint64_t eta_sec;
 	uint32_t is_pow2;
+	uint32_t unit_base;
 
 	/*
 	 * Network 'copy' of run_str[]
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux