BUG/MEDIUM: stream: use non-blocking freq_ctr calls from the stream dumper
authorWilly Tarreau <w@1wt.eu>
Fri, 21 Feb 2025 17:23:23 +0000 (18:23 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 18 Mar 2025 15:15:29 +0000 (16:15 +0100)
The stream dump function is called from signal handlers (warning, show
threads, panic). It makes use of read_freq_ctr() which might possibly
block if it tries to access a locked freq_ctr in the process of being
updated, e.g. by the current thread.

Here we're relying on the non-blocking API instead. It may return incorrect
values (typically smaller ones after resetting the curr counter) but at
least it will not block.

This needs to be backported to stable versions along with the previous
commit below:

   MINOR: freq_ctr: provide non-blocking read functions

At least 3.1 is concerned as the warnings tend to increase the risk of
this situation appearing.

(cherry picked from commit 3c22fa315bcb2945d588cb64302f6ba5c89b382e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 124c6cdb13e0f7c03fb9232f429eb58f7d3c4742)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>

src/stream.c

index 2e6bed2..698ecb3 100644 (file)
@@ -3295,7 +3295,8 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
                      "%s  task=%p (state=0x%02x nice=%d calls=%u rate=%u exp=%s tid=%d(%d/%d)%s", pfx,
                     strm->task,
                     strm->task->state,
-                    strm->task->nice, strm->task->calls, read_freq_ctr(&strm->call_rate),
+                    strm->task->nice, strm->task->calls,
+                    read_freq_ctr_period_estimate(&strm->call_rate, MS_TO_TICKS(1000)),
                     strm->task->expire ?
                             tick_is_expired(strm->task->expire, now_ms) ? "<PAST>" :
                                     human_time(TICKS_TO_MS(strm->task->expire - now_ms),
@@ -3376,7 +3377,8 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
                              tmpctx->st1,
                              tmpctx->applet->name,
                              tmpctx->t->tid,
-                             tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate));
+                             tmpctx->t->nice, tmpctx->t->calls,
+                             read_freq_ctr_period_estimate(&tmpctx->call_rate, MS_TO_TICKS(1000)));
        }
 
        scb = strm->scb;
@@ -3437,7 +3439,8 @@ void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const ch
                              tmpctx->st1,
                              tmpctx->applet->name,
                              tmpctx->t->tid,
-                             tmpctx->t->nice, tmpctx->t->calls, read_freq_ctr(&tmpctx->call_rate));
+                             tmpctx->t->nice, tmpctx->t->calls,
+                             read_freq_ctr_period_estimate(&tmpctx->call_rate, MS_TO_TICKS(1000)));
        }
 
        if (HAS_FILTERS(strm)) {