Skip to content

Fix IO-Threads redesign cleanup perf regression from #3544#3938

Merged
madolson merged 2 commits into
valkey-io:unstablefrom
roshkhatri:re-apply-io-threads-cleanup
Jun 9, 2026
Merged

Fix IO-Threads redesign cleanup perf regression from #3544#3938
madolson merged 2 commits into
valkey-io:unstablefrom
roshkhatri:re-apply-io-threads-cleanup

Conversation

@roshkhatri

@roshkhatri roshkhatri commented Jun 8, 2026

Copy link
Copy Markdown
Member

This regression is still present in 9.1 GA as the cherrypick of revert commit was missed during release.

Re-applies #3544 (reverted in #3756 due to ~20% SET regression) with the performance fix from #3760.

Root Cause: The original #3544 changed tryOffloadFreeObjToIOThreads to only offload the SDS buffer free to IO threads, freeing the robj shell on the main thread. I carried out profiling for the change and it showed that freeing the robj shell on the main thread became the prime main-thread hotspot (~10% CPU), while IO threads shifted from doing real jemalloc work to spinning idle on spmcDequeue.

Fix: Keep tryOffloadFreeObjToIOThreads offloading the entire robj (decrRefCount) to the IO thread. Cross-thread zfree is safe with jemalloc.

This PR includes all cleanup work from #3544 so -

  • trySendWriteToIOThreads: defer clearing last_header until after successful enqueue
  • evictClients: simplified bookkeeping
  • Queue sizes as runtime parameters instead of compile-time macros
  • IO ignition policy using stat_active_time instead of getrusage
  • Function renames (IOThreadFreeArgv --> ioThreadFreeArgv, etc.) and doc comments

Benchmark on (Graviton4 c8gb.metal-48xl):
Config: SET, 128B values, 9 IO threads, pipeline=10, 1600 clients - Same as Valkey official method

Version Throughput
Unstable + original #3544 ~1,554K rps
Unstable + this PR ~2,116K rps
Diff vs original #3544 (perf fix)
diff --git a/src/io_threads.c b/src/io_threads.c
--- a/src/io_threads.c
+++ b/src/io_threads.c
@@ // IO thread handler
 case JOB_REQ_FREE_OBJ:
-    zfree(data);
+    decrRefCount(data);
     break;

@@ // tryOffloadFreeObjToIOThreads
-    /* We offload only the free of the ptr that may be allocated by the I/O thread.
-     * The object itself was allocated by the main thread and will be freed by the main thread. */
-    void *job = tagJob(sdsAllocPtr(objectGetVal(obj)), JOB_REQ_FREE_OBJ);
+    void *job = tagJob(obj, JOB_REQ_FREE_OBJ);
     if (unlikely(spmcEnqueue(&io_shared_inbox, job) == false)) return C_ERR;
-    objectSetVal(obj, NULL);
-    decrRefCount(obj);
     io_jobs_submitted++;

Signed-off-by: Roshan Khatri <rvkhatri@amazon.com>
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 987987ab-0ac1-4bc3-8306-833d613c4e03

📥 Commits

Reviewing files that changed from the base of the PR and between c6b38ac and c15b111.

📒 Files selected for processing (2)
  • src/queues.c
  • src/queues.h
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/queues.h
  • src/queues.c

📝 Walkthrough

Walkthrough

This PR refactors the queue infrastructure from compile-time fixed capacities to runtime-configurable sizes, integrates dynamic queue initialization into IO threading, shifts IO thread ignition policy from CPU-time to main-thread active-time metrics, simplifies client eviction logic, and updates unit tests accordingly.

Changes

Queue Infrastructure and IO Threading Refactor

