diff --git a/examples/bdev/fio_plugin/fio_plugin.c b/examples/bdev/fio_plugin/fio_plugin.c index aab888a73..0a0cc132c 100644 --- a/examples/bdev/fio_plugin/fio_plugin.c +++ b/examples/bdev/fio_plugin/fio_plugin.c @@ -41,6 +41,7 @@ #include "spdk/log.h" #include "spdk/string.h" #include "spdk/queue.h" +#include "spdk/util.h" #include "config-host.h" #include "fio.h" @@ -85,7 +86,8 @@ struct spdk_fio_thread { struct thread_data *td; /* fio thread context */ struct spdk_thread *thread; /* spdk thread context */ struct spdk_ring *ring; /* ring for passing messages to this thread */ - TAILQ_HEAD(, spdk_fio_poller) pollers; /* List of registered pollers on this thread */ + uint64_t timeout; /* polling timeout */ + TAILQ_HEAD(, spdk_fio_poller) pollers; /* list of registered pollers on this thread */ TAILQ_HEAD(, spdk_fio_target) targets; @@ -100,6 +102,9 @@ static int spdk_fio_init(struct thread_data *td); static void spdk_fio_cleanup(struct thread_data *td); static size_t spdk_fio_poll_thread(struct spdk_fio_thread *fio_thread); +/* Default polling timeout (us) */ +#define SPDK_FIO_POLLING_TIMEOUT 1000000UL + static void spdk_fio_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) { @@ -143,6 +148,7 @@ spdk_fio_start_poller(void *thread_ctx, fio_poller->cb_fn = fn; fio_poller->cb_arg = arg; fio_poller->period_microseconds = period_microseconds; + fio_thread->timeout = spdk_min(fio_thread->timeout, period_microseconds); TAILQ_INSERT_TAIL(&fio_thread->pollers, fio_poller, link); @@ -154,11 +160,20 @@ spdk_fio_stop_poller(struct spdk_poller *poller, void *thread_ctx) { struct spdk_fio_poller *fio_poller; struct spdk_fio_thread *fio_thread = thread_ctx; + uint64_t timeout = SPDK_FIO_POLLING_TIMEOUT; fio_poller = (struct spdk_fio_poller *)poller; TAILQ_REMOVE(&fio_thread->pollers, fio_poller, link); + if (fio_thread->timeout == fio_poller->period_microseconds) { + TAILQ_FOREACH(fio_poller, &fio_thread->pollers, link) { + timeout = spdk_min(timeout, fio_poller->period_microseconds); + } + + fio_thread->timeout = timeout; + } + free(fio_poller); } @@ -201,6 +216,8 @@ spdk_fio_init_thread(struct thread_data *td) fio_thread->iocq = calloc(fio_thread->iocq_size, sizeof(struct io_u *)); assert(fio_thread->iocq != NULL); + fio_thread->timeout = SPDK_FIO_POLLING_TIMEOUT; + TAILQ_INIT(&fio_thread->targets); return 0; @@ -232,6 +249,16 @@ spdk_fio_module_finish_done(void *cb_arg) *(bool *)cb_arg = true; } +static void +spdk_fio_calc_timeout(struct timespec *ts, uint64_t us) +{ + uint64_t timeout = ts->tv_sec * SPDK_SEC_TO_NSEC + ts->tv_nsec; + + timeout += us * 1000; + ts->tv_sec = timeout / SPDK_SEC_TO_NSEC; + ts->tv_nsec = timeout % SPDK_SEC_TO_NSEC; +} + static pthread_t g_init_thread_id = 0; static pthread_mutex_t g_init_mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t g_init_cond = PTHREAD_COND_INITIALIZER; @@ -336,7 +363,7 @@ spdk_init_thread_poll(void *arg) spdk_fio_poll_thread(fio_thread); clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += 1; + spdk_fio_calc_timeout(&ts, fio_thread->timeout); rc = pthread_cond_timedwait(&g_init_cond, &g_init_mtx, &ts); if (rc != ETIMEDOUT) { @@ -673,7 +700,7 @@ spdk_fio_getevents(struct thread_data *td, unsigned int min, uint64_t timeout = 0; if (t) { - timeout = t->tv_sec * 1000000000L + t->tv_nsec; + timeout = t->tv_sec * SPDK_SEC_TO_NSEC + t->tv_nsec; clock_gettime(CLOCK_MONOTONIC_RAW, &t0); } @@ -688,7 +715,7 @@ spdk_fio_getevents(struct thread_data *td, unsigned int min, if (t) { clock_gettime(CLOCK_MONOTONIC_RAW, &t1); - uint64_t elapse = ((t1.tv_sec - t0.tv_sec) * 1000000000L) + uint64_t elapse = ((t1.tv_sec - t0.tv_sec) * SPDK_SEC_TO_NSEC) + t1.tv_nsec - t0.tv_nsec; if (elapse > timeout) { break; diff --git a/include/spdk/util.h b/include/spdk/util.h index 43d3b8d5b..76c5f6aa6 100644 --- a/include/spdk/util.h +++ b/include/spdk/util.h @@ -52,6 +52,7 @@ extern "C" { #define SPDK_CONTAINEROF(ptr, type, member) ((type *)((uintptr_t)ptr - offsetof(type, member))) #define SPDK_SEC_TO_USEC 1000000ULL +#define SPDK_SEC_TO_NSEC 1000000000ULL static inline uint32_t spdk_u32log2(uint32_t x)