File 6272-erts-Boost-thread-progress-later-op-execution.patch of Package erlang
From f35fd26f29730bac2b68353b66a03cd71aac2a57 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Thu, 6 Oct 2022 15:41:47 +0200
Subject: [PATCH 2/2] erts: Boost thread progress later op execution
to keep up and not lag behind for too long.
Symptom seen:
ets_SUITE:table_leak memory consumption running amok
as scheduled later ops to free large lock arrays could not keep up.
---
erts/emulator/beam/erl_process.c | 17 ++++++++++++++---
erts/emulator/beam/erl_process.h | 1 +
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index d4d7130e0f..5c9bf248f2 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -2258,17 +2258,24 @@ handle_canceled_timers_thr_prgr(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, i
/*
* Handle scheduled thread progress later operations.
*/
-#define ERTS_MAX_THR_PRGR_LATER_OPS 50
+#define ERTS_MIN_THR_PRGR_LATER_OPS 50
static ERTS_INLINE erts_aint32_t
handle_thr_prgr_later_op(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting)
{
- int lops;
+ int lops, limit;
ErtsThrPrgrVal current = haw_thr_prgr_current(awdp);
ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp));
- for (lops = 0; lops < ERTS_MAX_THR_PRGR_LATER_OPS; lops++) {
+ /*
+ * Boost loop limit proportional to number of queued later ops
+ * in order to always keep up.
+ */
+ limit = (awdp->later_op.list_len / 8
+ + ERTS_MIN_THR_PRGR_LATER_OPS);
+
+ for (lops = 0; lops < limit; lops++) {
ErtsThrPrgrLaterOp *lop = awdp->later_op.first;
if (!erts_thr_progress_has_reached_this(current, lop->later))
@@ -2277,6 +2284,7 @@ handle_thr_prgr_later_op(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int wait
if (!awdp->later_op.first) {
awdp->later_op.last = NULL;
}
+ awdp->later_op.list_len--;
lop->func(lop->data);
if (!awdp->later_op.first) {
awdp->later_op.size = thr_prgr_later_cleanup_op_threshold;
@@ -2309,6 +2317,7 @@ enqueue_later_op(ErtsSchedulerData *esdp,
else
awdp->later_op.last->next = lop;
awdp->later_op.last = lop;
+ awdp->later_op.list_len++;
set_aux_work_flags_wakeup_nob(esdp->ssi,
ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP);
return later;
@@ -5837,6 +5846,8 @@ init_aux_work_data(ErtsAuxWorkData *awdp, ErtsSchedulerData *esdp,
awdp->later_op.size = 0;
awdp->later_op.first = NULL;
awdp->later_op.last = NULL;
+ awdp->later_op.list_len = 0;
+
awdp->async_ready.need_thr_prgr = 0;
awdp->async_ready.thr_prgr = ERTS_THR_PRGR_VAL_WAITING;
awdp->async_ready.queue = NULL;
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 8dc55a8da0..949727d950 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -581,6 +581,7 @@ typedef struct ErtsAuxWorkData_ {
UWord size;
ErtsThrPrgrLaterOp *first;
ErtsThrPrgrLaterOp *last;
+ Uint list_len;
} later_op;
struct {
int need_thr_prgr;
--
2.35.3