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

openSUSE Build Service is sponsored by