Layer / File(s) Summary
Queue struct and API definitions
src/queues.h
Queue structs (mpscQueue, spmcQueue, spscQueue) gain queue_size field; initialization functions change from parameterless to mpscInit(q, size_t queue_size) signature; compile-time *_QUEUE_SIZE and *_QUEUE_MASK macros are removed.
MPSC queue initialization and operations
src/queues.c
MPSC init allocates dynamic-sized atomic buffer, asserts power-of-two, and initializes per-slot state; enqueue and batch dequeue use runtime capacity masking for slot indexing; fullness checks compare against dynamic queue_size.
SPMC queue initialization and operations
src/queues.c
SPMC init allocates aligned cell array sized to queue_size with per-slot sequence initialization; new spmcIsEmpty and spmcSize helpers use cached/refreshed atomic head; batch dequeue applies sequence-diff retry logic with dynamic masking.
SPSC queue initialization and operations
src/queues.c
SPSC init allocates dynamic-sized buffer and initializes atomic head/tail; fullness checks and conditional publish-on-commit enqueue use runtime queue_size; batch dequeue and two-phase isEmpty apply dynamic masking.
Queue unit test initialization
src/unit/test_queues.cpp
Test fixtures define explicit queue capacity constants (SPSC_QUEUE_SIZE, SPMC_QUEUE_SIZE, MPSC_QUEUE_SIZE) and update SetUp() to call *Init(q, QUEUE_SIZE) with those capacities.
Metrics enum and IO thread header updates
src/server.h, src/io_threads.h
Server metrics enum replaces STATS_METRIC_MAIN_THREAD_CPU_SYS/USER with single STATS_METRIC_MAIN_THREAD_ACTIVE_TIME; io_threads.h adds _Static_assert bounds for JOB_REQ/RES_COUNT ≤ 8 and removes job_handler typedef.
IO thread ignition policy refactor
src/io_threads.c
IO scaling removes RUSAGE_THREAD CPU-time accounting; new ignition logic samples main-thread active-time with 50ms guard and decides scaling via IO_IGNITION_MAIN_THREAD_ACTIVE_PERCENT threshold; queue size constants (IO_MPSC_QUEUE_SIZE, IO_SPMC_QUEUE_SIZE, IO_SPSC_QUEUE_SIZE) defined.
IO thread queue initialization and write offloading
src/io_threads.c
Shared/private queues initialized with explicit capacity constants; deadlock prevention compares pending responses against io_shared_outbox.queue_size instead of fixed constant; write offloading introduces optional clientReplyBlock *block pointer for safe buffer handling, derives io_last_bufpos from block or fallback, and conditionally forces non-replica headers based on encoding state; helper functions renamed to lowercase (IOThreadFreeArgvioThreadFreeArgv, IOThreadPollioThreadPoll).

Client Eviction Loop Simplification

Layer / File(s) Summary
Client eviction loop refactor
src/networking.c
Eviction loop rewritten to remove pending_freed memory tracking and close_asap fast-skip behavior; loop continues while combined server.stat_clients_type_memory[NORMAL/PUBSUB] exceeds limit, logs and frees each selected client, and increments stat_evictedclients only on immediate frees.

Build System

Layer / File(s) Summary
Makefile queues.o update
src/Makefile
Whitespace/indentation change to queues.o line in ENGINE_SERVER_OBJ list.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • valkey-io/valkey#3756: Reverts the main queue sizing, ignition policy, and IO threading changes from this PR back toward fixed-size queues and CPU-time metrics.

Suggested reviewers

  • madolson
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.59% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: re-applying the IO-threads cleanup with a performance fix for a regression from PR #3544.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the root cause, fix, and included cleanup items with benchmark results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/unit/test_queues.cpp (1)

25-33: ⚡ Quick win

Add invalid-size coverage for the new init contract.

These fixtures only exercise valid power-of-two sizes. Since *Init now accepts runtime input, please add death/error-path coverage for 0 and a non-power-of-two value so the mask invariant doesn't regress silently.

As per coding guidelines, "Data-structure and low-level logic changes should be covered by unit tests."

