Recent changes (master)

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

 



The following changes since commit 8d916c942bb088204ab5c0438c297903c9160698:

  Catch the case where size= is less than the minimum block size (2013-04-25 10:11:41 -0600)

are available in the git repository at:
  git://git.kernel.dk/fio.git master

Jens Axboe (3):
      Add support for modifying the randomness of a workload
      Get rid of td->o.perc_seq
      Ensure that stat outputs are serialized

Vincent Kang Fu (1):
      Add log_info_flush()

 HOWTO            |   11 +++++++++++
 backend.c        |    2 ++
 cconv.c          |    2 ++
 fio.1            |    9 +++++++++
 fio.h            |    9 +++++++++
 init.c           |    2 ++
 io_u.c           |   32 +++++++++++++++++++++++++++++---
 log.c            |    8 ++++++++
 log.h            |    1 +
 options.c        |   43 +++++++++++++++++++++++++++++++++++++++++++
 stat.c           |   40 ++++++++++++++++++++++++++++++++++++----
 stat.h           |    3 +++
 thread_options.h |    4 ++++
 13 files changed, 159 insertions(+), 7 deletions(-)

---

Diff of recent changes:

diff --git a/HOWTO b/HOWTO
index 6445348..8211c3b 100644
--- a/HOWTO
+++ b/HOWTO
@@ -766,6 +766,17 @@ random_distribution=str:float	By default, fio will use a completely uniform
 		random_distribution=zipf:1.2 as the option. If a non-uniform
 		model is used, fio will disable use of the random map.
 
+percentage_random=int	For a random workload, set how big a percentage should
+		be random. This defaults to 100%, in which case the workload
+		is fully random. It can be set from anywhere from 0 to 100.
+		Setting it to 0 would make the workload fully sequential. Any
+		setting in between will result in a random mix of sequential
+		and random IO, at the given percentages.
+	
+percentage_sequential=int	See percentage_random. It is guaranteed that
+		they add up to 100. The later setting has priority, each
+		will adjust the other.
+
 norandommap	Normally fio will cover every block of the file when doing
 		random IO. If this option is given, fio will just get a
 		new random offset without looking at past io history. This
diff --git a/backend.c b/backend.c
index 4d4e8ef..89ffee1 100644
--- a/backend.c
+++ b/backend.c
@@ -1895,6 +1895,7 @@ int fio_backend(void)
 		return 1;
 
 	set_genesis_time();
+	stat_init();
 	create_disk_util_thread();
 
 	cgroup_list = smalloc(sizeof(*cgroup_list));
@@ -1924,5 +1925,6 @@ int fio_backend(void)
 	fio_mutex_remove(startup_mutex);
 	fio_mutex_remove(writeout_mutex);
 	fio_mutex_remove(disk_thread_mutex);
+	stat_exit();
 	return exit_value;
 }
diff --git a/cconv.c b/cconv.c
index 57c76e3..b06f60f 100644
--- a/cconv.c
+++ b/cconv.c
@@ -125,6 +125,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,
 	o->zipf_theta.u.f = fio_uint64_to_double(le64_to_cpu(top->zipf_theta.u.i));
 	o->pareto_h.u.f = fio_uint64_to_double(le64_to_cpu(top->pareto_h.u.i));
 	o->random_generator = le32_to_cpu(top->random_generator);
+	o->perc_rand = le32_to_cpu(top->perc_rand);
 	o->hugepage_size = le32_to_cpu(top->hugepage_size);
 	o->rw_min_bs = le32_to_cpu(top->rw_min_bs);
 	o->thinktime = le32_to_cpu(top->thinktime);
@@ -283,6 +284,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top,
 	top->zipf_theta.u.i = __cpu_to_le64(fio_double_to_uint64(o->zipf_theta.u.f));
 	top->pareto_h.u.i = __cpu_to_le64(fio_double_to_uint64(o->pareto_h.u.f));
 	top->random_generator = cpu_to_le32(o->random_generator);
+	top->perc_rand = cpu_to_le32(o->perc_rand);
 	top->hugepage_size = cpu_to_le32(o->hugepage_size);
 	top->rw_min_bs = cpu_to_le32(o->rw_min_bs);
 	top->thinktime = cpu_to_le32(o->thinktime);
diff --git a/fio.1 b/fio.1
index 401d956..5082bf8 100644
--- a/fio.1
+++ b/fio.1
@@ -641,6 +641,15 @@ If you wanted to use zipf with a theta of 1.2, you would use
 random_distribution=zipf:1.2 as the option. If a non-uniform model is used,
 fio will disable use of the random map.
 .TP
+.BI percentage_random \fR=\fPint
+For a random workload, set how big a percentage should be random. This defaults
+to 100%, in which case the workload is fully random. It can be set from
+anywhere from 0 to 100.  Setting it to 0 would make the workload fully
+sequential.
+.TP
+.BI percentage_sequential \fR=\fPint
+See \fBpercentage_random\fR.
+.TP
 .B norandommap
 Normally \fBfio\fR will cover every block of the file when doing random I/O. If
 this parameter is given, a new offset will be chosen without looking at past
