From 22c1a00fa822a1b0e6909d738a8f38e7fb83fa0c Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Fri, 14 Dec 2018 11:36:22 +0100 Subject: [PATCH] fio_plugin: use pollers' expiration for timedwait Check next poller's expiration time to calculate the timeout for pthread_cond_timedwait. Change-Id: I96f81bab917c1bc628d94bba3c58d25066d4209a Signed-off-by: Konrad Sztyber Reviewed-on: https://review.gerrithub.io/437309 Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto Reviewed-by: Darek Stojaczyk Tested-by: SPDK CI Jenkins --- examples/bdev/fio_plugin/fio_plugin.c | 34 ++++++++++++++++++--------- include/spdk/thread.h | 10 ++++++++ lib/thread/thread.c | 6 +++++ 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/examples/bdev/fio_plugin/fio_plugin.c b/examples/bdev/fio_plugin/fio_plugin.c index fda2a3fc9..e7d48875e 100644 --- a/examples/bdev/fio_plugin/fio_plugin.c +++ b/examples/bdev/fio_plugin/fio_plugin.c @@ -72,7 +72,6 @@ struct spdk_fio_target { struct spdk_fio_thread { struct thread_data *td; /* fio thread context */ struct spdk_thread *thread; /* spdk thread context */ - uint64_t timeout; /* polling timeout */ TAILQ_HEAD(, spdk_fio_target) targets; bool failed; /* true if the thread failed to initialize */ @@ -88,8 +87,8 @@ 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 +/* Default polling timeout (ns) */ +#define SPDK_FIO_POLLING_TIMEOUT 1000000000ULL static int spdk_fio_init_thread(struct thread_data *td) @@ -116,8 +115,6 @@ 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; @@ -152,13 +149,28 @@ spdk_fio_cleanup_thread(struct spdk_fio_thread *fio_thread) } static void -spdk_fio_calc_timeout(struct timespec *ts, uint64_t us) +spdk_fio_calc_timeout(struct spdk_fio_thread *fio_thread, struct timespec *ts) { - uint64_t timeout = ts->tv_sec * SPDK_SEC_TO_NSEC + ts->tv_nsec; + uint64_t timeout, now; - timeout += us * 1000; - ts->tv_sec = timeout / SPDK_SEC_TO_NSEC; - ts->tv_nsec = timeout % SPDK_SEC_TO_NSEC; + if (spdk_thread_has_active_pollers(fio_thread->thread)) { + return; + } + + timeout = spdk_thread_next_poller_expiration(fio_thread->thread); + now = spdk_get_ticks(); + + if (timeout == 0) { + timeout = now + (SPDK_FIO_POLLING_TIMEOUT * spdk_get_ticks_hz()) / SPDK_SEC_TO_NSEC; + } + + if (timeout > now) { + timeout = ((timeout - now) * SPDK_SEC_TO_NSEC) / spdk_get_ticks_hz() + + ts->tv_sec * SPDK_SEC_TO_NSEC + ts->tv_nsec; + + ts->tv_sec = timeout / SPDK_SEC_TO_NSEC; + ts->tv_nsec = timeout % SPDK_SEC_TO_NSEC; + } } static pthread_t g_init_thread_id = 0; @@ -301,7 +313,7 @@ spdk_init_thread_poll(void *arg) spdk_fio_poll_thread(fio_thread); clock_gettime(CLOCK_MONOTONIC, &ts); - spdk_fio_calc_timeout(&ts, fio_thread->timeout); + spdk_fio_calc_timeout(fio_thread, &ts); rc = pthread_cond_timedwait(&g_init_cond, &g_init_mtx, &ts); if (rc != ETIMEDOUT) { diff --git a/include/spdk/thread.h b/include/spdk/thread.h index 71099a55f..a9e5fd44c 100644 --- a/include/spdk/thread.h +++ b/include/spdk/thread.h @@ -231,6 +231,16 @@ int spdk_thread_poll(struct spdk_thread *thread, uint32_t max_msgs); */ uint64_t spdk_thread_next_poller_expiration(struct spdk_thread *thread); +/** + * Returns whether there are any active pollers (pollers for which + * period_microseconds equals 0) registered to be run on the thread. + * + * \param thread The thread to check. + * + * \return 1 if there is at least one active poller, 0 otherwise. + */ +int spdk_thread_has_active_pollers(struct spdk_thread *thread); + /** * Get count of allocated threads. */ diff --git a/lib/thread/thread.c b/lib/thread/thread.c index d33086429..d111b7958 100644 --- a/lib/thread/thread.c +++ b/lib/thread/thread.c @@ -434,6 +434,12 @@ spdk_thread_next_poller_expiration(struct spdk_thread *thread) return 0; } +int +spdk_thread_has_active_pollers(struct spdk_thread *thread) +{ + return !TAILQ_EMPTY(&thread->active_pollers); +} + uint32_t spdk_thread_get_count(void) {