Also applies to: 143-153, 256-265

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/unit/test_queues.cpp` around lines 25 - 33, Add unit-test coverage for
the new runtime init contract by exercising spscInit with invalid sizes: call
spscInit(&q, 0) and spscInit(&q, nonPowerOfTwo) and assert they fail
(death/assert/error) so the mask invariant can't regress; update the test
fixtures around SetUp/SPSC_QUEUE_SIZE and add analogous invalid-size checks in
the other test sections referenced (around lines 143-153 and 256-265) using the
same pattern and test helpers so that ConsumerArg/spscInit behavior is validated
for both zero and a non-power-of-two size.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/networking.c`:
- Around line 6535-6544: The loop is using only current
server.stat_clients_type_memory to decide when to stop evicting and only
increments server.stat_evictedclients when freeClient(c) returns true, which can
cause over-eviction and missed counts for async closes; change the eviction loop
(the loop that references server.stat_clients_type_memory, CLIENT_TYPE_NORMAL,
CLIENT_TYPE_PUBSUB, client_eviction_limit and iterates with
listNext(&bucket_iter)) to use a projected/freed-bytes target so the condition
uses current_memory minus an accumulated freed_estimate instead of live memory
alone, and after calling freeClient(c) always account for the client as evicted
(increment server.stat_evictedclients) and update the projected freed bytes by
the client's memory footprint (or by adjusting server.stat_clients_type_memory
appropriately) whether freeClient returned synchronous (1) or async (0) so the
loop stops at the real target and async-closed clients are counted.

In `@src/queues.c`:
- Around line 12-16: The initializer(s) allow queue_size == 0 because the
power-of-two check passes for zero; update mpscInit (and the other two queue
initializer functions) to explicitly reject zero capacity by changing the
assertion to require queue_size != 0 and a power-of-two (e.g. assert(queue_size
!= 0 && (queue_size & (queue_size - 1)) == 0)); this ensures q->queue_size is
nonzero before setting q->buffer and using q->queue_size - 1 for masking.

---

Nitpick comments:
In `@src/unit/test_queues.cpp`:
- Around line 25-33: Add unit-test coverage for the new runtime init contract by
exercising spscInit with invalid sizes: call spscInit(&q, 0) and spscInit(&q,
nonPowerOfTwo) and assert they fail (death/assert/error) so the mask invariant
can't regress; update the test fixtures around SetUp/SPSC_QUEUE_SIZE and add
analogous invalid-size checks in the other test sections referenced (around
lines 143-153 and 256-265) using the same pattern and test helpers so that
ConsumerArg/spscInit behavior is validated for both zero and a non-power-of-two
size.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2428595b-cad3-43cd-bf15-c08bbf649833

📥 Commits

Reviewing files that changed from the base of the PR and between f7b236d and c6b38ac.

📒 Files selected for processing (8)
  • src/Makefile
  • src/io_threads.c
  • src/io_threads.h
  • src/networking.c
  • src/queues.c
  • src/queues.h
  • src/server.h
  • src/unit/test_queues.cpp

Comment thread src/networking.c
Comment thread src/queues.c
@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.41270% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 76.60%. Comparing base (f7b236d) to head (c15b111).

Files with missing lines Patch % Lines
src/io_threads.c 94.44% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #3938      +/-   ##
============================================
- Coverage     76.68%   76.60%   -0.09%     
============================================
  Files           162      162              
  Lines         80731    80727       -4     
============================================
- Hits          61910    61842      -68     
- Misses        18821    18885      +64     
Files with missing lines Coverage Δ
src/networking.c 92.17% <100.00%> (+0.17%) ⬆️
src/queues.c 99.35% <100.00%> (+0.02%) ⬆️
src/server.h 100.00% <ø> (ø)
src/unit/test_queues.cpp 99.53% <100.00%> (ø)
src/io_threads.c 75.82% <94.44%> (-0.16%) ⬇️

... and 19 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@roshkhatri

Copy link
Copy Markdown
Member Author

@coderabbitai Can you please review this for the perf regression fix for #3544 (reverted in #3756 due to ~20% SET regression) with the performance fix from #3760.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the PR diff
gh pr view 3938 --repo valkey-io/valkey --json files,body,title