diff --git a/fio.h b/fio.h
index 5438b76..965d7d9 100644
--- a/fio.h
+++ b/fio.h
@@ -81,6 +81,7 @@ enum {
 	FIO_RAND_FILE_SIZE_OFF,
 	FIO_RAND_TRIM_OFF,
 	FIO_RAND_BUF_OFF,
+	FIO_RAND_SEQ_RAND_OFF,
 	FIO_RAND_NR_OFFS,
 };
 
@@ -256,6 +257,14 @@ struct thread_data {
 	unsigned int ddir_seq_nr;
 
 	/*
+	 * rand/seq mixed workload state
+	 */
+	union {
+		os_random_state_t seq_rand_state;
+		struct frand_state __seq_rand_state;
+	};
+
+	/*
 	 * IO history logs for verification. We use a tree for sorting,
 	 * if we are overwriting. Otherwise just use a fifo.
 	 */
diff --git a/init.c b/init.c
index aba7671..7246bd8 100644
--- a/init.c
+++ b/init.c
@@ -701,6 +701,7 @@ static void td_fill_rand_seeds_os(struct thread_data *td)
 		td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
 
 	os_random_seed(td->rand_seeds[FIO_RAND_BLOCK_OFF], &td->random_state);
+	os_random_seed(td->rand_seeds[FIO_RAND_SEQ_RAND_OFF], &td->seq_rand_state);
 }
 
 static void td_fill_rand_seeds_internal(struct thread_data *td)
@@ -722,6 +723,7 @@ static void td_fill_rand_seeds_internal(struct thread_data *td)
 		td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
 
 	init_rand_seed(&td->__random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF]);
+	init_rand_seed(&td->__seq_rand_state, td->rand_seeds[FIO_RAND_SEQ_RAND_OFF]);
 }
 
 void td_fill_rand_seeds(struct thread_data *td)
diff --git a/io_u.c b/io_u.c
index 19ef7b9..d03049e 100644
--- a/io_u.c
+++ b/io_u.c
@@ -191,6 +191,25 @@ static inline int should_sort_io(struct thread_data *td)
 	return 1;
 }
 
