Recent changes (master)
The following changes since commit d9b7596a1fad5adf7f6731d067e1513c56eabe96:
Merge branch 'master' of https://github.com/bvanassche/fio (2020-01-18 09:35:25 -0700)
are available in the Git repository at:
git://git.kernel.dk/fio.git master
for you to fetch changes up to 4ee9c375b64de236356cc97843d84978edeba491:
stat: ensure we align correctly (2020-01-22 19:53:14 -0700)
----------------------------------------------------------------
Jens Axboe (2):
Merge branch 'priorityQueuing' of https://github.com/Seagate/fio
stat: ensure we align correctly
Phillip Chen (2):
Whitespace standardization
Per-command priority: Priority logging and libaio/io_uring cmdprio_percentage
Su, Friendy (1):
engines: add engine for file stat
HOWTO | 43 +++++--- Makefile | 2 +- client.c | 10 +- engines/filecreate.c | 2 +- engines/filestat.c | 116 +++++++++++++++++++++ engines/io_uring.c | 47 +++++++++ engines/libaio.c | 54 ++++++++++ eta.c | 6 +- examples/filestat-ioengine.fio | 19 ++++ fio.1 | 32 ++++-- fio.h | 4 +- init.c | 3 + io_u.c | 8 +- io_u.h | 3 + ioengines.c | 1 + iolog.c | 8 +- iolog.h | 1 + server.c | 13 ++- server.h | 2 +- stat.c | 229 +++++++++++++++++++++++++++++++++++------ stat.h | 14 ++- 21 files changed, 541 insertions(+), 76 deletions(-) create mode 100644 engines/filestat.c create mode 100644 examples/filestat-ioengine.fio
---
Diff of recent changes:
HOWTO +30 -13
@@ -1996,6 +1996,11 @@ I/O engine set `filesize` so that all the accounting still occurs, but no actual I/O will be done other than creating the file. + **filestat** + Simply do stat() and do no I/O to the file. You need to set 'filesize' + and 'nrfiles', so that files will be created. + This engine is to measure file lookup and meta data access. + **libpmem** Read and write using mmap I/O to a file on a filesystem mounted with DAX on a persistent memory device through the PMDK
@@ -2029,21 +2034,29 @@ In addition, there are some parameters which are only valid when a specific with the caveat that when used on the command line, they must come after the :option:`ioengine` that defines them is selected. -.. option:: hipri : [io_uring] +.. option:: cmdprio_percentage=int : [io_uring] [libaio] - If this option is set, fio will attempt to use polled IO completions. - Normal IO completions generate interrupts to signal the completion of - IO, polled completions do not. Hence they are require active reaping - by the application. The benefits are more efficient IO for high IOPS - scenarios, and lower latencies for low queue depth IO. + Set the percentage of I/O that will be issued with higher priority by setting + the priority bit. Non-read I/O is likely unaffected by ``cmdprio_percentage``. + This option cannot be used with the `prio` or `prioclass` options. For this + option to set the priority bit properly, NCQ priority must be supported and + enabled and :option:`direct`\=1 option must be used. .. option:: fixedbufs : [io_uring] - If fio is asked to do direct IO, then Linux will map pages for each - IO call, and release them when IO is done. If this option is set, the - pages are pre-mapped before IO is started. This eliminates the need to - map and release for each IO. This is more efficient, and reduces the - IO latency as well. + If fio is asked to do direct IO, then Linux will map pages for each + IO call, and release them when IO is done. If this option is set, the + pages are pre-mapped before IO is started. This eliminates the need to + map and release for each IO. This is more efficient, and reduces the + IO latency as well. + +.. option:: hipri : [io_uring] + + If this option is set, fio will attempt to use polled IO completions. + Normal IO completions generate interrupts to signal the completion of + IO, polled completions do not. Hence they are require active reaping + by the application. The benefits are more efficient IO for high IOPS + scenarios, and lower latencies for low queue depth IO. .. option:: registerfiles : [io_uring]
@@ -2687,11 +2700,15 @@ Threads, processes and job synchronization Set the I/O priority value of this job. Linux limits us to a positive value between 0 and 7, with 0 being the highest. See man :manpage:`ionice(1)`. Refer to an appropriate manpage for other operating - systems since meaning of priority may differ. + systems since meaning of priority may differ. For per-command priority + setting, see I/O engine specific `cmdprio_percentage` and `hipri_percentage` + options. .. option:: prioclass=int - Set the I/O priority class. See man :manpage:`ionice(1)`. + Set the I/O priority class. See man :manpage:`ionice(1)`. For per-command + priority setting, see I/O engine specific `cmdprio_percentage` and + `hipri_percentage` options. .. option:: cpus_allowed=str
Makefile +1 -1
@@ -45,7 +45,7 @@ SOURCE := $(sort $(patsubst $(SRCDIR)/%,%,$(wildcard $(SRCDIR)/crc/*.c)) \ pshared.c options.c \ smalloc.c filehash.c profile.c debug.c engines/cpu.c \ engines/mmap.c engines/sync.c engines/null.c engines/net.c \ - engines/ftruncate.c engines/filecreate.c \ + engines/ftruncate.c engines/filecreate.c engines/filestat.c \ server.c client.c iolog.c backend.c libfio.c flow.c cconv.c \ gettime-thread.c helpers.c json.c idletime.c td_error.c \ profiles/tiobench.c profiles/act.c io_u_queue.c filelock.c \
client.c +9 -1
@@ -1032,6 +1032,14 @@ static void convert_ts(struct thread_stat *dst, struct thread_stat *src) dst->nr_block_infos =le64_to_cpu (src->nr_block_infos);for (i =0 ; i < dst->nr_block_infos; i++) dst->block_infos[i] =le32_to_cpu (src->block_infos[i]); +for (i =0 ; i <DDIR_RWDIR_CNT ; i++) { +for (j =0 ; j <FIO_IO_U_PLAT_NR ; j++) { + dst->io_u_plat_high_prio[i][j] =le64_to_cpu (src->io_u_plat_high_prio[i][j]); + dst->io_u_plat_prio[i][j] =le64_to_cpu (src->io_u_plat_prio[i][j]); + } +convert_io_stat (&dst->clat_high_prio_stat[i], &src->clat_high_prio_stat[i]); +convert_io_stat (&dst->clat_prio_stat[i], &src->clat_prio_stat[i]); + } dst->ss_dur =le64_to_cpu (src->ss_dur); dst->ss_state =le32_to_cpu (src->ss_state);
@@ -1693,7 +1701,7 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd, s->time =le64_to_cpu (s->time); s->data.val =le64_to_cpu (s->data.val); - s->__ddir =le32_to_cpu (s->__ddir); + s->__ddir =__le32_to_cpu (s->__ddir); s->bs =le64_to_cpu (s->bs);if (ret->log_offset) {
engines/filecreate.c +1 -1
@@ -49,7 +49,7 @@ static int open_file(struct thread_data *td, struct fio_file *f)uint64_t nsec; nsec =ntime_since_now (&start); -add_clat_sample (td, data->stat_ddir, nsec,0 ,0 ); +add_clat_sample (td, data->stat_ddir, nsec,0 ,0 ,0 ); }return 0 ;
engines/filestat.c new file +116 -0
116 lines not on this page · raw message
engines/io_uring.c +47 -0
88 lines not on this page · raw message
engines/libaio.c +54 -0
103 lines not on this page · raw message
eta.c +3 -3
@@ -509,9 +509,9 @@ bool calc_thread_status(struct jobs_eta *je, int force)calc_rate (unified_rw_rep, rate_time, io_bytes, rate_io_bytes, je->rate);memcpy (&rate_prev_time, &now,sizeof (now)); -add_agg_sample (sample_val (je->rate[DDIR_READ ]),DDIR_READ ,0 ); -add_agg_sample (sample_val (je->rate[DDIR_WRITE ]),DDIR_WRITE ,0 ); -add_agg_sample (sample_val (je->rate[DDIR_TRIM ]),DDIR_TRIM ,0 ); +add_agg_sample (sample_val (je->rate[DDIR_READ ]),DDIR_READ ,0 ,0 ); +add_agg_sample (sample_val (je->rate[DDIR_WRITE ]),DDIR_WRITE ,0 ,0 ); +add_agg_sample (sample_val (je->rate[DDIR_TRIM ]),DDIR_TRIM ,0 ,0 ); } disp_time =mtime_since (&disp_prev_time, &now);
examples/filestat-ioengine.fio new file +19 -0
@@ -0,0 +1,19 @@ +# Example filestat job + +# 'filestat' engine only do 'stat(filename)', file will not be open(). +# 'filesize' must be set, then files will be created at setup stage. + +[global] +ioengine=filestat +numjobs=1 +filesize=4k +nrfiles=200 +thread + +[t0] +[t1] +[t2] +[t3] +[t4] +[t5] +
fio.1 +24 -8
@@ -1760,6 +1760,11 @@ Simply create the files and do no I/O to them. You still need to set \fBfilesize\fR so that all the accounting still occurs, but no actual I/O will be done other than creating the file. .TP +.B filestat +Simply do stat() and do no I/O to the file. You need to set 'filesize' +and 'nrfiles', so that files will be created. +This engine is to measure file lookup and meta data access. +.TP .B libpmem Read and write using mmap I/O to a file on a filesystem mounted with DAX on a persistent memory device through the PMDK
@@ -1790,12 +1795,12 @@ In addition, there are some parameters which are only valid when a specific with the caveat that when used on the command line, they must come after the \fBioengine\fR that defines them is selected. .TP -.BI (io_uring)hipri -If this option is set, fio will attempt to use polled IO completions. Normal IO -completions generate interrupts to signal the completion of IO, polled -completions do not. Hence they are require active reaping by the application. -The benefits are more efficient IO for high IOPS scenarios, and lower latencies -for low queue depth IO. +.BI (io_uring, libaio)cmdprio_percentage \fR=\fPint +Set the percentage of I/O that will be issued with higher priority by setting +the priority bit. Non-read I/O is likely unaffected by ``cmdprio_percentage``. +This option cannot be used with the `prio` or `prioclass` options. For this +option to set the priority bit properly, NCQ priority must be supported and +enabled and `direct=1' option must be used. .TP .BI (io_uring)fixedbufs If fio is asked to do direct IO, then Linux will map pages for each IO call, and
@@ -1803,6 +1808,13 @@ release them when IO is done. If this option is set, the pages are pre-mapped before IO is started. This eliminates the need to map and release for each IO. This is more efficient, and reduces the IO latency as well. .TP +.BI (io_uring)hipri +If this option is set, fio will attempt to use polled IO completions. Normal IO +completions generate interrupts to signal the completion of IO, polled +completions do not. Hence they are require active reaping by the application. +The benefits are more efficient IO for high IOPS scenarios, and lower latencies +for low queue depth IO. +.TP .BI (io_uring)registerfiles With this option, fio registers the set of files being used with the kernel. This avoids the overhead of managing file counts in the kernel, making the
@@ -2381,10 +2393,14 @@ priority class. Set the I/O priority value of this job. Linux limits us to a positive value between 0 and 7, with 0 being the highest. See man \fBionice\fR\|(1). Refer to an appropriate manpage for other operating -systems since meaning of priority may differ. +systems since meaning of priority may differ. For per-command priority +setting, see I/O engine specific `cmdprio_percentage` and `hipri_percentage` +options. .TP .BI prioclass \fR=\fPint -Set the I/O priority class. See man \fBionice\fR\|(1). +Set the I/O priority class. See man \fBionice\fR\|(1). For per-command +priority setting, see I/O engine specific `cmdprio_percentage` and `hipri_percent` +options. .TP .BI cpus_allowed \fR=\fPstr Controls the same options as \fBcpumask\fR, but accepts a textual
fio.h +3 -1
@@ -139,6 +139,7 @@ enum {FIO_RAND_ZONE_OFF ,FIO_RAND_POISSON2_OFF ,FIO_RAND_POISSON3_OFF , +FIO_RAND_PRIO_CMDS , FIO_RAND_NR_OFFS, };
@@ -258,6 +259,7 @@ struct thread_data {struct frand_state buf_state_prev;struct frand_state dedupe_state;struct frand_state zone_state; +struct frand_state prio_state;struct zone_split_index **zone_state_index;
@@ -460,7 +462,7 @@ struct thread_data {CUdevice cu_dev;CUcontext cu_ctx;CUdeviceptr dev_mem_ptr; -#endif +#endif };
init.c +3 -0
@@ -1042,6 +1042,7 @@ static void td_fill_rand_seeds_internal(struct thread_data *td, bool use64)init_rand_seed (&td->poisson_state[2 ], td->rand_seeds[FIO_RAND_POISSON3_OFF ],0 );init_rand_seed (&td->dedupe_state, td->rand_seeds[FIO_DEDUPE_OFF ], false);init_rand_seed (&td->zone_state, td->rand_seeds[FIO_RAND_ZONE_OFF ], false); +init_rand_seed (&td->prio_state, td->rand_seeds[FIO_RAND_PRIO_CMDS ], false);if (!td_random (td))return ;
@@ -1518,6 +1519,8 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num, td->ts.lat_stat[i].min_val =ULONG_MAX ; td->ts.bw_stat[i].min_val =ULONG_MAX ; td->ts.iops_stat[i].min_val =ULONG_MAX ; + td->ts.clat_high_prio_stat[i].min_val =ULONG_MAX ; + td->ts.clat_prio_stat[i].min_val =ULONG_MAX ; } td->ts.sync_stat.min_val =ULONG_MAX ; td->ddir_seq_nr = o->ddir_seq_nr;
io_u.c +4 -4
@@ -1541,7 +1541,7 @@ again:assert (io_u->flags &IO_U_F_FREE );io_u_clear (td, io_u,IO_U_F_FREE |IO_U_F_NO_FILE_PUT |IO_U_F_TRIMMED |IO_U_F_BARRIER | -IO_U_F_VER_LIST ); +IO_U_F_VER_LIST |IO_U_F_PRIORITY ); io_u->error =0 ; io_u->acct_ddir =-1 ;
@@ -1830,7 +1830,7 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,unsigned long long tnsec; tnsec =ntime_since (&io_u->start_time, &icd->time); -add_lat_sample (td, idx, tnsec, bytes, io_u->offset); +add_lat_sample (td, idx, tnsec, bytes, io_u->offset,io_u_is_prio (io_u));if (td->flags &TD_F_PROFILE_OPS ) {struct prof_io_ops *ops = &td->prof_io_ops;
@@ -1849,7 +1849,7 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,if (ddir_rw (idx)) {if (!td->o.disable_clat) { -add_clat_sample (td, idx, llnsec, bytes, io_u->offset); +add_clat_sample (td, idx, llnsec, bytes, io_u->offset,io_u_is_prio (io_u));io_u_mark_latency (td, llnsec); }
@@ -2091,7 +2091,7 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u) td = td->parent;add_slat_sample (td, io_u->ddir, slat_time, io_u->xfer_buflen, - io_u->offset); + io_u->offset,io_u_is_prio (io_u)); } }
io_u.h +3 -0
@@ -24,6 +24,7 @@ enum {IO_U_F_TRIMMED =1 <<5 ,IO_U_F_BARRIER =1 <<6 ,IO_U_F_VER_LIST =1 <<7 , + IO_U_F_PRIORITY = 1 << 8, };/*
@@ -193,5 +194,7 @@ static inline enum fio_ddir acct_ddir(struct io_u *io_u) td_flags_clear((td), &(io_u->flags), (val))#define io_u_set (td, io_u, val) \ td_flags_set((td), &(io_u)->flags, (val)) +#define io_u_is_prio (io_u) \ + (io_u->flags & (unsigned int) IO_U_F_PRIORITY) != 0#endif
ioengines.c +1 -0
@@ -318,6 +318,7 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u) sizeof(io_u->issue_time)); } +if (ddir_rw (ddir)) {if (!(io_u->flags &IO_U_F_VER_LIST )) { td->io_issues[ddir]++;
iolog.c +4 -4
@@ -896,18 +896,18 @@ void flush_samples(FILE *f, void *samples, uint64_t sample_size) s =__get_sample (samples, log_offset, i);if (!log_offset) { -fprintf (f,"%lu, %" PRId64", %u, %llu\n" , +fprintf (f,"%lu, %" PRId64", %u, %llu, %u\n" , (unsigned long ) s->time, s->data.val, -io_sample_ddir (s), (unsigned long long ) s->bs); +io_sample_ddir (s), (unsigned long long ) s->bs, s->priority_bit); }else {struct io_sample_offset *so = (void *) s; -fprintf (f,"%lu, %" PRId64", %u, %llu, %llu\n" , +fprintf (f,"%lu, %" PRId64", %u, %llu, %llu, %u\n" , (unsigned long ) s->time, s->data.val,io_sample_ddir (s), (unsigned long long ) s->bs, - (unsigned long long ) so->offset); + (unsigned long long ) so->offset, s->priority_bit); } } }
iolog.h +1 -0
@@ -42,6 +42,7 @@ struct io_sample {uint64_t time;union io_sample_data data;uint32_t __ddir; +uint8_t priority_bit;uint64_t bs; };
server.c +11 -2
@@ -1262,7 +1262,7 @@ static int handle_connection(struct sk_out *sk_out)_exit (ret); } -/* get the address on this host bound by the input socket, +/* get the address on this host bound by the input socket, * whether it is ipv6 or ipv4 */ static int get_my_addr_str (int sk)
@@ -1574,6 +1574,15 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) p.ts.cachehit =cpu_to_le64 (ts->cachehit); p.ts.cachemiss =cpu_to_le64 (ts->cachemiss); +for (i =0 ; i <DDIR_RWDIR_CNT ; i++) { +for (j =0 ; j <FIO_IO_U_PLAT_NR ; j++) { + p.ts.io_u_plat_high_prio[i][j] =cpu_to_le64 (ts->io_u_plat_high_prio[i][j]); + p.ts.io_u_plat_prio[i][j] =cpu_to_le64 (ts->io_u_plat_prio[i][j]); + } +convert_io_stat (&p.ts.clat_high_prio_stat[i], &ts->clat_high_prio_stat[i]); +convert_io_stat (&p.ts.clat_prio_stat[i], &ts->clat_prio_stat[i]); + } +convert_gs (&p.rs, rs);dprint (FD_NET ,"ts->ss_state = %d\n" , ts->ss_state);
@@ -1998,7 +2007,7 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) s->time =cpu_to_le64 (s->time); s->data.val =cpu_to_le64 (s->data.val); - s->__ddir =cpu_to_le32 (s->__ddir); + s->__ddir =__cpu_to_le32 (s->__ddir); s->bs =cpu_to_le64 (s->bs);if (log->log_offset) {
server.h +1 -1
@@ -48,7 +48,7 @@ struct fio_net_cmd_reply { };enum { -FIO_SERVER_VER =80 , +FIO_SERVER_VER =81 ,FIO_SERVER_MAX_FRAGMENT_PDU =1024 ,FIO_SERVER_MAX_CMD_MB =2048 ,
stat.c +196 -33
444 lines not on this page · raw message
stat.h +10 -4
@@ -239,6 +239,11 @@ struct thread_stat {fio_fp64_t ss_deviation;fio_fp64_t ss_criterion; + uint64_t io_u_plat_high_prio[DDIR_RWDIR_CNT][FIO_IO_U_PLAT_NR] __attribute__((aligned(8)));; +uint64_t io_u_plat_prio[DDIR_RWDIR_CNT ][FIO_IO_U_PLAT_NR ]; + struct io_stat clat_high_prio_stat[DDIR_RWDIR_CNT] __attribute__((aligned(8))); +struct io_stat clat_prio_stat[DDIR_RWDIR_CNT ]; +union {uint64_t *ss_iops_data;uint64_t pad4;
@@ -323,12 +328,13 @@ extern void update_rusage_stat(struct thread_data *);extern void clear_rusage_stat (struct thread_data *);extern void add_lat_sample (struct thread_data *,enum fio_ddir ,unsigned long long , -unsigned long long ,uint64_t ); +unsigned long long ,uint64_t ,uint8_t );extern void add_clat_sample (struct thread_data *,enum fio_ddir ,unsigned long long , -unsigned long long ,uint64_t ); +unsigned long long ,uint64_t ,uint8_t );extern void add_slat_sample (struct thread_data *,enum fio_ddir ,unsigned long , -unsigned long long ,uint64_t ); -extern void add_agg_sample (union io_sample_data ,enum fio_ddir ,unsigned long long ); +unsigned long long ,uint64_t ,uint8_t ); +extern void add_agg_sample (union io_sample_data ,enum fio_ddir ,unsigned long long bs, +uint8_t priority_bit);extern void add_iops_sample (struct thread_data *,struct io_u *,unsigned int ); extern void add_bw_sample(struct thread_data *, struct io_u *,