From: Jens Axboe Date: Fri, 3 Jul 2009 20:52:38 +0000 (+0200) Subject: mmap engine: allow full mmaps for 64-bit machines X-Git-Tag: fio-1.31~11 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=ed47cbf7063df84343cd79fdc64eb7bbf7d6df2a;p=fio.git mmap engine: allow full mmaps for 64-bit machines No need to do partial mmaps there. Signed-off-by: Jens Axboe --- diff --git a/engines/mmap.c b/engines/mmap.c index bd9a9428..71abfb9a 100644 --- a/engines/mmap.c +++ b/engines/mmap.c @@ -26,7 +26,6 @@ static int fio_mmap_file(struct thread_data *td, struct fio_file *f, size_t length, off_t off) { int flags = 0; - int ret = 0; if (td_rw(td)) flags = PROT_READ | PROT_WRITE; @@ -40,10 +39,8 @@ static int fio_mmap_file(struct thread_data *td, struct fio_file *f, f->mmap_ptr = mmap(NULL, length, flags, MAP_SHARED, f->fd, off); if (f->mmap_ptr == MAP_FAILED) { - int err = errno; - f->mmap_ptr = NULL; - td_verror(td, err, "mmap"); + td_verror(td, errno, "mmap"); goto err; } @@ -60,29 +57,27 @@ static int fio_mmap_file(struct thread_data *td, struct fio_file *f, } err: - return ret; + if (td->error && f->mmap_ptr) + munmap(f->mmap_ptr, length); + + return td->error; } -static int fio_mmapio_prep(struct thread_data *td, struct io_u *io_u) +/* + * Just mmap an appropriate portion, we cannot mmap the full extent + */ +static int fio_mmapio_prep_limited(struct thread_data *td, struct io_u *io_u) { struct fio_file *f = io_u->file; - int ret = 0; if (io_u->buflen > mmap_map_size) { log_err("fio: bs too big for mmap engine\n"); - ret = EIO; - goto err; + return EIO; } - if (io_u->offset >= f->mmap_off && - io_u->offset + io_u->buflen < f->mmap_off + f->mmap_sz) - goto done; - if (f->mmap_ptr) { - if (munmap(f->mmap_ptr, f->mmap_sz) < 0) { - ret = errno; - goto err; - } + if (munmap(f->mmap_ptr, f->mmap_sz) < 0) + return errno; f->mmap_ptr = NULL; } @@ -92,15 +87,58 @@ static int fio_mmapio_prep(struct thread_data *td, struct io_u *io_u) f->mmap_off = io_u->offset; + return fio_mmap_file(td, f, f->mmap_sz, f->mmap_off); +} + +/* + * Attempt to mmap the entire file + */ +static int fio_mmapio_prep_full(struct thread_data *td, struct io_u *io_u) +{ + struct fio_file *f = io_u->file; + int ret; + + if (fio_file_partial_mmap(f)) + return EINVAL; + + if (f->mmap_ptr) { + if (munmap(f->mmap_ptr, f->mmap_sz) < 0) + return errno; + f->mmap_ptr = NULL; + } + + f->mmap_sz = f->io_size; + f->mmap_off = 0; + ret = fio_mmap_file(td, f, f->mmap_sz, f->mmap_off); -done: - if (!ret) - io_u->mmap_data = f->mmap_ptr + io_u->offset - f->mmap_off - - f->file_offset; -err: + if (ret) + fio_file_set_partial_mmap(f); + return ret; } +static int fio_mmapio_prep(struct thread_data *td, struct io_u *io_u) +{ + struct fio_file *f = io_u->file; + int ret; + + if (io_u->offset >= f->mmap_off && + io_u->offset + io_u->buflen < f->mmap_off + f->mmap_sz) + goto done; + + if (fio_mmapio_prep_full(td, io_u)) { + td_clear_error(td); + ret = fio_mmapio_prep_limited(td, io_u); + if (ret) + return ret; + } + +done: + io_u->mmap_data = f->mmap_ptr + io_u->offset - f->mmap_off - + f->file_offset; + return 0; +} + static int fio_mmapio_queue(struct thread_data *td, struct io_u *io_u) { struct fio_file *f = io_u->file; diff --git a/file.h b/file.h index 7024d5ee..6aa5b502 100644 --- a/file.h +++ b/file.h @@ -20,6 +20,7 @@ enum fio_file_flags { FIO_FILE_done = 1 << 3, /* io completed to this file */ FIO_FILE_size_known = 1 << 4, /* size has been set */ FIO_FILE_hashed = 1 << 5, /* file is on hash */ + FIO_FILE_partial_mmap = 1 << 6, /* can't do full mmap */ }; enum file_lock_mode { @@ -114,6 +115,7 @@ FILE_FLAG_FNS(extend); FILE_FLAG_FNS(done); FILE_FLAG_FNS(size_known); FILE_FLAG_FNS(hashed); +FILE_FLAG_FNS(partial_mmap); #undef FILE_FLAG_FNS /*