+static int should_do_random(struct thread_data *td)
+{
+	unsigned int v;
+	unsigned long r;
+
+	if (td->o.perc_rand == 100)
+		return 1;
+
+	if (td->o.use_os_rand) {
+		r = os_random_long(&td->seq_rand_state);
+		v = 1 + (int) (100.0 * (r / (OS_RAND_MAX + 1.0)));
+	} else {
+		r = __rand(&td->__seq_rand_state);
+		v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+	}
+
+	return v <= td->o.perc_rand;
+}
+
 static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
 				enum fio_ddir ddir, uint64_t *b)
 {
@@ -285,9 +304,16 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u,
 	b = offset = -1ULL;
 
 	if (rw_seq) {
-		if (td_random(td))
-			ret = get_next_rand_block(td, f, ddir, &b);
-		else
+		if (td_random(td)) {
+			if (should_do_random(td))
+				ret = get_next_rand_block(td, f, ddir, &b);
+			else {
+				io_u->flags |= IO_U_F_BUSY_OK;
+				ret = get_next_seq_offset(td, f, ddir, &offset);
+				if (ret)
+					ret = get_next_rand_block(td, f, ddir, &b);
+			}
+		} else
 			ret = get_next_seq_offset(td, f, ddir, &offset);
 	} else {
 		io_u->flags |= IO_U_F_BUSY_OK;
diff --git a/log.c b/log.c
index d481edf..4822c33 100644
--- a/log.c
+++ b/log.c
@@ -71,6 +71,14 @@ int log_info(const char *format, ...)
 		return fwrite(buffer, len, 1, f_out);
 }
 
+int log_info_flush(void)
+{
+	if (is_backend || log_syslog)
+		return 0;
+
+	return fflush(f_out);
+}
+
 int log_err(const char *format, ...)
 {
 	char buffer[1024];
diff --git a/log.h b/log.h
index 25f92f9..a885be7 100644
--- a/log.h
+++ b/log.h
@@ -12,6 +12,7 @@ extern int log_info(const char *format, ...) __attribute__ ((__format__ (__print
 extern int log_local(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
 extern int log_valist(const char *str, va_list);
 extern int log_local_buf(const char *buf, size_t);
+extern int log_info_flush(void);
 
 enum {
 	FIO_LOG_DEBUG	= 1,
diff --git a/options.c b/options.c
index 1219803..7a4e7b5 100644
--- a/options.c
+++ b/options.c
@@ -376,6 +376,23 @@ static int str_rwmix_write_cb(void *data, unsigned long long *val)
 	return 0;
 }
 
+static int str_perc_rand_cb(void *data, unsigned long long *val)
+{
+	struct thread_data *td = data;
+
+	td->o.perc_rand = *val;
+	return 0;
+}
+
+static int str_perc_seq_cb(void *data, unsigned long long *val)
+{
+	struct thread_data *td = data;
+
+	td->o.perc_rand = 100 - *val;
+	return 0;
+}
+
+
 static int str_exitall_cb(void)
 {
 	exitall_on_terminate = 1;
@@ -1643,6 +1660,32 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 		.group	= FIO_OPT_G_RANDOM,
 	},
 	{
+		.name	= "percentage_random",
+		.lname	= "Percentage Random",
+		.type	= FIO_OPT_INT,
+		.cb	= str_perc_rand_cb,
+		.maxval	= 100,
+		.help	= "Percentage of seq/random mix that should be random",
+		.def	= "100",
+		.interval = 5,
+		.inverse = "percentage_sequential",
+		.category = FIO_OPT_C_IO,
+		.group	= FIO_OPT_G_RANDOM,
+	},
+	{
+		.name	= "percentage_sequential",
+		.lname	= "Percentage Sequential",
+		.type	= FIO_OPT_INT,
+		.cb	= str_perc_seq_cb,
+		.maxval	= 100,
+		.help	= "Percentage of seq/random mix that should be sequential",
+		.def	= "0",
+		.interval = 5,
+		.inverse = "percentage_random",
+		.category = FIO_OPT_C_IO,
+		.group	= FIO_OPT_G_RANDOM,
+	},
+	{
 		.name	= "nrfiles",
 		.lname	= "Number of files",
 		.alias	= "nr_files",
diff --git a/stat.c b/stat.c
index 7ff7ad4..b386188 100644
--- a/stat.c
+++ b/stat.c
@@ -14,6 +14,8 @@
 #include "lib/getrusage.h"
 #include "idletime.h"
 
+static struct fio_mutex *stat_mutex;
+
 void update_rusage_stat(struct thread_data *td)
 {
 	struct thread_stat *ts = &td->ts;
@@ -1141,7 +1143,7 @@ void init_thread_stat(struct thread_stat *ts)
 	ts->groupid = -1;
 }
 
-void show_run_stats(void)
+static void __show_run_stats(void)
 {
 	struct group_run_stats *runstats, *rs;
 	struct thread_data *td;
@@ -1354,10 +1356,18 @@ void show_run_stats(void)
 		show_idle_prof_stats(FIO_OUTPUT_NORMAL, NULL);
 	}
 
+	log_info_flush();
 	free(runstats);
 	free(threadstats);
 }
 
+void show_run_stats(void)
+{
+	fio_mutex_down(stat_mutex);
+	__show_run_stats();
+	fio_mutex_up(stat_mutex);
+}
+
 static void *__show_running_run_stats(void fio_unused *arg)
 {
 	struct thread_data *td;
@@ -1392,7 +1402,7 @@ static void *__show_running_run_stats(void fio_unused *arg)
 		td->update_rusage = 0;
 	}
 
-	show_run_stats();
+	__show_run_stats();
 
 	for_each_td(td, i) {
 		if (td_read(td) && td->io_bytes[DDIR_READ])
@@ -1404,6 +1414,7 @@ static void *__show_running_run_stats(void fio_unused *arg)
 	}
 
 	free(rt);
+	fio_mutex_up(stat_mutex);
 	return NULL;
 }
 
@@ -1416,8 +1427,14 @@ void show_running_run_stats(void)
 {
 	pthread_t thread;
 
-	pthread_create(&thread, NULL, __show_running_run_stats, NULL);
-	pthread_detach(thread);
+	fio_mutex_down(stat_mutex);
+
+	if (!pthread_create(&thread, NULL, __show_running_run_stats, NULL)) {
+		pthread_detach(thread);
+		return;
+	}
+
+	fio_mutex_up(stat_mutex);
 }
 
 static int status_interval_init;
@@ -1700,3 +1717,18 @@ void add_iops_sample(struct thread_data *td, enum fio_ddir ddir,
 
 	fio_gettime(&td->iops_sample_time, NULL);
 }
+
+void stat_init(void)
+{
+	stat_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED);
+}
+
+void stat_exit(void)
+{
+	/*
+	 * When we have the mutex, we know out-of-band access to it
+	 * have ended.
+	 */
+	fio_mutex_down(stat_mutex);
+	fio_mutex_remove(stat_mutex);
+}
diff --git a/stat.h b/stat.h
index b1bf5dc..541b77e 100644
--- a/stat.h
+++ b/stat.h
@@ -199,6 +199,9 @@ struct jobs_eta {
 	uint8_t run_str[];
 };
 
+extern void stat_init(void);
+extern void stat_exit(void);
+
 extern void show_thread_status(struct thread_stat *ts, struct group_run_stats *rs);
 extern void show_group_stats(struct group_run_stats *rs);
 extern int calc_thread_status(struct jobs_eta *je, int force);
diff --git a/thread_options.h b/thread_options.h
index f25988a..45e22ae 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -113,6 +113,8 @@ struct thread_options {
 
 	unsigned int random_generator;
 
+	unsigned int perc_rand;
+
 	unsigned int hugepage_size;
 	unsigned int rw_min_bs;
 	unsigned int thinktime;
@@ -322,6 +324,8 @@ struct thread_options_pack {
 
 	uint32_t random_generator;
 
+	uint32_t perc_rand;
+
 	uint32_t hugepage_size;
 	uint32_t rw_min_bs;
 	uint32_t thinktime;
--
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