BUG/MINOR: polling: fix time reporting when using busy polling
Since commit beb859abce ("MINOR: polling: add an option to support
busy polling") the time and status passed to clock_update_local_date()
were incorrect. Indeed, what is considered is the before_poll date
related to the configured timeout which does not correspond to what
is passed to the poller. That's not correct because before_poll+the
syscall's timeout will be crossed by the current date 100 ms after
the start of the poller. In practice it didn't happen when the poller
was limited to 1s timeout but at one minute it happens all the time.
That's particularly visible when running a multi-threaded setup with
busy polling and only half of the threads working (bind ... thread even).
In this case, the fixup code of clock_update_local_date() is executed
for each round of busy polling. The issue was made really visible
starting with recent commit e8b1ad4c2b ("BUG/MEDIUM: clock: also
update the date offset on time jumps") because upon a jump, the
shared offset is reset, while it should not be in this specific
case.
What needs to be done instead is to pass the configured timeout of
the poller (and not of the syscall), and always pass "interrupted"
set so as to claim we got an event (which is sort of true as it just
means the poller returned instantly). In this case we can still
detect backwards/forward jumps and will use a correct boundary
for the maximum date that covers the whole loop.
This can be backported to all versions since the issue was introduced
with busy-polling in 1.9-dev8.
(cherry picked from commit ad98edd00accdf5529da77eb79b72cf9fc025a7d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 250c436ff765b426aeafb193ec3dbc71709f9871)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit b97f63d21718844d6117de6691cc244db804c654)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/ev_epoll.c b/src/ev_epoll.c
index c42cf2e..30127af 100644
--- a/src/ev_epoll.c
+++ b/src/ev_epoll.c
@@ -230,7 +230,7 @@
int timeout = (global.tune.options & GTUNE_BUSY_POLLING) ? 0 : wait_time;
status = epoll_wait(epoll_fd[tid], epoll_events, global.tune.maxpollevents, timeout);
- clock_update_local_date(timeout, status);
+ clock_update_local_date(wait_time, (global.tune.options & GTUNE_BUSY_POLLING) ? 1 : status);
if (status) {
activity[tid].poll_io++;
diff --git a/src/ev_evports.c b/src/ev_evports.c
index 0acded2..ceecf9d 100644
--- a/src/ev_evports.c
+++ b/src/ev_evports.c
@@ -217,7 +217,7 @@
break;
}
}
- clock_update_local_date(timeout, nevlist);
+ clock_update_local_date(wait_time, (global.tune.options & GTUNE_BUSY_POLLING) ? 1 : nevlist);
if (nevlist || interrupted)
break;
diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c
index f123e7b..271e95b 100644
--- a/src/ev_kqueue.c
+++ b/src/ev_kqueue.c
@@ -183,7 +183,7 @@
kev, // struct kevent *eventlist
fd, // int nevents
&timeout_ts); // const struct timespec *timeout
- clock_update_local_date(timeout, status);
+ clock_update_local_date(wait_time, (global.tune.options & GTUNE_BUSY_POLLING) ? 1 : status);
if (status) {
activity[tid].poll_io++;