The following changes since commit 76cd9378b90dddf2cedc9a5d49f317aaad485b90: Get rid of warning on platforms for casting char -> int (2011-07-08 21:14:57 +0200) are available in the git repository at: git://git.kernel.dk/fio.git master Bruce Cran (2): Fix integer overflow in calculating large IOPS on 32-bit platforms Improve Windows windowsaio engine performance Jens Axboe (5): Make processes work on HP-UX A few HP-UX fixes Add note saying that HP-UX should work HP-UX typo posixaio: fix for HP-UX Makefile | 23 ++++++------ README | 8 ++-- engines/net.c | 8 ++++ engines/posixaio.c | 1 + engines/windowsaio.c | 91 ++++++++++++++------------------------------------ fio.c | 7 ++++ os/os-hpux.h | 10 +++++ stat.c | 2 +- 8 files changed, 68 insertions(+), 82 deletions(-) --- Diff of recent changes: diff --git a/Makefile b/Makefile index dade0ae..6626f1f 100644 --- a/Makefile +++ b/Makefile @@ -13,49 +13,50 @@ SOURCE = gettime.c fio.c ioengines.c init.c stat.c log.c time.c filesetup.c \ eta.c verify.c memory.c io_u.c parse.c mutex.c options.c \ rbtree.c smalloc.c filehash.c profile.c debug.c lib/rand.c \ lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \ - engines/mmap.c engines/sync.c engines/null.c memalign.c + engines/mmap.c engines/sync.c engines/null.c engines/net.c \ + memalign.c ifeq ($(UNAME), Linux) SOURCE += diskutil.c fifo.c blktrace.c helpers.c cgroup.c trim.c \ engines/libaio.c engines/posixaio.c engines/sg.c \ engines/splice.c engines/syslet-rw.c engines/guasi.c \ - engines/binject.c profiles/tiobench.c engines/net.c + engines/binject.c profiles/tiobench.c LIBS += -lpthread -ldl -lrt -laio CFLAGS += -rdynamic endif ifeq ($(UNAME), SunOS) SOURCE += fifo.c lib/strsep.c helpers.c engines/posixaio.c \ - engines/solarisaio.c engines/net.c + engines/solarisaio.c LIBS += -lpthread -ldl -laio -lrt -lnsl -lsocket CPPFLAGS += -D__EXTENSIONS__ endif ifeq ($(UNAME), FreeBSD) - SOURCE += helpers.c engines/posixaio.c engines/net.c + SOURCE += helpers.c engines/posixaio.c LIBS += -lpthread -lrt CFLAGS += -rdynamic endif ifeq ($(UNAME), NetBSD) - SOURCE += helpers.c engines/posixaio.c engines/net.c + SOURCE += helpers.c engines/posixaio.c LIBS += -lpthread -lrt CFLAGS += -rdynamic endif ifeq ($(UNAME), AIX) - SOURCE += fifo.c helpers.c lib/getopt_long.c engines/posixaio.c engines/net.c + SOURCE += fifo.c helpers.c lib/getopt_long.c engines/posixaio.c LIBS += -lpthread -ldl -lrt CFLAGS += -rdynamic CPPFLAGS += -D_LARGE_FILES -D__ppc__ endif ifeq ($(UNAME), HP-UX) - SOURCE += fifo.c helpers.c lib/getopt_long.c lib/strsep.c - LIBS += -lpthread -dl -lrt - CPPFLAGS += -D_LARGE_FILES + SOURCE += fifo.c helpers.c lib/getopt_long.c lib/strsep.c engines/posixaio.c + LIBS += -lpthread -ldl -lrt + CFLAGS += -D_LARGEFILE64_SOURCE endif ifeq ($(UNAME), Darwin) - SOURCE += helpers.c engines/posixaio.c engines/net.c + SOURCE += helpers.c engines/posixaio.c LIBS += -lpthread -ldl endif ifneq (,$(findstring CYGWIN,$(UNAME))) - SOURCE += engines/windowsaio.c engines/net.c + SOURCE += engines/windowsaio.c LIBS += -lpthread -lrt endif diff --git a/README b/README index 08b4df6..163ee38 100644 --- a/README +++ b/README @@ -317,10 +317,10 @@ The job file parameters are: Platforms --------- -Fio works on (at least) Linux, Solaris, AIX, OSX, NetBSD, Windows and FreeBSD. -Some features and/or options may only be available on some of the platforms, -typically because those features only apply to that platform (like the -solarisaio engine, or the splice engine on Linux). +Fio works on (at least) Linux, Solaris, AIX, HP-UX, OSX, NetBSD, Windows +and FreeBSD. Some features and/or options may only be available on some of +the platforms, typically because those features only apply to that platform +(like the solarisaio engine, or the splice engine on Linux). Some features are not available on FreeBSD/Solaris even if they could be implemented, I'd be happy to take patches for that. An example of that is diff --git a/engines/net.c b/engines/net.c index b594e0a..6866ba2 100644 --- a/engines/net.c +++ b/engines/net.c @@ -280,7 +280,11 @@ static int fio_netio_recv(struct thread_data *td, struct io_u *io_u) do { if (nd->net_protocol == IPPROTO_UDP) { +#ifdef __hpux + int len = sizeof(nd->addr); +#else socklen_t len = sizeof(nd->addr); +#endif struct sockaddr *from = (struct sockaddr *) &nd->addr; ret = recvfrom(io_u->file->fd, io_u->xfer_buf, @@ -377,7 +381,11 @@ static int fio_netio_connect(struct thread_data *td, struct fio_file *f) static int fio_netio_accept(struct thread_data *td, struct fio_file *f) { struct netio_data *nd = td->io_ops->data; +#ifdef __hpux + int socklen = sizeof(nd->addr); +#else socklen_t socklen = sizeof(nd->addr); +#endif if (nd->net_protocol == IPPROTO_UDP) { f->fd = nd->listenfd; diff --git a/engines/posixaio.c b/engines/posixaio.c index a84eb77..e315e97 100644 --- a/engines/posixaio.c +++ b/engines/posixaio.c @@ -72,6 +72,7 @@ static int fio_posixaio_prep(struct thread_data fio_unused *td, aiocb->aio_buf = io_u->xfer_buf; aiocb->aio_nbytes = io_u->xfer_buflen; aiocb->aio_offset = io_u->offset; + aiocb->aio_sigevent.sigev_notify = SIGEV_NONE; io_u->seen = 0; return 0; diff --git a/engines/windowsaio.c b/engines/windowsaio.c index 299acc4..78f7382 100644 --- a/engines/windowsaio.c +++ b/engines/windowsaio.c @@ -28,7 +28,6 @@ struct windowsaio_data { HANDLE iocomplete_event; CANCELIOEX pCancelIoEx; BOOL iothread_running; - BOOL use_iocp; }; struct thread_ctx { @@ -36,7 +35,6 @@ struct thread_ctx { struct windowsaio_data *wd; }; -static void PrintError(LPCSTR lpszFunction); static int fio_windowsaio_cancel(struct thread_data *td, struct io_u *io_u); static BOOL timeout_expired(DWORD start_count, DWORD end_count); @@ -58,27 +56,6 @@ int sync_file_range(int fd, off64_t offset, off64_t nbytes, return -1; } -static void PrintError(LPCSTR lpszFunction) -{ - // Retrieve the system error message for the last-error code - - LPSTR lpMsgBuf; - DWORD dw = GetLastError(); - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf, - 0, NULL ); - - log_err("%s - %s", lpszFunction, lpMsgBuf); - LocalFree(lpMsgBuf); -} - static int fio_windowsaio_init(struct thread_data *td) { struct windowsaio_data *wd; @@ -125,7 +102,6 @@ static int fio_windowsaio_init(struct thread_data *td) } if (rc) { - PrintError(__func__); if (wd != NULL) { if (wd->ovls != NULL) free(wd->ovls); @@ -140,7 +116,7 @@ static int fio_windowsaio_init(struct thread_data *td) wd->pCancelIoEx = GetProcAddress(hKernel32Dll, "CancelIoEx"); td->io_ops->data = wd; - return 0; + return rc; } static void fio_windowsaio_cleanup(struct thread_data *td) @@ -174,7 +150,7 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) { int rc = 0; HANDLE hFile; - DWORD flags = FILE_FLAG_POSIX_SEMANTICS; + DWORD flags = FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_OVERLAPPED; DWORD sharemode = FILE_SHARE_READ | FILE_SHARE_WRITE; DWORD openmode = OPEN_ALWAYS; DWORD access; @@ -191,15 +167,11 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) return 1; } - if (!td->o.odirect && !td->o.sync_io && td->io_ops->data != NULL) - flags |= FILE_FLAG_OVERLAPPED; - if (td->o.odirect) flags |= FILE_FLAG_NO_BUFFERING; if (td->o.sync_io) flags |= FILE_FLAG_WRITE_THROUGH; - if (td->o.td_ddir == TD_DDIR_READ || td->o.td_ddir == TD_DDIR_WRITE) flags |= FILE_FLAG_SEQUENTIAL_SCAN; @@ -219,25 +191,18 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) f->hFile = CreateFile(f->file_name, access, sharemode, NULL, openmode, flags, NULL); - if (f->hFile == INVALID_HANDLE_VALUE) { - PrintError(__func__); + if (f->hFile == INVALID_HANDLE_VALUE) rc = 1; - } /* Only set up the competion port and thread if we're not just * querying the device size */ - if (!rc && td->io_ops->data != NULL && !td->o.odirect && !td->o.sync_io) { + if (!rc && td->io_ops->data != NULL) { struct thread_ctx *ctx; struct windowsaio_data *wd; hFile = CreateIoCompletionPort(f->hFile, NULL, 0, 0); wd = td->io_ops->data; - if (!td->o.odirect && !td->o.sync_io) - wd->use_iocp = 1; - else - wd->use_iocp = 0; - wd->iothread_running = TRUE; if (!rc) { @@ -248,10 +213,8 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) wd->iothread = CreateThread(NULL, 0, IoCompletionRoutine, ctx, 0, NULL); } - if (rc || wd->iothread == NULL) { - PrintError(__func__); + if (rc || wd->iothread == NULL) rc = 1; - } } return rc; @@ -259,15 +222,17 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) static int fio_windowsaio_close_file(struct thread_data fio_unused *td, struct fio_file *f) { + int rc = 0; + dprint(FD_FILE, "fd close %s\n", f->file_name); if (f->hFile != INVALID_HANDLE_VALUE) { if (!CloseHandle(f->hFile)) - PrintError(__func__); + rc = 1; } f->hFile = INVALID_HANDLE_VALUE; - return 0; + return rc; } static BOOL timeout_expired(DWORD start_count, DWORD end_count) @@ -353,26 +318,24 @@ static int fio_windowsaio_queue(struct thread_data *td, wd = td->io_ops->data; - if (wd->use_iocp) { - for (index = 0; index < td->o.iodepth; index++) { - if (wd->ovls[index].io_free) { - wd->ovls[index].io_free = FALSE; - ResetEvent(wd->ovls[index].o.hEvent); - break; - } + for (index = 0; index < td->o.iodepth; index++) { + if (wd->ovls[index].io_free) { + wd->ovls[index].io_free = FALSE; + ResetEvent(wd->ovls[index].o.hEvent); + break; } + } - assert(index < td->o.iodepth); + assert(index < td->o.iodepth); - lpOvl = &wd->ovls[index].o; - wd->ovls[index].io_u = io_u; - lpOvl->Internal = STATUS_PENDING; - lpOvl->InternalHigh = 0; - lpOvl->Offset = io_u->offset & 0xFFFFFFFF; - lpOvl->OffsetHigh = io_u->offset >> 32; - lpOvl->Pointer = NULL; - io_u->engine_data = &wd->ovls[index]; - } + lpOvl = &wd->ovls[index].o; + wd->ovls[index].io_u = io_u; + lpOvl->Internal = STATUS_PENDING; + lpOvl->InternalHigh = 0; + lpOvl->Offset = io_u->offset & 0xFFFFFFFF; + lpOvl->OffsetHigh = io_u->offset >> 32; + lpOvl->Pointer = NULL; + io_u->engine_data = &wd->ovls[index]; switch (io_u->ddir) { case DDIR_WRITE: @@ -400,13 +363,9 @@ static int fio_windowsaio_queue(struct thread_data *td, assert(0); } - if (wd->use_iocp && (success || GetLastError() == ERROR_IO_PENDING)) { + if (success || GetLastError() == ERROR_IO_PENDING) { rc = FIO_Q_QUEUED; - } else if (success && !wd->use_iocp) { - io_u->resid = io_u->xfer_buflen - iobytes; - io_u->error = 0; } else { - PrintError(__func__); io_u->error = GetLastError(); io_u->resid = io_u->xfer_buflen; } diff --git a/fio.c b/fio.c index 8185481..a8608f4 100644 --- a/fio.c +++ b/fio.c @@ -1294,6 +1294,7 @@ static int fork_main(int shmid, int offset) struct thread_data *td; void *data, *ret; +#ifndef __hpux data = shmat(shmid, NULL, 0); if (data == (void *) -1) { int __err = errno; @@ -1301,6 +1302,12 @@ static int fork_main(int shmid, int offset) perror("shmat"); return __err; } +#else + /* + * HP-UX inherits shm mappings? + */ + data = threads; +#endif td = data + offset * sizeof(struct thread_data); ret = thread_main(td); diff --git a/os/os-hpux.h b/os/os-hpux.h index 3c90841..38a1441 100644 --- a/os/os-hpux.h +++ b/os/os-hpux.h @@ -9,6 +9,8 @@ #include <sys/mman.h> #include <sys/mpctl.h> #include <sys/scsi.h> +#include <time.h> +#include <aio.h> #include "../file.h" @@ -27,6 +29,14 @@ #define POSIX_MADV_RANDOM MADV_RANDOM #define posix_madvise(ptr, sz, hint) madvise((ptr), (sz), (hint)) +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC CLOCK_REALTIME +#endif + +#ifndef MSG_WAITALL +#define MSG_WAITALL 0x40 +#endif + static inline int blockdev_invalidate_cache(struct fio_file *f) { return EINVAL; diff --git a/stat.c b/stat.c index d95be75..9f22c6e 100644 --- a/stat.c +++ b/stat.c @@ -169,7 +169,7 @@ static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts, io_p = num2str(ts->io_bytes[ddir], 6, 1, i2p); bw_p = num2str(bw, 6, 1, i2p); - iops = (1000 * ts->total_io_u[ddir]) / runt; + iops = (1000 * (uint64_t)ts->total_io_u[ddir]) / runt; iops_p = num2str(iops, 6, 1, 0); log_info(" %s: io=%sB, bw=%sB/s, iops=%s, runt=%6llumsec\n", -- 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