# Get the diff
gh pr diff 3938 --repo valkey-io/valkey 2>/dev/null | head -3000

Length of output: 32984


🏁 Script executed:

#!/bin/bash
# Check io_private_inbox initialization for thread 0
rg -n "io_private_inbox" --type c

# Check tryOffloadFreeObjToIOThreads full context
rg -n "tryOffloadFreeObjToIOThreads" --type c -A 20 -B 5

# Check freeClient return value semantics
rg -n "int freeClient" --type c -A 5

# Check stat_active_time usage
rg -n "stat_active_time" --type c -C 3

# Check decrRefCount for thread safety concerns
rg -n "decrRefCount" src/io_threads.c -C 3

# Check if copyright header was intentionally removed from queues.h
git log --oneline -5 -- src/queues.h

Length of output: 10427



@roshkhatri: Thanks for the detailed PR description and benchmark data — the root-cause analysis is solid. Below is my review.


Overall Assessment

The core perf fix is correct and well-motivated. The decrRefCount path in the IO thread is safe because tryOffloadFreeObjToIOThreads gates on refcount == 1 and OBJ_ENCODING_RAW | OBJ_STRING, so the IO thread always takes the single-owner fast-path through freeStringObject → sdsfree, which is safe with jemalloc's cross-thread zfree. The trySendWriteToIOThreads deferral of last_header = NULL to post-enqueue also correctly closes the race. Queue sizing moving to runtime parameters is a clean improvement.

A few things worth addressing:


1. evictClients — "Evicting client" log fires before outcome is known

// src/networking.c
serverLog(LL_NOTICE, "Evicting client: %s", ci);
if (freeClient(c)) server.stat_evictedclients++;

The log message is printed before freeClient(c) is called. If the client is protected or has pending IO, freeClient returns 0 and the client is only scheduled for async close — but the log already says "Evicting client". This can mislead operators into thinking the eviction happened immediately. Consider logging after the fact, or differentiating between immediate and async:

sds ci = catClientInfoString(sdsempty(), c, server.hide_user_data_from_log);
if (freeClient(c)) {
    serverLog(LL_NOTICE, "Evicting client: %s", ci);
    server.stat_evictedclients++;
} else {
    serverLog(LL_NOTICE, "Scheduling async eviction for client: %s", ci);
}
sdsfree(ci);

2. evictClientsstat_evictedclients semantics change

Previously stat_evictedclients was incremented unconditionally for all eviction attempts (including async). Now it counts only immediate frees. This is arguably more correct, but it's a behavioral change in the metric that operators and monitoring tools may rely on. Worth a comment in the code explaining the new semantics, and potentially a changelog/docs note.


3. queues.h — Copyright/license header accidentally removed

The diff removes lines 1–4 of queues.h:

