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 <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/437309
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Konrad Sztyber 2018-12-14 11:36:22 +01:00 committed by Jim Harris
parent 270a25df8d
commit 22c1a00fa8
3 changed files with 39 additions and 11 deletions

View File

@ -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) {

View File

@ -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.
*/

View File

@ -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)
{