]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: checks: do not queue/wake a bounced check
authorWilly Tarreau <w@1wt.eu>
Fri, 1 Sep 2023 05:41:46 +0000 (07:41 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 1 Sep 2023 06:26:06 +0000 (08:26 +0200)
A small issue was introduced with commit d114f4a68 ("MEDIUM: checks:
spread the checks load over random threads"): when a check is bounced
to another thread, its expiration time is set to TICK_ETERNITY. This
makes it show as not expired upon first wakeup on the next thread,
thus being detected as "woke up too early" and being instantly
rescheduled. Only this after this next wakeup it will be properly
considered.

Several approaches were attempted to fix this. The best one seems to
consist in resetting t->expire and expired upon wakeup, and changing
the !expired test for !tick_is_expired() so that we don't trigger on
this case.

This needs to be backported to 2.7.

src/check.c

index 786c1c61cca1a86846eb1f7d901ee61b75a40c6a..7359c2574da09370a2eb71baa5fa677bdb044197 100644 (file)
@@ -1167,8 +1167,10 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
                 * needs an expiration timer that was supposed to be now, but that
                 * was erased during the bounce.
                 */
-               if (!tick_isset(t->expire))
+               if (!tick_isset(t->expire)) {
                        t->expire = now_ms;
+                       expired = 0;
+               }
        }
 
        if (unlikely(check->state & CHK_ST_PURGE)) {
@@ -1180,7 +1182,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
                 * new state (e.g. fastinter), in which case we'll reprogram
                 * the new timer.
                 */
-               if (!expired) /* woke up too early */ {
+               if (!tick_is_expired(t->expire, now_ms)) { /* woke up too early */
                        if (check->server) {
                                int new_exp = tick_add(now_ms, MS_TO_TICKS(srv_getinter(check)));