The following changes since commit cf7cadec891c9e4226f2d93c2014c87a94ebd730: goptions: fix bad log_err() type (2013-04-16 21:10:46 +0200) are available in the git repository at: git://git.kernel.dk/fio.git master Jens Axboe (8): Propagate io engine error back to 'td', if not already done null: 'td' isn't actually unused, unmark it Split out td error handling code Move unused and other attributes to the compiler section Kil unneeded forward declaration ioengine: kill unneeded thread_data forward declaration Get rid of mixed code/data sections Add -Wdeclaration-after-statement to compiler flags Makefile | 4 ++-- compiler/compiler.h | 7 +++++++ engines/null.c | 2 +- fio.h | 47 +---------------------------------------------- idletime.c | 32 +++++++++++++++++++++----------- ioengine.h | 2 -- ioengines.c | 7 +++++++ td_error.c | 41 +++++++++++++++++++++++++++++++++++++++++ td_error.h | 27 +++++++++++++++++++++++++++ thread_options.h | 19 +------------------ 10 files changed, 108 insertions(+), 80 deletions(-) create mode 100644 td_error.c create mode 100644 td_error.h --- Diff of recent changes: diff --git a/Makefile b/Makefile index e93bf4d..d10123e 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ endif DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG CPPFLAGS= -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(DEBUGFLAGS) OPTFLAGS= -O3 -g -ffast-math -CFLAGS = -std=gnu99 -Wwrite-strings -Wall $(OPTFLAGS) $(EXTFLAGS) $(BUILD_CFLAGS) +CFLAGS = -std=gnu99 -Wwrite-strings -Wall -Wdeclaration-after-statement $(OPTFLAGS) $(EXTFLAGS) $(BUILD_CFLAGS) LIBS += -lm $(EXTLIBS) PROGS = fio SCRIPTS = fio_generate_plots @@ -32,7 +32,7 @@ SOURCE := gettime.c ioengines.c init.c stat.c log.c time.c filesetup.c \ memalign.c server.c client.c iolog.c backend.c libfio.c flow.c \ cconv.c lib/prio_tree.c json.c lib/zipf.c lib/axmap.c \ lib/lfsr.c gettime-thread.c helpers.c lib/flist_sort.c \ - lib/hweight.c lib/getrusage.c idletime.c + lib/hweight.c lib/getrusage.c idletime.c td_error.c ifdef CONFIG_64BIT_LLP64 CFLAGS += -DBITS_PER_LONG=32 diff --git a/compiler/compiler.h b/compiler/compiler.h index 72e8419..036ba20 100644 --- a/compiler/compiler.h +++ b/compiler/compiler.h @@ -13,4 +13,11 @@ #define __must_check #endif +/* + * Mark unused variables passed to ops functions as unused, to silence gcc + */ +#define fio_unused __attribute__((__unused__)) +#define fio_init __attribute__((constructor)) +#define fio_exit __attribute__((destructor)) + #endif diff --git a/engines/null.c b/engines/null.c index f434550..bf7885e 100644 --- a/engines/null.c +++ b/engines/null.c @@ -54,7 +54,7 @@ static int fio_null_commit(struct thread_data *td) return 0; } -static int fio_null_queue(struct thread_data fio_unused *td, struct io_u *io_u) +static int fio_null_queue(struct thread_data *td, struct io_u *io_u) { struct null_data *nd = td->io_ops->data; diff --git a/fio.h b/fio.h index 47e711f..50a868a 100644 --- a/fio.h +++ b/fio.h @@ -14,8 +14,6 @@ #include <inttypes.h> #include <assert.h> -struct thread_data; - #include "compiler/compiler.h" #include "thread_options.h" #include "flist.h" @@ -323,9 +321,9 @@ enum { #define __td_verror(td, err, msg, func) \ do { \ + int e = (err); \ if ((td)->error) \ break; \ - int e = (err); \ (td)->error = e; \ if (!(td)->first_error) \ snprintf(td->verror, sizeof(td->verror), "file:%s:%d, func=%s, error=%s", __FILE__, __LINE__, (func), (msg)); \ @@ -375,42 +373,6 @@ static inline void fio_ro_check(struct thread_data *td, struct io_u *io_u) #define REAL_MAX_JOBS 2048 -static inline enum error_type_bit td_error_type(enum fio_ddir ddir, int err) -{ - if (err == EILSEQ) - return ERROR_TYPE_VERIFY_BIT; - if (ddir == DDIR_READ) - return ERROR_TYPE_READ_BIT; - return ERROR_TYPE_WRITE_BIT; -} - -static int __NON_FATAL_ERR[] = {EIO, EILSEQ}; -static inline int td_non_fatal_error(struct thread_data *td, - enum error_type_bit etype, int err) -{ - unsigned int i; - - if (!td->o.ignore_error[etype]) { - td->o.ignore_error[etype] = __NON_FATAL_ERR; - td->o.ignore_error_nr[etype] = sizeof(__NON_FATAL_ERR) - / sizeof(int); - } - - if (!(td->o.continue_on_error & (1 << etype))) - return 0; - for (i = 0; i < td->o.ignore_error_nr[etype]; i++) - if (td->o.ignore_error[etype][i] == err) - return 1; - return 0; -} - -static inline void update_error_count(struct thread_data *td, int err) -{ - td->total_err_count++; - if (td->total_err_count == 1) - td->first_error = err; -} - static inline int should_fsync(struct thread_data *td) { if (td->last_was_sync) @@ -507,13 +469,6 @@ extern int is_blktrace(const char *); extern int load_blktrace(struct thread_data *, const char *); #endif -/* - * Mark unused variables passed to ops functions as unused, to silence gcc - */ -#define fio_unused __attribute((__unused__)) -#define fio_init __attribute__((constructor)) -#define fio_exit __attribute__((destructor)) - #define for_each_td(td, i) \ for ((i) = 0, (td) = &threads[0]; (i) < (int) thread_number; (i)++, (td)++) #define for_each_file(td, f, i) \ diff --git a/idletime.c b/idletime.c index d4d665a..9e69607 100644 --- a/idletime.c +++ b/idletime.c @@ -43,6 +43,26 @@ static double calibrate_unit(unsigned char *data) return tunit / CALIBRATE_SCALE; } +static int set_cpu_affinity(struct idle_prof_thread *ipt) +{ +#if defined(FIO_HAVE_CPU_AFFINITY) + os_cpu_mask_t cpu_mask; + + memset(&cpu_mask, 0, sizeof(cpu_mask)); + fio_cpu_set(&cpu_mask, ipt->cpu); + + if (fio_setaffinity(gettid(), cpu_mask)) { + log_err("fio: fio_setaffinity failed\n"); + return -1; + } + + return 0; +#else + log_err("fio: fio_setaffinity not supported\n"); + return -1; +#endif +} + static void *idle_prof_thread_fn(void *data) { int retval; @@ -56,17 +76,7 @@ static void *idle_prof_thread_fn(void *data) if (ipc.status == IDLE_PROF_STATUS_ABORT) return NULL; -#if defined(FIO_HAVE_CPU_AFFINITY) - os_cpu_mask_t cpu_mask; - memset(&cpu_mask, 0, sizeof(cpu_mask)); - fio_cpu_set(&cpu_mask, ipt->cpu); - - if ((retval=fio_setaffinity(gettid(), cpu_mask)) == -1) - log_err("fio: fio_setaffinity failed\n"); -#else - retval = -1; - log_err("fio: fio_setaffinity not supported\n"); -#endif + retval = set_cpu_affinity(ipt); if (retval == -1) { ipt->state = TD_EXITED; pthread_mutex_unlock(&ipt->init_lock); diff --git a/ioengine.h b/ioengine.h index 493d4b5..d52b2b9 100644 --- a/ioengine.h +++ b/ioengine.h @@ -28,8 +28,6 @@ enum { IO_U_F_VER_LIST = 1 << 7, }; -struct thread_data; - /* * The io unit */ diff --git a/ioengines.c b/ioengines.c index 93e7631..d71e372 100644 --- a/ioengines.c +++ b/ioengines.c @@ -288,6 +288,13 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) unlock_file(td, io_u->file); /* + * If an error was seen and the io engine didn't propagate it + * back to 'td', do so. + */ + if (io_u->error && !td->error) + td_verror(td, io_u->error, "td_io_queue"); + + /* * Add warning for O_DIRECT so that users have an easier time * spotting potentially bad alignment. If this triggers for the first * IO, then it's likely an alignment problem or because the host fs diff --git a/td_error.c b/td_error.c new file mode 100644 index 0000000..903f9ea --- /dev/null +++ b/td_error.c @@ -0,0 +1,41 @@ +#include "fio.h" +#include "io_ddir.h" +#include "td_error.h" + +static int __NON_FATAL_ERR[] = { EIO, EILSEQ }; + +enum error_type_bit td_error_type(enum fio_ddir ddir, int err) +{ + if (err == EILSEQ) + return ERROR_TYPE_VERIFY_BIT; + if (ddir == DDIR_READ) + return ERROR_TYPE_READ_BIT; + return ERROR_TYPE_WRITE_BIT; +} + +int td_non_fatal_error(struct thread_data *td, enum error_type_bit etype, + int err) +{ + unsigned int i; + + if (!td->o.ignore_error[etype]) { + td->o.ignore_error[etype] = __NON_FATAL_ERR; + td->o.ignore_error_nr[etype] = sizeof(__NON_FATAL_ERR) + / sizeof(int); + } + + if (!(td->o.continue_on_error & (1 << etype))) + return 0; + for (i = 0; i < td->o.ignore_error_nr[etype]; i++) + if (td->o.ignore_error[etype][i] == err) + return 1; + + return 0; +} + +void update_error_count(struct thread_data *td, int err) +{ + td->total_err_count++; + if (td->total_err_count == 1) + td->first_error = err; +} diff --git a/td_error.h b/td_error.h new file mode 100644 index 0000000..1133989 --- /dev/null +++ b/td_error.h @@ -0,0 +1,27 @@ +#ifndef FIO_TD_ERROR_H +#define FIO_TD_ERROR_H + +/* + * What type of errors to continue on when continue_on_error is used + */ +enum error_type_bit { + ERROR_TYPE_READ_BIT = 0, + ERROR_TYPE_WRITE_BIT = 1, + ERROR_TYPE_VERIFY_BIT = 2, + ERROR_TYPE_CNT = 3, +}; + +enum error_type { + ERROR_TYPE_NONE = 0, + ERROR_TYPE_READ = 1 << ERROR_TYPE_READ_BIT, + ERROR_TYPE_WRITE = 1 << ERROR_TYPE_WRITE_BIT, + ERROR_TYPE_VERIFY = 1 << ERROR_TYPE_VERIFY_BIT, + ERROR_TYPE_ANY = 0xffff, +}; + +enum error_type_bit td_error_type(enum fio_ddir ddir, int err); +int td_non_fatal_error(struct thread_data *td, enum error_type_bit etype, + int err); +void update_error_count(struct thread_data *td, int err); + +#endif diff --git a/thread_options.h b/thread_options.h index 60a1b69..f25988a 100644 --- a/thread_options.h +++ b/thread_options.h @@ -6,6 +6,7 @@ #include "stat.h" #include "gettime.h" #include "lib/ieee754.h" +#include "td_error.h" /* * What type of allocation to use for io buffers @@ -18,26 +19,8 @@ enum fio_memtype { MEM_MMAPHUGE, /* memory mapped huge file */ }; -/* - * What type of errors to continue on when continue_on_error is used - */ -enum error_type_bit { - ERROR_TYPE_READ_BIT = 0, - ERROR_TYPE_WRITE_BIT = 1, - ERROR_TYPE_VERIFY_BIT = 2, - ERROR_TYPE_CNT = 3, -}; - #define ERROR_STR_MAX 128 -enum error_type { - ERROR_TYPE_NONE = 0, - ERROR_TYPE_READ = 1 << ERROR_TYPE_READ_BIT, - ERROR_TYPE_WRITE = 1 << ERROR_TYPE_WRITE_BIT, - ERROR_TYPE_VERIFY = 1 << ERROR_TYPE_VERIFY_BIT, - ERROR_TYPE_ANY = 0xffff, -}; - #define BSSPLIT_MAX 64 struct bssplit { -- 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