From 85d0424b20c4148a2b1f5b5a4442dd7fed44c562 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 16 Apr 2019 18:09:13 +0200 Subject: [PATCH] BUG/MINOR: listener/mq: correctly scan all bound threads under low load When iterating on the CLI using "show activity" and no other load, it was visible that the last thread was always skipped. This was caused by the way the thread bits were walking : t1 was updated after t2 to make sure it never equals t2 (thus it skips t2), and in case of a tie we choose t1. This results in the chosen thread never to equal t2 unless the other ones already have one connection. In addition to this, t2 was recalulated upon each pass due to the fact that only the 31th bit was looked at instead of looking at the t2'th bit. This patch fixes this by updating t2 after t1 so that t1 is free to walk over all positions under equal load. No measurable performance gains are expected from this though, but it at least removes one strange indicator which could lead to some suspicion. No backport is needed. --- src/listener.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/listener.c b/src/listener.c index d8631883e..3656c821b 100644 --- a/src/listener.c +++ b/src/listener.c @@ -880,15 +880,7 @@ void listener_accept(int fd) m1 = mask >> t1; m2 = mask & (t2 ? nbits(t2 + 1) : ~0UL); - if (unlikely((signed long)m2 >= 0)) { - /* highest bit not set */ - if (!m2) - m2 = mask; - - t2 = my_flsl(m2) - 1; - } - - if (unlikely(!(m1 & 1) || t1 == t2)) { + if (unlikely(!(m1 & 1))) { m1 &= ~1UL; if (!m1) { m1 = mask; @@ -897,6 +889,14 @@ void listener_accept(int fd) t1 += my_ffsl(m1) - 1; } + if (unlikely(!(m2 & (1UL << t2)) || t1 == t2)) { + /* highest bit not set */ + if (!m2) + m2 = mask; + + t2 = my_flsl(m2) - 1; + } + /* now we have two distinct thread IDs belonging to the mask */ q1 = accept_queue_rings[t1].tail - accept_queue_rings[t1].head + ACCEPT_QUEUE_SIZE; if (q1 >= ACCEPT_QUEUE_SIZE)