From bf46b91f9a106084d1d4e8bb30cd6a849f1d33b5 Mon Sep 17 00:00:00 2001 From: Atirna <288419661+atirna@users.noreply.github.com> Date: Sat, 15 Aug 2026 19:36:35 +0530 Subject: [PATCH] fix(mem): honor explicit worker budget override Signed-off-by: Atirna <288419661+atirna@users.noreply.github.com> --- src/foundation/mem.c | 17 +++++++++++++---- tests/test_mem.c | 17 +++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/foundation/mem.c b/src/foundation/mem.c index c3462b11a..26a542104 100644 --- a/src/foundation/mem.c +++ b/src/foundation/mem.c @@ -248,10 +248,19 @@ cbm_mem_budget_t cbm_mem_resolve_budget(size_t total_ram, double ram_fraction, cbm_mem_budget_t cbm_mem_resolve_budget_capped(size_t total_ram, double ram_fraction, const char *budget_mb, size_t hard_cap_bytes) { cbm_mem_budget_t result = cbm_mem_resolve_budget(total_ram, ram_fraction, budget_mb); - if (hard_cap_bytes > 0 && (result.budget == 0 || result.budget > hard_cap_bytes)) { - result.budget = hard_cap_bytes; - result.source = "daemon_worker_cap"; - result.hard_capped = true; + /* CBM_MEM_BUDGET_MB is the user-facing emergency override for a single + * large index. Applying the daemon's equal-share cap after resolving it + * makes a requested raise indistinguishable from the default and leaves a + * worker stuck at a quarter of the host budget (#1654). The normal + * fraction-derived path remains capped, preserving aggregate admission for + * concurrent jobs; an explicit value remains clamped to detected RAM by + * cbm_mem_resolve_budget(). */ + if (result.source == NULL || strcmp(result.source, "CBM_MEM_BUDGET_MB") != 0) { + if (hard_cap_bytes > 0 && (result.budget == 0 || result.budget > hard_cap_bytes)) { + result.budget = hard_cap_bytes; + result.source = "daemon_worker_cap"; + result.hard_capped = true; + } } return result; } diff --git a/tests/test_mem.c b/tests/test_mem.c index 7b0e73d01..2453d13d1 100644 --- a/tests/test_mem.c +++ b/tests/test_mem.c @@ -490,7 +490,12 @@ TEST(resolve_budget_override_when_total_unknown) { PASS(); } -TEST(resolve_budget_worker_cap_preserves_lower_user_override) { +/* A user who explicitly raises CBM_MEM_BUDGET_MB must not be silently reduced + * by the daemon's capacity slice. The parent-level slice still protects the + * default path, but the explicit override is the documented escape hatch for a + * single large index (#1654). Before the fix, a 64 MiB request was reported as + * daemon_worker_cap at 16 MiB instead of honoring the requested 64 MiB. */ +TEST(resolve_budget_worker_cap_honors_explicit_override) { size_t total = 8192 * CBM_TEST_MB; size_t worker_cap = 16 * CBM_TEST_MB; cbm_mem_budget_t lower = cbm_mem_resolve_budget_capped(total, 0.5, "8", worker_cap); @@ -498,10 +503,10 @@ TEST(resolve_budget_worker_cap_preserves_lower_user_override) { ASSERT_STR_EQ(lower.source, "CBM_MEM_BUDGET_MB"); ASSERT_FALSE(lower.hard_capped); - cbm_mem_budget_t capped = cbm_mem_resolve_budget_capped(total, 0.5, "64", worker_cap); - ASSERT_EQ(capped.budget, worker_cap); - ASSERT_STR_EQ(capped.source, "daemon_worker_cap"); - ASSERT_TRUE(capped.hard_capped); + cbm_mem_budget_t raised = cbm_mem_resolve_budget_capped(total, 0.5, "64", worker_cap); + ASSERT_EQ(raised.budget, 64 * CBM_TEST_MB); + ASSERT_STR_EQ(raised.source, "CBM_MEM_BUDGET_MB"); + ASSERT_FALSE(raised.hard_capped); PASS(); } @@ -1288,7 +1293,7 @@ SUITE(mem) { RUN_TEST(resolve_budget_override_wins); RUN_TEST(resolve_budget_override_clamped_to_total); RUN_TEST(resolve_budget_override_when_total_unknown); - RUN_TEST(resolve_budget_worker_cap_preserves_lower_user_override); + RUN_TEST(resolve_budget_worker_cap_honors_explicit_override); RUN_TEST(resolve_budget_invalid_override_falls_back); RUN_TEST(resolve_budget_override_overflow_clamps_to_total); RUN_TEST(resolve_budget_override_overflow_total_unknown_caps);