thread: refine period poller intr function
These refined functions are prepared to adapt period poller to following poller switchable API. Change-Id: I34d2a785fa0e757b97b0dac5ccf24819d75e0184 Signed-off-by: Liu Xiaodong <xiaodong.liu@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7156 Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot
This commit is contained in:
parent
b763ebfe1d
commit
39527e93d8
@ -982,49 +982,6 @@ spdk_thread_send_critical_msg(struct spdk_thread *thread, spdk_msg_fn fn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
static int
|
|
||||||
interrupt_timerfd_prepare(uint64_t period_microseconds)
|
|
||||||
{
|
|
||||||
int timerfd;
|
|
||||||
int ret;
|
|
||||||
struct itimerspec new_tv;
|
|
||||||
uint64_t period_seconds;
|
|
||||||
uint64_t period_nanoseconds;
|
|
||||||
|
|
||||||
if (period_microseconds == 0) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
period_seconds = period_microseconds / SPDK_SEC_TO_USEC;
|
|
||||||
period_nanoseconds = period_microseconds % SPDK_SEC_TO_USEC * 1000;
|
|
||||||
|
|
||||||
new_tv.it_value.tv_sec = period_seconds;
|
|
||||||
new_tv.it_value.tv_nsec = period_nanoseconds;
|
|
||||||
|
|
||||||
new_tv.it_interval.tv_sec = period_seconds;
|
|
||||||
new_tv.it_interval.tv_nsec = period_nanoseconds;
|
|
||||||
|
|
||||||
timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK & TFD_CLOEXEC);
|
|
||||||
if (timerfd < 0) {
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = timerfd_settime(timerfd, 0, &new_tv, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
close(timerfd);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return timerfd;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int
|
|
||||||
interrupt_timerfd_prepare(uint64_t period_microseconds)
|
|
||||||
{
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
interrupt_timerfd_process(void *arg)
|
interrupt_timerfd_process(void *arg)
|
||||||
{
|
{
|
||||||
@ -1045,17 +1002,25 @@ interrupt_timerfd_process(void *arg)
|
|||||||
return poller->fn(poller->arg);
|
return poller->fn(poller->arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void period_poller_interrupt_fini(struct spdk_poller *poller);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
thread_interrupt_register_timerfd(struct spdk_fd_group *fgrp,
|
period_poller_interrupt_init(struct spdk_poller *poller)
|
||||||
uint64_t period_microseconds,
|
|
||||||
struct spdk_poller *poller)
|
|
||||||
{
|
{
|
||||||
|
struct spdk_fd_group *fgrp = poller->thread->fgrp;
|
||||||
int timerfd;
|
int timerfd;
|
||||||
int rc;
|
int rc;
|
||||||
|
uint64_t now_tick = spdk_get_ticks();
|
||||||
|
uint64_t ticks = spdk_get_ticks_hz();
|
||||||
|
int ret;
|
||||||
|
struct itimerspec new_tv;
|
||||||
|
|
||||||
timerfd = interrupt_timerfd_prepare(period_microseconds);
|
assert(poller->period_ticks != 0);
|
||||||
|
|
||||||
|
SPDK_DEBUGLOG(thread, "timerfd init for period poller %s\n", poller->name);
|
||||||
|
timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||||
if (timerfd < 0) {
|
if (timerfd < 0) {
|
||||||
return timerfd;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = spdk_fd_group_add(fgrp, timerfd,
|
rc = spdk_fd_group_add(fgrp, timerfd,
|
||||||
@ -1065,9 +1030,57 @@ thread_interrupt_register_timerfd(struct spdk_fd_group *fgrp,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return timerfd;
|
poller->timerfd = timerfd;
|
||||||
|
|
||||||
|
/* Set repeated timer expirations */
|
||||||
|
new_tv.it_interval.tv_sec = poller->period_ticks / ticks;
|
||||||
|
new_tv.it_interval.tv_nsec = poller->period_ticks % ticks * SPDK_SEC_TO_NSEC / ticks;
|
||||||
|
|
||||||
|
/* Update next expiration */
|
||||||
|
if (poller->next_run_tick == 0) {
|
||||||
|
poller->next_run_tick = now_tick + poller->period_ticks;
|
||||||
|
} else if (poller->next_run_tick < now_tick) {
|
||||||
|
poller->next_run_tick = now_tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_tv.it_value.tv_sec = (poller->next_run_tick - now_tick) / ticks;
|
||||||
|
new_tv.it_value.tv_nsec = (poller->next_run_tick - now_tick) % ticks * SPDK_SEC_TO_NSEC / ticks;
|
||||||
|
|
||||||
|
ret = timerfd_settime(timerfd, 0, &new_tv, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
rc = -errno;
|
||||||
|
SPDK_ERRLOG("Failed to arm timerfd: error(%d)\n", errno);
|
||||||
|
period_poller_interrupt_fini(poller);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
period_poller_interrupt_fini(struct spdk_poller *poller)
|
||||||
|
{
|
||||||
|
SPDK_DEBUGLOG(thread, "timerfd fini for poller %s\n", poller->name);
|
||||||
|
assert(poller->timerfd >= 0);
|
||||||
|
spdk_fd_group_remove(poller->thread->fgrp, poller->timerfd);
|
||||||
|
close(poller->timerfd);
|
||||||
|
poller->timerfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static int
|
||||||
|
period_poller_interrupt_init(struct spdk_poller *poller)
|
||||||
|
{
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
period_poller_interrupt_fini(struct spdk_poller *poller)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct spdk_poller *
|
static struct spdk_poller *
|
||||||
poller_register(spdk_poller_fn fn,
|
poller_register(spdk_poller_fn fn,
|
||||||
void *arg,
|
void *arg,
|
||||||
@ -1105,6 +1118,7 @@ poller_register(spdk_poller_fn fn,
|
|||||||
poller->fn = fn;
|
poller->fn = fn;
|
||||||
poller->arg = arg;
|
poller->arg = arg;
|
||||||
poller->thread = thread;
|
poller->thread = thread;
|
||||||
|
poller->timerfd = -1;
|
||||||
|
|
||||||
if (period_microseconds) {
|
if (period_microseconds) {
|
||||||
quotient = period_microseconds / SPDK_SEC_TO_USEC;
|
quotient = period_microseconds / SPDK_SEC_TO_USEC;
|
||||||
@ -1116,17 +1130,15 @@ poller_register(spdk_poller_fn fn,
|
|||||||
poller->period_ticks = 0;
|
poller->period_ticks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spdk_interrupt_mode_is_enabled() && period_microseconds != 0) {
|
if (period_microseconds && spdk_interrupt_mode_is_enabled()) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
poller->timerfd = -1;
|
rc = period_poller_interrupt_init(poller);
|
||||||
rc = thread_interrupt_register_timerfd(thread->fgrp, period_microseconds, poller);
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
SPDK_ERRLOG("Failed to register timerfd for periodic poller: %s\n", spdk_strerror(-rc));
|
SPDK_ERRLOG("Failed to register timerfd for periodic poller: %s\n", spdk_strerror(-rc));
|
||||||
free(poller);
|
free(poller);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
poller->timerfd = rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_insert_poller(thread, poller);
|
thread_insert_poller(thread, poller);
|
||||||
@ -1177,9 +1189,7 @@ spdk_poller_unregister(struct spdk_poller **ppoller)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (spdk_interrupt_mode_is_enabled() && poller->timerfd >= 0) {
|
if (spdk_interrupt_mode_is_enabled() && poller->timerfd >= 0) {
|
||||||
spdk_fd_group_remove(thread->fgrp, poller->timerfd);
|
period_poller_interrupt_fini(poller);
|
||||||
close(poller->timerfd);
|
|
||||||
poller->timerfd = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the poller was paused, put it on the active_pollers list so that
|
/* If the poller was paused, put it on the active_pollers list so that
|
||||||
|
Loading…
Reference in New Issue
Block a user