-/*
- * Copyright (c) Valkey Contributors
- * All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause
-```
This looks unintentional — all other files in `src/` retain the license header.

---

### 4. Minor: `_Static_assert` message fix is correct

```diff
-_Static_assert(JOB_REQ_COUNT <= 8, "JOB_REQ_COUNT must not exceed 7 for pointer arithmetic");
+_Static_assert(JOB_REQ_COUNT <= 8, "JOB_REQ_COUNT must not exceed 8 for pointer arithmetic");

Good catch — the old message said "7" but the limit is 8. ✓


5. Minor: IO_IGNITION_MAIN_THREAD_ACTIVE_PERCENT is still compile-time

The PR converts queue sizes to runtime parameters, but the ignition threshold remains a compile-time #define. This is fine for now, but if you ever want to allow runtime tuning (e.g., via config set), keeping it alongside the other IO-thread knobs would be natural. Not blocking.


Summary

Area Status
Core perf fix (decrRefCount in IO thread) ✅ Correct
trySendWriteToIOThreads header race fix ✅ Correct
Queue runtime sizing ✅ Clean
IO ignition policy (active time vs. getrusage) ✅ Simpler, cross-platform
evictClients log ordering ⚠️ Log fires before outcome
stat_evictedclients semantics change ⚠️ Undocumented behavioral change
queues.h copyright header removed 🐛 Looks unintentional
_Static_assert message fix

The three items above are the ones I'd recommend addressing before merge. The perf fix and cleanups are solid work.

@roshkhatri roshkhatri changed the title Re-apply IO-Threads redesign cleanup(#3544) with perf regression fix Fix IO-Threads redesign cleanup perf regression from #3544 Jun 8, 2026
- Restore copyright header in queues.h
- Reject queue_size == 0 in queue initializers (0 passes power-of-two check)

Signed-off-by: Roshan Khatri <rvkhatri@amazon.com>
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Benchmark ran on this commit: c6b38ac

RPS Benchmark Comparison: unstable vs 4a035db

1 significant change(s)

  • ✅ +7±2% SET rps pipe=1 threads=9 (data_size=16)

15 with no significant change

Click to expand full comparison tables

data_size = 128

% Change Test unstable 4a035db unstable stats 4a035db stats
-1±3% GET rps P1 T1 221.3K 218K n=3, σ=778, CV=0.4%, CI95%=±0.9%, PI95%=±1.7% n=3, σ=2.44K, CV=1.1%, CI95%=±2.8%, PI95%=±5.6%
+4±5% GET rps P1 T9 1.56M 1.630M n=3, σ=27.2K, CV=1.7%, CI95%=±4.3%, PI95%=±8.6% n=3, σ=1.92K, CV=0.1%, CI95%=±0.3%, PI95%=±0.6%
-2±2% GET rps P10 T1 1.171M 1.153M n=3, σ=3.91K, CV=0.3%, CI95%=±0.8%, PI95%=±1.7% n=3, σ=6.78K, CV=0.6%, CI95%=±1.5%, PI95%=±2.9%
+1±2% GET rps P10 T9 2.50M 2.529M n=3, σ=23.7K, CV=0.9%, CI95%=±2.4%, PI95%=±4.7% n=3, σ=4.87K, CV=0.2%, CI95%=±0.5%, PI95%=±1.0%
+0±2% SET rps P1 T1 211K 211K n=3, σ=1.44K, CV=0.7%, CI95%=±1.7%, PI95%=±3.4% n=3, σ=1.07K, CV=0.5%, CI95%=±1.3%, PI95%=±2.5%
+1±3% SET rps P1 T9 1.51M 1.524M n=3, σ=15.8K, CV=1.0%, CI95%=±2.6%, PI95%=±5.2% n=3, σ=6.12K, CV=0.4%, CI95%=±1.0%, PI95%=±2.0%
-0.1±0.6% SET rps P10 T1 1.034M 1.033M n=3, σ=1.99K, CV=0.2%, CI95%=±0.5%, PI95%=±1.0% n=3, σ=1.50K, CV=0.1%, CI95%=±0.4%, PI95%=±0.7%
+5±9% SET rps P10 T9 2.04M 2.15M n=3, σ=64.8K, CV=3.2%, CI95%=±7.9%, PI95%=±15.8% n=3, σ=28.4K, CV=1.3%, CI95%=±3.3%, PI95%=±6.6%

data_size = 16

% Change Test unstable 4a035db unstable stats 4a035db stats
-0±2% GET rps P1 T1 231.5K 231K n=3, σ=669, CV=0.3%, CI95%=±0.7%, PI95%=±1.4% n=3, σ=1.90K, CV=0.8%, CI95%=±2.0%, PI95%=±4.1%
+0±1% GET rps P1 T9 1.666M 1.672M n=3, σ=7.85K, CV=0.5%, CI95%=±1.2%, PI95%=±2.3% n=3, σ=5.29K, CV=0.3%, CI95%=±0.8%, PI95%=±1.6%
-1±2% GET rps P10 T1 1.262M 1.250M n=3, σ=6.27K, CV=0.5%, CI95%=±1.2%, PI95%=±2.5% n=3, σ=8.04K, CV=0.6%, CI95%=±1.6%, PI95%=±3.2%
+2±2% GET rps P10 T9 3.20M 3.27M n=3, σ=22.4K, CV=0.7%, CI95%=±1.7%, PI95%=±3.5% n=3, σ=16.8K, CV=0.5%, CI95%=±1.3%, PI95%=±2.6%
+0±2% SET rps P1 T1 222K 222K n=3, σ=1.72K, CV=0.8%, CI95%=±1.9%, PI95%=±3.9% n=3, σ=1.07K, CV=0.5%, CI95%=±1.2%, PI95%=±2.4%
+7±2% SET rps P1 T9 1.52M 1.63M n=3, σ=10.2K, CV=0.7%, CI95%=±1.7%, PI95%=±3.3% n=3, σ=10.9K, CV=0.7%, CI95%=±1.7%, PI95%=±3.3%
+0.7±0.7% SET rps P10 T1 1.059M 1.066M n=3, σ=2.46K, CV=0.2%, CI95%=±0.6%, PI95%=±1.2% n=3, σ=1.85K, CV=0.2%, CI95%=±0.4%, PI95%=±0.9%
+1±2% SET rps P10 T9 2.200M 2.21M n=3, σ=8.05K, CV=0.4%, CI95%=±0.9%, PI95%=±1.8% n=3, σ=17.2K, CV=0.8%, CI95%=±1.9%, PI95%=±3.9%

Configuration:

  • architecture: aarch64
  • benchmark_mode: duration
  • clients: 1600
  • cluster_mode: False
  • duration: 180
  • tls: False
  • valkey_benchmark_threads: 90
  • warmup: 30

Legend:

  • Test column: Command, metric, P=pipeline depth, T=io-threads
  • Significance: ✅ significant improvement, ❌ significant regression, ➖ not significant, ❔ insufficient data

Statistical Notes:

  • CV: Coefficient of Variation - relative variability (σ/μ × 100%)
  • CI95%: 95% Confidence Interval - range where the true population mean is likely to fall
  • PI95%: 95% Prediction Interval - range where a single future observation is likely to fall

@sarthakaggarwal97

Copy link
Copy Markdown
Contributor

@akashkgit please review when you get a chance.

@madolson madolson merged commit 859649d into valkey-io:unstable Jun 9, 2026
63 checks passed
@github-project-automation github-project-automation Bot moved this to To be backported in Valkey 9.1 Jun 9, 2026
sarthakaggarwal97 added a commit that referenced this pull request Jun 24, 2026
The `test io-threads are runtime modifiable` test in
`tests/unit/other.tcl` times out on the dedicated Valgrind jobs of the
daily CI, failing the run. The failing test is introduced in #3938.

This PR reduces the loop to 10 iterations under Valgrind.

**Failure links:**
- https://github.com/valkey-io/valkey/actions/runs/27386948127 (Jun 12)
- https://github.com/valkey-io/valkey/actions/runs/27315974006 (Jun 11)
- https://github.com/valkey-io/valkey/actions/runs/27245311034 (Jun 10)

---------

Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com>
valkeyrie-ops Bot pushed a commit that referenced this pull request Jun 25, 2026
The `test io-threads are runtime modifiable` test in
`tests/unit/other.tcl` times out on the dedicated Valgrind jobs of the
daily CI, failing the run. The failing test is introduced in #3938.

This PR reduces the loop to 10 iterations under Valgrind.

**Failure links:**
- https://github.com/valkey-io/valkey/actions/runs/27386948127 (Jun 12)
- https://github.com/valkey-io/valkey/actions/runs/27315974006 (Jun 11)
- https://github.com/valkey-io/valkey/actions/runs/27245311034 (Jun 10)

---------

Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To be backported

Development

Successfully merging this pull request may close these issues.

3 participants