The following changes since commit 0fe21ef7de00f5cc0f100e1f036ddca4b4bcd234: Makefile: clean $(FIO_OBJS) too (2013-04-11 18:44:33 +0200) are available in the git repository at: git://git.kernel.dk/fio.git master Aaron Carroll (3): server: fix 32-bit build warning android: add shm syscalls and fix ioprio definitions android: add byteorder for the swab routines Bruce Cran (1): server: include uio.h for writev() Jens Axboe (7): x86: fixup cpuid for some odd (android) 32-bit variants configure: add needed packages hints Merge branch 'master' of ssh://git.kernel.dk/data/git/fio Make use of zlib optional gclient: update to new probe command format Merge branch 'master' of ssh://git.kernel.dk/data/git/fio Fix warning on platforms without disk util support arch/arch-x86-common.h | 9 ---- arch/arch-x86.h | 15 +++++++ arch/arch-x86_64.h | 9 ++++ client.c | 83 +++++++++++++++++++++++++++++++--------- configure | 12 ++++-- diskutil.h | 5 ++- gclient.c | 2 +- os/os-android.h | 18 ++++++-- server.c | 97 +++++++++++++++++++++++++++++++++-------------- server.h | 11 ++++- 10 files changed, 191 insertions(+), 70 deletions(-) --- Diff of recent changes: diff --git a/arch/arch-x86-common.h b/arch/arch-x86-common.h index 78fd40c..179572d 100644 --- a/arch/arch-x86-common.h +++ b/arch/arch-x86-common.h @@ -3,15 +3,6 @@ #include <string.h> -static inline void do_cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - asm volatile("cpuid" - : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) - : "0" (*eax), "2" (*ecx) - : "memory"); -} - static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) diff --git a/arch/arch-x86.h b/arch/arch-x86.h index 8eea538..49e64dd 100644 --- a/arch/arch-x86.h +++ b/arch/arch-x86.h @@ -1,6 +1,15 @@ #ifndef ARCH_X86_H #define ARCH_X86_H +static inline void do_cpuid(unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + asm volatile("xchgl %%ebx, %1\ncpuid\nxchgl %%ebx, %1" + : "=a" (*eax), "=r" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (*eax) + : "memory"); +} + #include "arch-x86-common.h" #define FIO_ARCH (arch_i386) @@ -20,6 +29,12 @@ #define __NR_sys_vmsplice 316 #endif +#ifndef __NR_shmget +#define __NR_shmget 29 +#define __NR_shmat 30 +#define __NR_shmctl 31 +#endif + #define FIO_HUGE_PAGE 4194304 #define nop __asm__ __volatile__("rep;nop": : :"memory") diff --git a/arch/arch-x86_64.h b/arch/arch-x86_64.h index cea0451..8bdf01e 100644 --- a/arch/arch-x86_64.h +++ b/arch/arch-x86_64.h @@ -1,6 +1,15 @@ #ifndef ARCH_X86_64_h #define ARCH_X86_64_h +static inline void do_cpuid(unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + asm volatile("cpuid" + : "=a" (*eax), "=b" (*ebx), "=r" (*ecx), "=d" (*edx) + : "0" (*eax), "2" (*ecx) + : "memory"); +} + #include "arch-x86-common.h" #define FIO_ARCH (arch_x86_64) diff --git a/client.c b/client.c index eb695ff..13e84f6 100644 --- a/client.c +++ b/client.c @@ -14,7 +14,9 @@ #include <arpa/inet.h> #include <netdb.h> #include <signal.h> +#ifdef CONFIG_ZLIB #include <zlib.h> +#endif #include "fio.h" #include "client.h" @@ -296,9 +298,18 @@ int fio_client_add(struct client_ops *ops, const char *hostname, void **cookie) static void probe_client(struct fio_client *client) { + struct cmd_client_probe_pdu pdu; + uint64_t tag; + dprint(FD_NET, "client: send probe\n"); - fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_PROBE, 0, &client->cmd_list); +#ifdef CONFIG_ZLIB + pdu.flags = __le64_to_cpu(FIO_PROBE_FLAG_ZLIB); +#else + pdu.flags = 0; +#endif + + fio_net_send_cmd(client->fd, FIO_NET_CMD_PROBE, &pdu, sizeof(pdu), &tag, &client->cmd_list); } static int fio_client_connect_ip(struct fio_client *client) @@ -998,7 +1009,7 @@ static void handle_eta(struct fio_client *client, struct fio_net_cmd *cmd) static void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd) { - struct cmd_probe_pdu *probe = (struct cmd_probe_pdu *) cmd->payload; + struct cmd_probe_reply_pdu *probe = (struct cmd_probe_reply_pdu *) cmd->payload; const char *os, *arch; char bit[16]; @@ -1011,10 +1022,11 @@ static void handle_probe(struct fio_client *client, struct fio_net_cmd *cmd) os = "unknown"; sprintf(bit, "%d-bit", probe->bpp * 8); + probe->flags = le64_to_cpu(probe->flags); - log_info("hostname=%s, be=%u, %s, os=%s, arch=%s, fio=%s\n", + log_info("hostname=%s, be=%u, %s, os=%s, arch=%s, fio=%s, flags=%lx\n", probe->hostname, probe->bigendian, bit, os, arch, - probe->fio_version); + probe->fio_version, (unsigned long) probe->flags); if (!client->name) client->name = strdup((char *) probe->hostname); @@ -1057,19 +1069,15 @@ static void convert_text(struct fio_net_cmd *cmd) pdu->log_usec = le64_to_cpu(pdu->log_usec); } -/* - * This has been compressed on the server side, since it can be big. - * Uncompress here. - */ -static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) +static struct cmd_iolog_pdu *convert_iolog_gz(struct fio_net_cmd *cmd, + struct cmd_iolog_pdu *pdu) { - struct cmd_iolog_pdu *pdu = (struct cmd_iolog_pdu *) cmd->payload; +#ifdef CONFIG_ZLIB struct cmd_iolog_pdu *ret; - uint32_t nr_samples; - unsigned long total; z_stream stream; + uint32_t nr_samples; + size_t total; void *p; - int i; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; @@ -1087,10 +1095,9 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) total = nr_samples * sizeof(struct io_sample); ret = malloc(total + sizeof(*pdu)); - ret->thread_number = le32_to_cpu(pdu->thread_number); ret->nr_samples = nr_samples; - ret->log_type = le32_to_cpu(pdu->log_type); - strcpy((char *) ret->name, (char *) pdu->name); + + memcpy(ret, pdu, sizeof(*pdu)); p = (void *) ret + sizeof(*pdu); @@ -1112,7 +1119,7 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) log_err("fio: inflate error %d\n", err); free(ret); ret = NULL; - goto out; + goto err; } this_len = this_chunk - stream.avail_out; @@ -1120,6 +1127,46 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) total -= this_len; } +err: + inflateEnd(&stream); + return ret; +#else + return NULL; +#endif +} + +/* + * This has been compressed on the server side, since it can be big. + * Uncompress here. + */ +static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) +{ + struct cmd_iolog_pdu *pdu = (struct cmd_iolog_pdu *) cmd->payload; + struct cmd_iolog_pdu *ret; + int i; + + /* + * Convert if compressed and we support it. If it's not + * compressed, we need not do anything. + */ + if (le32_to_cpu(pdu->compressed)) { +#ifndef CONFIG_ZLIB + log_err("fio: server sent compressed data by mistake\n"); + return NULL; +#endif + ret = convert_iolog_gz(cmd, pdu); + if (!ret) { + log_err("fio: failed decompressing log\n"); + return NULL; + } + } else + ret = pdu; + + ret->thread_number = le32_to_cpu(ret->thread_number); + ret->nr_samples = le32_to_cpu(ret->nr_samples); + ret->log_type = le32_to_cpu(ret->log_type); + ret->compressed = le32_to_cpu(ret->compressed); + for (i = 0; i < ret->nr_samples; i++) { struct io_sample *s = &ret->samples[i]; @@ -1129,8 +1176,6 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) s->bs = le32_to_cpu(s->bs); } -out: - inflateEnd(&stream); return ret; } diff --git a/configure b/configure index 4b71afd..7be8789 100755 --- a/configure +++ b/configure @@ -94,9 +94,13 @@ compile_prog() { feature_not_found() { feature=$1 + packages=$2 echo "ERROR" echo "ERROR: User requested feature $feature" + if test ! -z "$packages" ; then + echo "ERROR: That feature needs $packages installed" + fi echo "ERROR: configure was not able to find it" fatal "ERROR" } @@ -411,9 +415,6 @@ EOF if compile_prog "" "-lz" "zlib" ; then zlib=yes LIBS="-lz $LIBS" -else - feature_not_found "zlib" - zlib=no fi echo "zlib $zlib" @@ -434,7 +435,7 @@ if compile_prog "" "-laio" "libaio" ; then LIBS="-laio $LIBS" else if test "$libaio" = "yes" ; then - feature_not_found "linux AIO" + feature_not_found "linux AIO" "libaio-dev or libaio-devel" fi libaio=no fi @@ -1079,6 +1080,9 @@ if test "$bigendian" = "yes" ; then else output_sym "CONFIG_LITTLE_ENDIAN" fi +if test "$zlib" = "yes" ; then + output_sym "CONFIG_ZLIB" +fi if test "$libaio" = "yes" ; then output_sym "CONFIG_LIBAIO" fi diff --git a/diskutil.h b/diskutil.h index ddd6471..6ae4aee 100644 --- a/diskutil.h +++ b/diskutil.h @@ -109,7 +109,10 @@ extern int update_io_ticks(void); extern void setup_disk_util(void); extern void disk_util_prune_entries(void); #else -#define print_disk_util(dus, agg, terse) +static inline void print_disk_util(struct disk_util_stat *du, + struct disk_util_agg *agg, int terse) +{ +} #define show_disk_util(terse, parent) #define disk_util_prune_entries() #define init_disk_util(td) diff --git a/gclient.c b/gclient.c index 6f7865c..4360aea 100644 --- a/gclient.c +++ b/gclient.c @@ -534,7 +534,7 @@ static void gfio_update_all_eta(struct jobs_eta *je) static void gfio_probe_op(struct fio_client *client, struct fio_net_cmd *cmd) { - struct cmd_probe_pdu *probe = (struct cmd_probe_pdu *) cmd->payload; + struct cmd_probe_reply_pdu *probe = (struct cmd_probe_reply_pdu *) cmd->payload; struct gfio_client *gc = client->client_data; struct gui_entry *ge = gc->ge; const char *os, *arch; diff --git a/os/os-android.h b/os/os-android.h index 070aa1a..df22333 100644 --- a/os/os-android.h +++ b/os/os-android.h @@ -13,6 +13,7 @@ #include <sched.h> #include <linux/unistd.h> #include <linux/major.h> +#include <asm/byteorder.h> #include "binject.h" #include "../file.h" @@ -79,11 +80,6 @@ static inline int shmdt (const void *__shmaddr) #define SPLICE_DEF_SIZE (64*1024) -static inline int ioprio_set(int which, int who, int ioprio) -{ - return syscall(__NR_ioprio_set, which, who, ioprio); -} - enum { IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, @@ -100,6 +96,18 @@ enum { #define IOPRIO_BITS 16 #define IOPRIO_CLASS_SHIFT 13 +static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio) +{ + /* + * If no class is set, assume BE + */ + if (!ioprio_class) + ioprio_class = IOPRIO_CLASS_BE; + + ioprio |= ioprio_class << IOPRIO_CLASS_SHIFT; + return syscall(__NR_ioprio_set, which, who, ioprio); +} + #ifndef BLKGETSIZE64 #define BLKGETSIZE64 _IOR(0x12,114,size_t) #endif diff --git a/server.c b/server.c index 9537c96..884ff8e 100644 --- a/server.c +++ b/server.c @@ -11,12 +11,15 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/un.h> +#include <sys/uio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <syslog.h> #include <signal.h> +#ifdef CONFIG_ZLIB #include <zlib.h> +#endif #include "fio.h" #include "server.h" @@ -33,6 +36,12 @@ static char *bind_sock; static struct sockaddr_in saddr_in; static struct sockaddr_in6 saddr_in6; static int use_ipv6; +#ifdef CONFIG_ZLIB +static unsigned int has_zlib = 1; +#else +static unsigned int has_zlib = 0; +#endif +static unsigned int use_zlib; struct fio_fork_item { struct flist_head list; @@ -293,8 +302,9 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk) static void add_reply(uint64_t tag, struct flist_head *list) { - struct fio_net_cmd_reply *reply = (struct fio_net_cmd_reply *) tag; + struct fio_net_cmd_reply *reply; + reply = (struct fio_net_cmd_reply *) (uintptr_t) tag; flist_add_tail(&reply->list, list); } @@ -313,8 +323,9 @@ static uint64_t alloc_reply(uint64_t tag, uint16_t opcode) static void free_reply(uint64_t tag) { - struct fio_net_cmd_reply *reply = (struct fio_net_cmd_reply *) tag; + struct fio_net_cmd_reply *reply; + reply = (struct fio_net_cmd_reply *) (uintptr_t) tag; free(reply); } @@ -614,7 +625,8 @@ static int handle_jobline_cmd(struct fio_net_cmd *cmd) static int handle_probe_cmd(struct fio_net_cmd *cmd) { - struct cmd_probe_pdu probe; + struct cmd_client_probe_pdu *pdu = (struct cmd_client_probe_pdu *) cmd->payload; + struct cmd_probe_reply_pdu probe; uint64_t tag = cmd->tag; dprint(FD_NET, "server: sending probe reply\n"); @@ -630,7 +642,17 @@ static int handle_probe_cmd(struct fio_net_cmd *cmd) probe.arch = FIO_ARCH; probe.bpp = sizeof(void *); probe.cpus = __cpu_to_le32(cpus_online()); - probe.flags = 0; + + /* + * If the client supports compression and we do too, then enable it + */ + if (has_zlib && le64_to_cpu(pdu->flags) & FIO_PROBE_FLAG_ZLIB) { + probe.flags = __cpu_to_le64(FIO_PROBE_FLAG_ZLIB); + use_zlib = 1; + } else { + probe.flags = 0; + use_zlib = 0; + } return fio_net_send_cmd(server_fd, FIO_NET_CMD_PROBE, &probe, sizeof(probe), &tag, NULL); } @@ -1115,26 +1137,12 @@ static int fio_send_cmd_ext_pdu(int sk, uint16_t opcode, const void *buf, return fio_sendv_data(sk, iov, 2); } -int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) +static int fio_send_iolog_gz(struct cmd_iolog_pdu *pdu, struct io_log *log) { - struct cmd_iolog_pdu pdu; + int ret = 0; +#ifdef CONFIG_ZLIB z_stream stream; void *out_pdu; - int i, ret = 0; - - pdu.thread_number = cpu_to_le32(td->thread_number); - pdu.nr_samples = __cpu_to_le32(log->nr_samples); - pdu.log_type = cpu_to_le32(log->log_type); - strcpy((char *) pdu.name, name); - - for (i = 0; i < log->nr_samples; i++) { - struct io_sample *s = &log->log[i]; - - s->time = cpu_to_le64(s->time); - s->val = cpu_to_le64(s->val); - s->ddir = cpu_to_le32(s->ddir); - s->bs = cpu_to_le32(s->bs); - } /* * Dirty - since the log is potentially huge, compress it into @@ -1152,14 +1160,6 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) goto err; } - /* - * Send header first, it's not compressed. - */ - ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, &pdu, - sizeof(pdu), 0, FIO_NET_CMD_F_MORE); - if (ret) - goto err_zlib; - stream.next_in = (void *) log->log; stream.avail_in = log->nr_samples * sizeof(struct io_sample); @@ -1189,9 +1189,48 @@ err_zlib: deflateEnd(&stream); err: free(out_pdu); +#endif return ret; } +int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) +{ + struct cmd_iolog_pdu pdu; + int i, ret = 0; + + pdu.thread_number = cpu_to_le32(td->thread_number); + pdu.nr_samples = __cpu_to_le32(log->nr_samples); + pdu.log_type = cpu_to_le32(log->log_type); + pdu.compressed = cpu_to_le32(use_zlib); + strcpy((char *) pdu.name, name); + + for (i = 0; i < log->nr_samples; i++) { + struct io_sample *s = &log->log[i]; + + s->time = cpu_to_le64(s->time); + s->val = cpu_to_le64(s->val); + s->ddir = cpu_to_le32(s->ddir); + s->bs = cpu_to_le32(s->bs); + } + + /* + * Send header first, it's not compressed. + */ + ret = fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, &pdu, + sizeof(pdu), 0, FIO_NET_CMD_F_MORE); + if (ret) + return ret; + + /* + * Now send actual log, compress if we can, otherwise just plain + */ + if (use_zlib) + return fio_send_iolog_gz(&pdu, log); + + return fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, log->log, + log->nr_samples * sizeof(struct io_sample), 0, 0); +} + void fio_server_send_add_job(struct thread_data *td) { struct cmd_add_job_pdu pdu; diff --git a/server.h b/server.h index 067cdc0..478c283 100644 --- a/server.h +++ b/server.h @@ -38,7 +38,7 @@ struct fio_net_cmd_reply { }; enum { - FIO_SERVER_VER = 21, + FIO_SERVER_VER = 22, FIO_SERVER_MAX_FRAGMENT_PDU = 1024, @@ -71,6 +71,8 @@ enum { FIO_NET_NAME_MAX = 256, FIO_NET_CLIENT_TIMEOUT = 5000, + + FIO_PROBE_FLAG_ZLIB = 1UL << 0, }; struct cmd_ts_pdu { @@ -83,7 +85,11 @@ struct cmd_du_pdu { struct disk_util_agg agg; }; -struct cmd_probe_pdu { +struct cmd_client_probe_pdu { + uint64_t flags; +}; + +struct cmd_probe_reply_pdu { uint8_t hostname[64]; uint8_t bigendian; uint8_t fio_version[32]; @@ -139,6 +145,7 @@ struct cmd_iolog_pdu { uint32_t thread_number; uint32_t nr_samples; uint32_t log_type; + uint32_t compressed; uint8_t name[FIO_NET_NAME_MAX]; struct io_sample samples[0]; }; -- 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