From: Willy Tarreau Date: Fri, 1 Sep 2023 05:41:46 +0000 (+0200) Subject: BUG/MINOR: checks: do not queue/wake a bounced check X-Git-Tag: v2.9-dev5~86 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=48442b8b156b3d7b7e99cdeb6decc1314b3e286d;p=thirdparty%2Fhaproxy.git BUG/MINOR: checks: do not queue/wake a bounced check 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. --- diff --git a/src/check.c b/src/check.c index 786c1c61cc..7359c2574d 100644 --- a/src/check.c +++ b/src/check.c @@ -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)));