The following changes since commit 304a47c7d94f407cc72a87025679a67f02288447: Reduce thread stack size (2010-08-01 21:31:26 +0200) are available in the git repository at: git://git.kernel.dk/fio.git master Cigy Cyriac (4): Add get_cpu_clock() for powerpc Fix bad casting of unsigned long long to unsigned long Not all platforms have MSG_DONTWAIT Add support for AIX Jens Axboe (2): Add comment as to where getopt_long.c came from AIX fixups Makefile.aix | 73 +++++++++++++++++++++++++ README | 23 ++++++++- arch/arch-ppc.h | 17 ++++++ engines/net.c | 14 ++++- fio.h | 2 +- init.c | 3 +- lib/getopt.h | 26 +++++++++ lib/getopt_long.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++ options.c | 17 +++--- os/os-aix.h | 45 +++++++++++++++ os/os.h | 2 + 11 files changed, 363 insertions(+), 14 deletions(-) create mode 100644 Makefile.aix create mode 100644 lib/getopt.h create mode 100644 lib/getopt_long.c create mode 100644 os/os-aix.h --- Diff of recent changes: diff --git a/Makefile.aix b/Makefile.aix new file mode 100644 index 0000000..83b5cf4 --- /dev/null +++ b/Makefile.aix @@ -0,0 +1,73 @@ +CC = gcc +DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG +OPTFLAGS= -O2 -g $(EXTFLAGS) +CFLAGS = -Wwrite-strings -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(DEBUGFLAGS) -fno-omit-frame-pointer -D_LARGE_FILES -D__ppc__ +PROGS = fio +SCRIPTS = fio_generate_plots +OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ + eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \ + rbtree.o fifo.o smalloc.o filehash.o helpers.o \ + profile.o debug.o + +OBJS += lib/rand.o +OBJS += lib/getopt_long.o + +OBJS += crc/crc7.o +OBJS += crc/crc16.o +OBJS += crc/crc32.o +OBJS += crc/crc32c.o +OBJS += crc/crc32c-intel.o +OBJS += crc/crc64.o +OBJS += crc/sha1.o +OBJS += crc/sha256.o +OBJS += crc/sha512.o +OBJS += crc/md5.o + +OBJS += engines/cpu.o +OBJS += engines/mmap.o +OBJS += engines/posixaio.o +OBJS += engines/sync.o +OBJS += engines/null.o +OBJS += engines/net.o + +OBJS += profiles/tiobench.o + +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifndef V + QUIET_CC = @echo ' ' CC $@; + QUIET_DEP = @echo ' ' DEP $@; +endif +endif + +INSTALL = installbsd -c +prefix = /usr/local +bindir = $(prefix)/bin +mandir = $(prefix)/man + +%.o: %.c + $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $< +fio: $(OBJS) + $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(EXTLIBS) -lpthread -lm -ldl -lrt + +depend: + $(QUIET_DEP)$(CC) -MM $(ALL_CFLAGS) *.c engines/*.c crc/*.c 1> .depend + +$(PROGS): depend + +all: depend $(PROGS) $(SCRIPTS) + +clean: + -rm -f .depend cscope.out $(OBJS) $(PROGS) core.* core + +cscope: + @cscope -b + +install: $(PROGS) $(SCRIPTS) + mkdir -p -m 755 $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1 + $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir) + $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1 + $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1 + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/README b/README index f2438ba..4115455 100644 --- a/README +++ b/README @@ -65,6 +65,10 @@ specify the FreeBSD Makefile with -f and use gmake (not make), eg: $ gmake -f Makefile.Freebsd && gmake -f Makefile.FreeBSD install +Same goes for AIX: + +$ gmake -f Makefile.aix && gmake -f Makefile.aix install + Likewise with OpenSolaris, use the Makefile.solaris to compile there. The OpenSolaris make should work fine. This might change in the future if I opt for an autoconf type setup. @@ -270,7 +274,7 @@ The job file parameters are: Platforms --------- -Fio works on (at least) Linux, Solaris, and FreeBSD. Some features and/or +Fio works on (at least) Linux, Solaris, AIX 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). @@ -291,6 +295,23 @@ your mileage may vary. Sending me patches for other platforms is greatly appreciated. There's a lot of value in having the same test/benchmark tool available on all platforms. +Note that POSIX aio is not enabled by default on AIX. If you get messages like: + + Symbol resolution failed for /usr/lib/libc.a(posix_aio.o) because: + Symbol _posix_kaio_rdwr (number 2) is not exported from dependent module /unix. + +you need to enable POSIX aio. Run the following commands as root: + + # lsdev -C -l posix_aio0 + posix_aio0 Defined Posix Asynchronous I/O + # cfgmgr -l posix_aio0 + # lsdev -C -l posix_aio0 + posix_aio0 Available Posix Asynchronous I/O + +POSIX aio should work now. To make the change permanent: + + # chdev -l posix_aio0 -P -a autoconfig='available' + posix_aio0 changed Author diff --git a/arch/arch-ppc.h b/arch/arch-ppc.h index 0611538..8719869 100644 --- a/arch/arch-ppc.h +++ b/arch/arch-ppc.h @@ -42,6 +42,23 @@ static inline int arch_ffz(unsigned long bitmask) return 32; return __ilog2(bitmask & -bitmask); } + +static inline unsigned long long get_cpu_clock(void) +{ + unsigned int tbl, tbu0, tbu1; + unsigned long long ret; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl) ); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + ret = (((unsigned long long)tbu0) << 32) | tbl; + return ret; +} + #define ARCH_HAVE_FFZ +#define ARCH_HAVE_CPU_CLOCK #endif diff --git a/engines/net.c b/engines/net.c index c0a793e..9e6e789 100644 --- a/engines/net.c +++ b/engines/net.c @@ -223,7 +223,10 @@ static int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) static int fio_netio_send(struct thread_data *td, struct io_u *io_u) { struct netio_data *nd = td->io_ops->data; - int ret, flags = MSG_DONTWAIT; + int ret, flags = 0; +#ifdef MSG_DONTWAIT + flags = MSG_DONTWAIT; +#endif do { if (nd->net_protocol == IPPROTO_UDP) { @@ -251,7 +254,9 @@ static int fio_netio_send(struct thread_data *td, struct io_u *io_u) if (ret <= 0) break; +#ifdef MSG_DONTWAIT flags &= ~MSG_DONTWAIT; +#endif } while (1); return ret; @@ -276,7 +281,10 @@ static int is_udp_close(struct io_u *io_u, int len) static int fio_netio_recv(struct thread_data *td, struct io_u *io_u) { struct netio_data *nd = td->io_ops->data; - int ret, flags = MSG_DONTWAIT; + int ret, flags = 0; +#ifdef MSG_DONTWAIT + flags = MSG_DONTWAIT; +#endif do { if (nd->net_protocol == IPPROTO_UDP) { @@ -299,7 +307,9 @@ static int fio_netio_recv(struct thread_data *td, struct io_u *io_u) ret = poll_wait(td, io_u->file->fd, POLLIN); if (ret <= 0) break; +#ifdef MSG_DONTWAIT flags &= ~MSG_DONTWAIT; +#endif flags |= MSG_WAITALL; } while (1); diff --git a/fio.h b/fio.h index de76e65..5788107 100644 --- a/fio.h +++ b/fio.h @@ -11,7 +11,6 @@ #include <stdio.h> #include <unistd.h> #include <string.h> -#include <getopt.h> #include <inttypes.h> #include <assert.h> @@ -32,6 +31,7 @@ #include "options.h" #include "profile.h" #include "time.h" +#include "lib/getopt.h" #ifdef FIO_HAVE_GUASI #include <guasi.h> diff --git a/init.c b/init.c index 09b9152..c3fe88f 100644 --- a/init.c +++ b/init.c @@ -8,7 +8,6 @@ #include <ctype.h> #include <string.h> #include <errno.h> -#include <getopt.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> @@ -21,6 +20,8 @@ #include "verify.h" #include "profile.h" +#include "lib/getopt.h" + static char fio_version_string[] = "fio 1.42"; #define FIO_RANDSEED (0xb1899bedUL) diff --git a/lib/getopt.h b/lib/getopt.h new file mode 100644 index 0000000..56fe3bf --- /dev/null +++ b/lib/getopt.h @@ -0,0 +1,26 @@ +#ifndef _AIX + +#include <getopt.h> + +#else /* _AIX */ + +#ifndef _GETOPT_H +#define _GETOPT_H + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +enum { + no_argument = 0, + required_argument = 1, + optional_argument = 2, +}; + +int getopt_long_only(int, char *const *, const char *, const struct option *, int *); + +#endif /* _GETOPT_H */ +#endif /* _AIX */ diff --git a/lib/getopt_long.c b/lib/getopt_long.c new file mode 100644 index 0000000..6e8abc0 --- /dev/null +++ b/lib/getopt_long.c @@ -0,0 +1,155 @@ +/* + * getopt.c + * + * getopt_long(), or at least a common subset thereof: + * + * - Option reordering is not supported + * - -W foo is not supported + * - First optstring character "-" not supported. + * + * This file was imported from the klibc library from hpa + */ + +#include <stdint.h> +#include <unistd.h> +#include <string.h> + +#include "getopt.h" + +char *optarg; +int optind, opterr, optopt; +static struct getopt_private_state { + const char *optptr; + const char *last_optstring; + char *const *last_argv; +} pvt; + +static inline const char *option_matches(const char *arg_str, + const char *opt_name) +{ + while (*arg_str != '\0' && *arg_str != '=') { + if (*arg_str++ != *opt_name++) + return NULL; + } + + if (*opt_name) + return NULL; + + return arg_str; +} + +int getopt_long_only(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longindex) +{ + const char *carg; + const char *osptr; + int opt; + + /* getopt() relies on a number of different global state + variables, which can make this really confusing if there is + more than one use of getopt() in the same program. This + attempts to detect that situation by detecting if the + "optstring" or "argv" argument have changed since last time + we were called; if so, reinitialize the query state. */ + + if (optstring != pvt.last_optstring || argv != pvt.last_argv || + optind < 1 || optind > argc) { + /* optind doesn't match the current query */ + pvt.last_optstring = optstring; + pvt.last_argv = argv; + optind = 1; + pvt.optptr = NULL; + } + + carg = argv[optind]; + + /* First, eliminate all non-option cases */ + + if (!carg || carg[0] != '-' || !carg[1]) + return -1; + + if (carg[1] == '-') { + const struct option *lo; + const char *opt_end = NULL; + + optind++; + + /* Either it's a long option, or it's -- */ + if (!carg[2]) { + /* It's -- */ + return -1; + } + + for (lo = longopts; lo->name; lo++) { + if ((opt_end = option_matches(carg+2, lo->name))) + break; + } + if (!opt_end) + return '?'; + + if (longindex) + *longindex = lo-longopts; + + if (*opt_end == '=') { + if (lo->has_arg) + optarg = (char *)opt_end+1; + else + return '?'; + } else if (lo->has_arg == 1) { + if (!(optarg = argv[optind])) + return '?'; + optind++; + } + + if (lo->flag) { + *lo->flag = lo->val; + return 0; + } else { + return lo->val; + } + } + + if ((uintptr_t) (pvt.optptr - carg) > (uintptr_t) strlen(carg)) { + /* Someone frobbed optind, change to new opt. */ + pvt.optptr = carg + 1; + } + + opt = *pvt.optptr++; + + if (opt != ':' && (osptr = strchr(optstring, opt))) { + if (osptr[1] == ':') { + if (*pvt.optptr) { + /* Argument-taking option with attached + argument */ + optarg = (char *)pvt.optptr; + optind++; + } else { + /* Argument-taking option with non-attached + argument */ + if (argv[optind + 1]) { + optarg = (char *)argv[optind+1]; + optind += 2; + } else { + /* Missing argument */ + optind++; + return (optstring[0] == ':') + ? ':' : '?'; + } + } + return opt; + } else { + /* Non-argument-taking option */ + /* pvt.optptr will remember the exact position to + resume at */ + if (!*pvt.optptr) + optind++; + return opt; + } + } else { + /* Unknown option */ + optopt = opt; + if (!*pvt.optptr) + optind++; + return '?'; + } +} diff --git a/options.c b/options.c index 10e58db..7a9d5d3 100644 --- a/options.c +++ b/options.c @@ -3,7 +3,6 @@ #include <unistd.h> #include <ctype.h> #include <string.h> -#include <getopt.h> #include <assert.h> #include <libgen.h> #include <fcntl.h> @@ -251,13 +250,13 @@ static int fio_clock_source_cb(void *data, const char *str) return 0; } -static int str_lockmem_cb(void fio_unused *data, unsigned long *val) +static int str_lockmem_cb(void fio_unused *data, unsigned long long *val) { mlock_size = *val; return 0; } -static int str_rwmix_read_cb(void *data, unsigned int *val) +static int str_rwmix_read_cb(void *data, unsigned long long *val) { struct thread_data *td = data; @@ -266,7 +265,7 @@ static int str_rwmix_read_cb(void *data, unsigned int *val) return 0; } -static int str_rwmix_write_cb(void *data, unsigned int *val) +static int str_rwmix_write_cb(void *data, unsigned long long *val) { struct thread_data *td = data; @@ -276,7 +275,7 @@ static int str_rwmix_write_cb(void *data, unsigned int *val) } #ifdef FIO_HAVE_IOPRIO -static int str_prioclass_cb(void *data, unsigned int *val) +static int str_prioclass_cb(void *data, unsigned long long *val) { struct thread_data *td = data; unsigned short mask; @@ -292,7 +291,7 @@ static int str_prioclass_cb(void *data, unsigned int *val) return 0; } -static int str_prio_cb(void *data, unsigned int *val) +static int str_prio_cb(void *data, unsigned long long *val) { struct thread_data *td = data; @@ -316,7 +315,7 @@ static int str_exitall_cb(void) } #ifdef FIO_HAVE_CPU_AFFINITY -static int str_cpumask_cb(void *data, unsigned int *val) +static int str_cpumask_cb(void *data, unsigned long long *val) { struct thread_data *td = data; unsigned int i; @@ -614,7 +613,7 @@ static int str_opendir_cb(void *data, const char fio_unused *str) return add_dir_files(td, td->o.opendir); } -static int str_verify_offset_cb(void *data, unsigned int *off) +static int str_verify_offset_cb(void *data, unsigned long long *off) { struct thread_data *td = data; @@ -720,7 +719,7 @@ static int str_gtod_reduce_cb(void *data, int *il) return 0; } -static int str_gtod_cpu_cb(void *data, int *il) +static int str_gtod_cpu_cb(void *data, long long *il) { struct thread_data *td = data; int val = *il; diff --git a/os/os-aix.h b/os/os-aix.h new file mode 100644 index 0000000..7a64697 --- /dev/null +++ b/os/os-aix.h @@ -0,0 +1,45 @@ +#ifndef FIO_OS_AIX_H +#define FIO_OS_AIX_H + +#include <errno.h> +#include <unistd.h> +#include <sys/devinfo.h> +#include <sys/ioctl.h> + +#define FIO_HAVE_POSIXAIO +#define FIO_HAVE_ODIRECT +#define FIO_USE_GENERIC_RAND + +#define FIO_HAVE_PSHARED_MUTEX + +#define OS_MAP_ANON MAP_ANON + +static inline int blockdev_invalidate_cache(int fd) +{ + return EINVAL; +} + +static inline int blockdev_size(int fd, unsigned long long *bytes) +{ + struct devinfo info; + + if (!ioctl(fd, IOCINFO, &info)) { + *bytes = (unsigned long long)info.un.scdk.numblks * + info.un.scdk.blksize; + return 0; + } + + return errno; +} + +static inline unsigned long long os_phys_mem(void) +{ + long mem = sysconf(_SC_AIX_REALMEM); + + if (mem == -1) + return 0; + + return (unsigned long long) mem * 1024; +} + +#endif diff --git a/os/os.h b/os/os.h index 218766a..e2bb0ba 100644 --- a/os/os.h +++ b/os/os.h @@ -14,6 +14,8 @@ #include "os-solaris.h" #elif defined(__APPLE__) #include "os-mac.h" +#elif defined(_AIX) +#include "os-aix.h" #else #error "unsupported os" #endif -- 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