From b3a84800b4f8246d5c9af62a3a8e2d6d0f6cc76f Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 19 Mar 2026 15:18:32 +0100 Subject: [PATCH] MINOR: task: maintain a per-thread indicator of the peak run-queue size The new field th_ctx->rq_tot_peak contains the computed peak run queue length averaged over the last 512 calls. This is computed when entering process_runnable_tasks. It will not take into account new tasks that are created or woken up during this round nor those which are evicted, which is the reason why we're using a peak measurement to increase chances to observe transient high values. Tests have shown that 512 samples are good to provide a relatively smooth average measurement while still fading away in a matter of milliseconds at high loads. Since this value is only updated once per round, it cannot be used as a statistic and shouldn't be exposed, it's only for internal use (self-regulation). --- include/haproxy/defaults.h | 5 +++++ include/haproxy/tinfo-t.h | 1 + src/task.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/include/haproxy/defaults.h b/include/haproxy/defaults.h index 72a9bc13a..2c9896047 100644 --- a/include/haproxy/defaults.h +++ b/include/haproxy/defaults.h @@ -536,6 +536,11 @@ #define TIME_STATS_SAMPLES 512 #endif +/* number of samples used to measure the load in the run queue */ +#ifndef RQ_LOAD_SAMPLES +#define RQ_LOAD_SAMPLES 512 +#endif + /* max ocsp cert id asn1 encoded length */ #ifndef OCSP_MAX_CERTID_ASN1_LENGTH #define OCSP_MAX_CERTID_ASN1_LENGTH 128 diff --git a/include/haproxy/tinfo-t.h b/include/haproxy/tinfo-t.h index 031b491d8..af74e4ff7 100644 --- a/include/haproxy/tinfo-t.h +++ b/include/haproxy/tinfo-t.h @@ -233,6 +233,7 @@ struct thread_ctx { struct buffer *last_dump_buffer; /* Copy of last buffer used for a dump; may be NULL or invalid; for post-mortem only */ unsigned long long total_streams; /* Total number of streams created on this thread */ unsigned int stream_cnt; /* Number of streams attached to this thread */ + unsigned int rq_tot_peak; /* total run queue size last call */ // around 68 bytes here for shared variables diff --git a/src/task.c b/src/task.c index 8f03b1dda..939a5d8b0 100644 --- a/src/task.c +++ b/src/task.c @@ -738,6 +738,8 @@ void process_runnable_tasks() _HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_STUCK); // this thread is still running + swrate_add_peak_local(&th_ctx->rq_tot_peak, RQ_LOAD_SAMPLES, th_ctx->rq_total); + if (!thread_has_tasks()) { activity[tid].empty_rq++; return; -- 2.47.3