From: Frederic Lecaille Date: Fri, 21 Aug 2026 16:26:38 +0000 (+0200) Subject: BUG/MINOR: haload: split the rate exactly across threads X-Git-Tag: v3.5-dev6~83 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=98093c5105fdc7b04c7ceb3348f010fa52ac1986;p=haproxy.git BUG/MINOR: haload: split the rate exactly across threads hld_usr_schedule() and hld_rate_task() gave every thread ceil(rate / arg_thrd), so a low rate on a machine with many threads was quietly served several times over (e.g. rate=1 on 200 threads gave ~200 req/s instead of 1). Use the same exact split already used elsewhere in haload (thread gets (rate + tid) / arg_thrd): most threads then get 0 and only of them get 1, so the total always matches regardless of the thread count. A thread with no budget now just checks back in 1s instead of being bumped to 1 by the old max ? max : 1 fallback. --- diff --git a/src/haload.c b/src/haload.c index fa44cd931..0dbae94c6 100644 --- a/src/haload.c +++ b/src/haload.c @@ -1413,11 +1413,19 @@ static inline void hld_usr_schedule(struct hld_usr *usr, int rate) if (ti->curusrs < maxusrs && throttle) max = 0; else if (throttle) - max = (mul32hi(rate, throttle) + arg_thrd - 1) / arg_thrd; + max = (mul32hi(rate, throttle) + tid) / arg_thrd; else - max = (rate + arg_thrd - 1) / arg_thrd; + max = (rate + tid) / arg_thrd; + + if (!max) { + /* this thread has no budget right now (its exact share of + * is 0, or it's still ramping up under -s): nothing + * to send from here, just check back shortly. + */ + task_schedule(usr->task, tick_add(now_ms, MS_TO_TICKS(1000))); + return; + } - max = max ? max : 1; wait = hld_next_event_delay(&ti->req_rate, max, ti->curusrs - ti->cur_req, date); task_schedule(usr->task, tick_add(now_ms, MS_TO_TICKS(wait)));