]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: pollers: clear the sleeping bit after waking up, not before
authorWilly Tarreau <w@1wt.eu>
Fri, 30 Jul 2021 08:57:09 +0000 (10:57 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 30 Jul 2021 08:57:09 +0000 (10:57 +0200)
A bug was introduced in 2.1-dev2 by commit 305d5ab46 ("MAJOR: fd: Get
rid of the fd cache."). Pollers "poll" and "evport" had the sleeping
bit accidentally removed before the syscall instead of after. This
results in them not being woken up by inter-thread wakeups, which is
particularly visible with the multi-queue accept() and with queues.

As a work-around, when these pollers are used, "nbthread 1" should
be used.

The fact that it has remained broken for 2 years is a great indication
that threads are definitely not enabled outside of epoll and kqueue,
hence why this patch is only tagged medium.

This must be backported as far as 2.2.

src/ev_evports.c
src/ev_poll.c

index 09a48a4d986ddccf8a348352037fc51b261df342..9dc5728c648e8eac4810d8fba8dea9d115b391d4 100644 (file)
@@ -152,8 +152,6 @@ static void _do_poll(struct poller *p, int exp, int wake)
        }
 
        thread_harmless_now();
-       if (sleeping_thread_mask & tid_bit)
-               _HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
 
        /*
         * Determine how long to wait for events to materialise on the port.
@@ -206,6 +204,8 @@ static void _do_poll(struct poller *p, int exp, int wake)
        tv_leaving_poll(wait_time, nevlist);
 
        thread_harmless_end();
+       if (sleeping_thread_mask & tid_bit)
+               _HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
 
        if (nevlist > 0)
                activity[tid].poll_io++;
index 4ed1b9e84d03bf414c1898649de3079d617a5d20..f973d08bcddf978cfecebc1a5e2acbe1626ed754 100644 (file)
@@ -165,8 +165,6 @@ static void _do_poll(struct poller *p, int exp, int wake)
        } while (!_HA_ATOMIC_CAS(&maxfd, &old_maxfd, new_maxfd));
 
        thread_harmless_now();
-       if (sleeping_thread_mask & tid_bit)
-               _HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
 
        fd_nbupdt = 0;
 
@@ -210,6 +208,8 @@ static void _do_poll(struct poller *p, int exp, int wake)
        tv_leaving_poll(wait_time, status);
 
        thread_harmless_end();
+       if (sleeping_thread_mask & tid_bit)
+               _HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
 
        if (status > 0)
                activity[tid].poll_io++;