The following changes since commit 3427207d9d638a6c4bd4ca8e9b3634733fd2c780: Improve Makefile for t/ test code (2011-08-16 10:01:03 +0200) are available in the git repository at: git://git.kernel.dk/fio.git master Jens Axboe (3): Add possibility to make sequential IO "holed" Make SH port work for packagers that don't differentiate between SH4 and SH4A Add 'null' perf test HOWTO | 8 ++++++-- arch/arch-sh.h | 35 ++++++++++++++++++++++++++++++----- arch/arch.h | 14 ++++++++++++++ examples/null | 10 ++++++++++ fio.1 | 5 ++++- fio.c | 6 +++++- fio.h | 1 + io_u.c | 7 ++++++- options.c | 19 +++++++++++++++++-- 9 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 examples/null --- Diff of recent changes: diff --git a/HOWTO b/HOWTO index 72a29a9..a1b2e8c 100644 --- a/HOWTO +++ b/HOWTO @@ -319,8 +319,12 @@ rw=str Type of io pattern. Accepted values are: a number of IO's to do before getting a new offset, this is one by appending a ':<nr>' to the end of the string given. For a random read, it would look like 'rw=randread:8' for - passing in an offset modifier with a value of 8. See the - 'rw_sequencer' option. + passing in an offset modifier with a value of 8. If the + postfix is used with a sequential IO pattern, then the value + specified will be added to the generated offset for each IO. + For instance, using rw=write:4k will skip 4k for every + write. It turns sequential IO into sequential IO with holes. + See the 'rw_sequencer' option. rw_sequencer=str If an offset modifier is given by appending a number to the rw=<str> line, then this option controls how that diff --git a/arch/arch-sh.h b/arch/arch-sh.h index 08c5fb3..ef4ee03 100644 --- a/arch/arch-sh.h +++ b/arch/arch-sh.h @@ -22,13 +22,38 @@ #define nop __asm__ __volatile__ ("nop": : :"memory") -#if defined(__SH4A__) -#define mb() __asm__ __volatile__ ("synco": : :"memory") -#else -#define mb() __asm__ __volatile__ (" " : : : "memory") -#endif +#define mb() \ + do { \ + if (arch_flags & ARCH_FLAG_1) \ + __asm__ __volatile__ ("synco": : :"memory"); \ + else \ + __asm__ __volatile__ (" " : : : "memory"); \ + } while (0) #define read_barrier() mb() #define write_barrier() mb() +#define CPU_HAS_LLSC 0x0040 + +static inline int arch_init(char *envp[]) +{ + Elf32_auxv_t *auxv; + + while (*envp++ != NULL) + ; + + for (auxv = (Elf32_auxv_t *) envp; auxv->a_type != AT_NULL; auxv++) { + if (auxv->a_type == AT_HWCAP) { + if (auxv->a_un.a_val & CPU_HAS_LLSC) { + arch_flags |= ARCH_FLAG_1; + break; + } + } + } + + return 0; +} + +#define ARCH_HAVE_INIT + #endif diff --git a/arch/arch.h b/arch/arch.h index 8cafa11..16f4c3a 100644 --- a/arch/arch.h +++ b/arch/arch.h @@ -58,4 +58,18 @@ enum { #include "../lib/ffz.h" #endif +#ifndef ARCH_HAVE_INIT +static inline int arch_init(char *envp[]) +{ + return 0; +} +#endif + +enum { + ARCH_FLAG_1 = 1 << 0, + ARCH_FLAG_2 = 1 << 1, + ARCH_FLAG_3 = 1 << 2, + ARCH_FLAG_4 = 1 << 3, +}; + #endif diff --git a/examples/null b/examples/null new file mode 100644 index 0000000..9d2f3e0 --- /dev/null +++ b/examples/null @@ -0,0 +1,10 @@ +[global] +bs=4k +gtod_reduce=1 + +[null] +ioengine=null +size=100g +rw=randread +norandommap +time_based=0 diff --git a/fio.1 b/fio.1 index 40940f3..488896c 100644 --- a/fio.1 +++ b/fio.1 @@ -181,7 +181,10 @@ may still be skewed a bit, since the speed may be different. It is possible to specify a number of IO's to do before getting a new offset, this is one by appending a `:\fI<nr>\fR to the end of the string given. For a random read, it would look like \fBrw=randread:8\fR for passing in an offset modifier with a -value of 8. See the \fBrw_sequencer\fR option. +value of 8. If the postfix is used with a sequential IO pattern, then the value +specified will be added to the generated offset for each IO. For instance, +using \fBrw=write:4k\fR will skip 4k for every write. It turns sequential IO +into sequential IO with holes. See the \fBrw_sequencer\fR option. .RE .TP .BI rw_sequencer \fR=\fPstr diff --git a/fio.c b/fio.c index 7396421..9c1bed3 100644 --- a/fio.c +++ b/fio.c @@ -70,6 +70,8 @@ static pthread_t disk_util_thread; static struct flist_head *cgroup_list; static char *cgroup_mnt; +unsigned long arch_flags = 0; + struct io_log *agg_io_log[2]; #define TERMINATE_ALL (-1) @@ -1690,10 +1692,12 @@ static void run_threads(void) fio_unpin_memory(); } -int main(int argc, char *argv[]) +int main(int argc, char *argv[], char *envp[]) { long ps; + arch_init(envp); + sinit(); init_rand(&__fio_rand_state); diff --git a/fio.h b/fio.h index 6c57496..9d2a61c 100644 --- a/fio.h +++ b/fio.h @@ -254,6 +254,7 @@ struct thread_options { unsigned int rw_seq; unsigned int kb_base; unsigned int ddir_seq_nr; + unsigned long ddir_seq_add; unsigned int iodepth; unsigned int iodepth_low; unsigned int iodepth_batch; diff --git a/io_u.c b/io_u.c index 51da223..6a53bda 100644 --- a/io_u.c +++ b/io_u.c @@ -249,7 +249,12 @@ static int get_next_seq_block(struct thread_data *td, struct fio_file *f, assert(ddir_rw(ddir)); if (f->last_pos < f->real_file_size) { - *b = (f->last_pos - f->file_offset) / td->o.min_bs[ddir]; + unsigned long long pos = f->last_pos - f->file_offset; + + if (pos) + pos += td->o.ddir_seq_add; + + *b = pos / td->o.min_bs[ddir]; return 0; } diff --git a/options.c b/options.c index 3d8a720..6a87e98 100644 --- a/options.c +++ b/options.c @@ -203,11 +203,26 @@ static int str_rw_cb(void *data, const char *str) char *nr = get_opt_postfix(str); td->o.ddir_seq_nr = 1; - if (nr) { + td->o.ddir_seq_add = 0; + + if (!nr) + return 0; + + if (td_random(td)) td->o.ddir_seq_nr = atoi(nr); - free(nr); + else { + long long val; + + if (str_to_decimal(nr, &val, 1, td)) { + log_err("fio: rw postfix parsing failed\n"); + free(nr); + return 1; + } + + td->o.ddir_seq_add = val; } + free(nr); return 0; } -- 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