On Mon, Feb 10, 2014 at 2:14 PM, Jens Axboe <axboe@xxxxxxxxx> wrote: > On Sun, Feb 09 2014, Matthew Eaton wrote: >> On Sun, Feb 9, 2014 at 12:57 PM, Jens Axboe <axboe@xxxxxxxxx> wrote: >> > On Sat, Feb 08 2014, Matthew Eaton wrote: >> >> On Thu, Feb 6, 2014 at 11:21 AM, Jens Axboe <axboe@xxxxxxxxx> wrote: >> >> > Hi, >> >> > >> >> > I've been late on this release, originally wanted it out around >> >> > Christmas. But various issues here and there prevented that. However, I >> >> > now think we are getting pretty close. It'd be great if folks running on >> >> > non-linux systems could compile and ensure that everything is in working >> >> > order, because otherwise I'm going to assume that it is... >> >> > >> >> > Similarly, if you know of bugs (particularly regressions from previous >> >> > releases), speak up now so we can get them fixed before 2.1.5 is cut. >> >> > >> >> > I'll wait until Monday to tag the release. >> >> > >> >> > -- >> >> > Jens Axboe >> >> > >> >> >> >> Hi Jens, >> >> >> >> I was messing around with the openfiles flag in one of my job files >> >> last week but was unable to get it to work. Fio would keep defaulting >> >> to opening all files set by nrfiles, but I'm not sure if I was doing >> >> something wrong. This was with fio 2.1.4 on linux. Can you check on >> >> this? >> > >> > It'd be easier if you include your job file / command line! >> > >> > -- >> > Jens Axboe >> > >> >> Hi Jens, >> >> Here's an example. In fio output I get f=50 instead of f=10 which I >> believe is the number of simultaneous opens? Also strange to me is >> that write io is 2000 MB instead of 1024 MB. >> >> [job] >> bs=1m >> rw=write >> size=1g >> nrfiles=50 >> openfiles=10 >> directory=temp >> >> job: (g=0): rw=write, bs=1M-1M/1M-1M/1M-1M, ioengine=sync, iodepth=1 >> fio-2.1.4 >> Starting 1 process >> job: Laying out IO file(s) (50 file(s) / 1023MB) >> Jobs: 1 (f=50): [W] [-.-% done] [0KB/539.0MB/0KB /s] [0/539/0 iops] >> [eta 00m:00s] >> job: (groupid=0, jobs=1): err= 0: pid=15131: Sun Feb 9 16:18:55 2014 >> write: io=2000.0MB, bw=697785KB/s, iops=681, runt= 2935msec >> clat (usec): min=167, max=145348, avg=1399.89, stdev=6030.76 >> lat (usec): min=175, max=145359, avg=1413.43, stdev=6031.10 >> clat percentiles (usec): >> | 1.00th=[ 175], 5.00th=[ 207], 10.00th=[ 253], 20.00th=[ 262], >> | 30.00th=[ 274], 40.00th=[ 290], 50.00th=[ 302], 60.00th=[ 358], >> | 70.00th=[ 516], 80.00th=[ 572], 90.00th=[ 5984], 95.00th=[ 6624], >> | 99.00th=[ 7328], 99.50th=[10816], 99.90th=[115200], 99.95th=[140288], >> | 99.99th=[144384] >> bw (KB /s): min=81160, max=1503620, per=100.00%, avg=778889.75, >> stdev=604179.56 >> lat (usec) : 250=7.50%, 500=61.95%, 750=18.25% >> lat (msec) : 10=11.70%, 20=0.20%, 50=0.15%, 100=0.10%, 250=0.15% >> cpu : usr=2.97%, sys=25.70%, ctx=504, majf=0, minf=33 >> IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% >> submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% >> complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% >> issued : total=r=0/w=2000/d=0, short=r=0/w=0/d=0 >> >> Run status group 0 (all jobs): >> WRITE: io=2000.0MB, aggrb=697785KB/s, minb=697785KB/s, >> maxb=697785KB/s, mint=2935msec, maxt=2935msec >> >> Disk stats (read/write): >> sdb: ios=0/2740, merge=0/2, ticks=0/360280, in_queue=376924, util=90.05% > > Can you try this patch? > > > diff --git a/backend.c b/backend.c > index a607134..32bc265 100644 > --- a/backend.c > +++ b/backend.c > @@ -52,6 +52,7 @@ > #include "server.h" > #include "lib/getrusage.h" > #include "idletime.h" > +#include "err.h" > > static pthread_t disk_util_thread; > static struct fio_mutex *disk_thread_mutex; > @@ -478,6 +479,12 @@ static void do_verify(struct thread_data *td, uint64_t verify_bytes) > break; > > while ((io_u = get_io_u(td)) != NULL) { > + if (IS_ERR(io_u)) { > + io_u = NULL; > + ret = FIO_Q_BUSY; > + goto reap; > + } > + > /* > * We are only interested in the places where > * we wrote or trimmed IOs. Turn those into > @@ -574,6 +581,7 @@ sync_done: > * completed io_u's first. Note that we can get BUSY even > * without IO queued, if the system is resource starved. > */ > +reap: > full = queue_full(td) || (ret == FIO_Q_BUSY && td->cur_depth); > if (full || !td->o.iodepth_batch_complete) { > min_events = min(td->o.iodepth_batch_complete, > @@ -692,7 +700,14 @@ static uint64_t do_io(struct thread_data *td) > break; > > io_u = get_io_u(td); > - if (!io_u) { > + if (IS_ERR_OR_NULL(io_u)) { > + int err = PTR_ERR(io_u); > + > + io_u = NULL; > + if (err == -EBUSY) { > + ret = FIO_Q_BUSY; > + goto reap; > + } > if (td->o.latency_target) > goto reap; > break; > @@ -1124,6 +1139,9 @@ static int keep_running(struct thread_data *td) > if (diff < td_max_bs(td)) > return 0; > > + if (fio_files_done(td)) > + return 0; > + > return 1; > } > > diff --git a/err.h b/err.h > new file mode 100644 > index 0000000..5c024ee > --- /dev/null > +++ b/err.h > @@ -0,0 +1,44 @@ > +#ifndef FIO_ERR_H > +#define FIO_ERR_H > + > +/* > + * Kernel pointers have redundant information, so we can use a > + * scheme where we can return either an error code or a dentry > + * pointer with the same return value. > + * > + * This should be a per-architecture thing, to allow different > + * error and pointer decisions. > + */ > +#define MAX_ERRNO 4095 > + > +#define IS_ERR_VALUE(x) ((x) >= (unsigned long)-MAX_ERRNO) > + > +static inline void *ERR_PTR(long error) > +{ > + return (void *) error; > +} > + > +static inline long PTR_ERR(const void *ptr) > +{ > + return (long) ptr; > +} > + > +static inline long IS_ERR(const void *ptr) > +{ > + return IS_ERR_VALUE((unsigned long)ptr); > +} > + > +static inline long IS_ERR_OR_NULL(const void *ptr) > +{ > + return !ptr || IS_ERR_VALUE((unsigned long)ptr); > +} > + > +static inline int PTR_ERR_OR_ZERO(const void *ptr) > +{ > + if (IS_ERR(ptr)) > + return PTR_ERR(ptr); > + else > + return 0; > +} > + > +#endif > diff --git a/file.h b/file.h > index d7e05f4..19413fc 100644 > --- a/file.h > +++ b/file.h > @@ -176,5 +176,6 @@ extern void dup_files(struct thread_data *, struct thread_data *); > extern int get_fileno(struct thread_data *, const char *); > extern void free_release_files(struct thread_data *); > void fio_file_reset(struct thread_data *, struct fio_file *); > +int fio_files_done(struct thread_data *); > > #endif > diff --git a/filesetup.c b/filesetup.c > index d1702e2..975579a 100644 > --- a/filesetup.c > +++ b/filesetup.c > @@ -639,7 +639,7 @@ static int get_file_sizes(struct thread_data *td) > } > > if (f->real_file_size == -1ULL && td->o.size) > - f->real_file_size = td->o.size / td->o.nr_files; > + f->real_file_size = (td->o.size + td_min_bs(td) - 1) / td->o.nr_files; > } > > return err; > @@ -801,7 +801,7 @@ int setup_files(struct thread_data *td) > * total size divided by number of files. if that is > * zero, set it to the real file size. > */ > - f->io_size = o->size / o->nr_files; > + f->io_size = (o->size + td_min_bs(td) - 1) / o->nr_files; > if (!f->io_size) > f->io_size = f->real_file_size - f->file_offset; > } else if (f->real_file_size < o->file_size_low || > @@ -1386,3 +1386,15 @@ void fio_file_reset(struct thread_data *td, struct fio_file *f) > if (td->o.random_generator == FIO_RAND_GEN_LFSR) > lfsr_reset(&f->lfsr, td->rand_seeds[FIO_RAND_BLOCK_OFF]); > } > + > +int fio_files_done(struct thread_data *td) > +{ > + struct fio_file *f; > + unsigned int i; > + > + for_each_file(td, f, i) > + if (!fio_file_done(f)) > + return 0; > + > + return 1; > +} > diff --git a/io_u.c b/io_u.c > index 64ff73c..acc1a7b 100644 > --- a/io_u.c > +++ b/io_u.c > @@ -11,6 +11,7 @@ > #include "trim.h" > #include "lib/rand.h" > #include "lib/axmap.h" > +#include "err.h" > > struct io_completion_data { > int nr; /* input */ > @@ -985,6 +986,9 @@ static struct fio_file *get_next_file_rand(struct thread_data *td, > if (!fio_file_open(f)) { > int err; > > + if (td->nr_open_files >= td->o.open_files) > + return ERR_PTR(-EBUSY); > + > err = td_io_open_file(td, f); > if (err) > continue; > @@ -1027,6 +1031,9 @@ static struct fio_file *get_next_file_rr(struct thread_data *td, int goodf, > if (!fio_file_open(f)) { > int err; > > + if (td->nr_open_files >= td->o.open_files) > + return ERR_PTR(-EBUSY); > + > err = td_io_open_file(td, f); > if (err) { > dprint(FD_FILE, "error %d on open of %s\n", > @@ -1080,6 +1087,9 @@ static struct fio_file *__get_next_file(struct thread_data *td) > else > f = get_next_file_rand(td, FIO_FILE_open, FIO_FILE_closing); > > + if (IS_ERR(f)) > + return f; > + > td->file_service_file = f; > td->file_service_left = td->file_service_nr - 1; > out: > @@ -1099,14 +1109,14 @@ static struct fio_file *get_next_file(struct thread_data *td) > return __get_next_file(td); > } > > -static int set_io_u_file(struct thread_data *td, struct io_u *io_u) > +static long set_io_u_file(struct thread_data *td, struct io_u *io_u) > { > struct fio_file *f; > > do { > f = get_next_file(td); > - if (!f) > - return 1; > + if (IS_ERR_OR_NULL(f)) > + return PTR_ERR(f); > > io_u->file = f; > get_file(f); > @@ -1400,6 +1410,7 @@ struct io_u *get_io_u(struct thread_data *td) > struct fio_file *f; > struct io_u *io_u; > int do_scramble = 0; > + long ret = 0; > > io_u = __get_io_u(td); > if (!io_u) { > @@ -1425,11 +1436,17 @@ struct io_u *get_io_u(struct thread_data *td) > if (read_iolog_get(td, io_u)) > goto err_put; > } else if (set_io_u_file(td, io_u)) { > + ret = -EBUSY; > dprint(FD_IO, "io_u %p, setting file failed\n", io_u); > goto err_put; > } > > f = io_u->file; > + if (!f) { > + dprint(FD_IO, "io_u %p, setting file failed\n", io_u); > + goto err_put; > + } > + > assert(fio_file_open(f)); > > if (ddir_rw(io_u->ddir)) { > @@ -1478,7 +1495,7 @@ out: > err_put: > dprint(FD_IO, "get_io_u failed\n"); > put_io_u(td, io_u); > - return NULL; > + return ERR_PTR(ret); > } > > void io_u_log_error(struct thread_data *td, struct io_u *io_u) > > -- > Jens Axboe > To be honest I'm not sure how to apply a patch. Thus far I have only used release versions of fio. Do I need to get fio from git, apply the patch, and then compile? -- 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