[Store] pin host segments with quota#2945
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a mechanism to register Store-managed host segments as pinned memory in CUDA-enabled builds, managed by a new RegisteredPinnedMemoryManager and configured via environment variables. Feedback on the changes suggests leaking the singleton instance of the manager to prevent potential crashes on program exit due to static destruction order issues, and refactoring the environment variable parsing to use std::from_chars instead of std::strtoull for safer, locale-independent parsing.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
he-yufeng
left a comment
There was a problem hiding this comment.
Read through the whole thing — the manager and the real_client wiring. This is careful work and the correctness-sensitive parts hold up well:
- The quota check is overflow-safe (
size > limit_bytes_ || pinned_bytes_ > limit_bytes_ - sizerather thanpinned_bytes_ + size > limit_bytes_), and the reserve-then-commit split — insert the key with anullptrplaceholder under the lock,cudaHostRegisteroutside the lock, then commit the pointer — keeps a single owner per(addr, size)since theemplaceis exclusive. A concurrenttry_pinfor the same key fails at the placeholder insert, sorelease's window between "mark nullptr" and "erase" can't be hijacked. - Failure paths refund correctly: a failed
cudaHostRegistercallsdrop_reservation_locked(placeholder removed, quota returned) and falls back to pageable, andcudaGetLastError()clears the sticky error. The env parse is properly guarded (std::from_chars+ explicit negative check + trim, invalid → disabled) rather than a barestoull. - Lifetime is right: the region
shared_ptris held insetup_segment_pinned_regions_for the segment's life and released on teardown, and the pin is dropped ifMountSegmentfails. Scope is correctly limited to Store host segments.
Two things I'd like to resolve before approving, neither a correctness bug:
-
release()escalates a non-unloadingcudaHostUnregisterfailure toLOG(FATAL). For a long-running Store process, aborting on a pin-bookkeeping unregister failure is a heavy response — the alternative isLOG(ERROR)and leak the pin so the service survives a transient CUDA hiccup. ThecudaErrorCudartUnloadingcase is already handled gracefully; is aborting on the other errors the intended contract, or would you rather degrade? (TheLOG(FATAL)in thetry_pintracking-mismatch path is fine as an assert — that branch is unreachable given the single-owner invariant.) -
There are no tests, but the second constructor taking
std::pair<bool, uint64_t> configis an obvious seam for them. ThecudaHostRegister/Unregistercalls are the real barrier to full coverage, but the reservation math — over-quota returnsnullptr, overlap returnsnullptr, exact-key double-pin returnsnullptr, quota is refunded after release — is the part most worth locking down, and it's the part most likely to drift later. Worth a small unit test around the manager's bookkeeping even if the CUDA path stays CI-only.
Design and the careful bookkeeping look good; happy to approve once the FATAL question is settled.
@he-yufeng I've updated this part to be availability-first.
Test cases are added.
|
Description
This PR adds opt-in CUDA pinned-memory registration for Mooncake Store-managed host segment memory.
The pinned memory is limited to Store segment memory only. It does not pin client local buffers, staging buffers, dummy-client SHM buffers, user-provided buffers, file-backed
mountSegment()mappings, CXL/device segments, or tensor-wrapper temporary buffers.The feature is disabled by default and controlled by a process-wide quota:
MC_STORE_PIN_MEMORY_MAX_BYTES=<bytes>enables pinned registration up to the configured quota.0, or invalid values disable the feature.MC_STORE_PIN_MEMORY=0|false|off|noexplicitly disables the feature.When enabled, Store host segments are registered with
cudaHostRegister()after allocation and before the segment is mounted. Registration failures fall back to pageable memory so Store startup and allocation remain usable.This PR is intentionally scoped to Store segment memory. GPU-destination reads still copy through the client local buffer / staging path before the final CPU -> GPU copy, so
getonly sees a smaller improvement. Removing or pinning that final staging path is follow-up work and is not part of this PR.The tensor wrapper path is also not the primary target of this PR.
put_tensor(cuda)currently goes throughput_parts, which still stages through the client local buffer before writing into Store. Optimizing tensor /put_partsto avoid that staging copy is also follow-up work.This PR is split from #2598.
Module
Type of Change
How Has This Been Tested?
Manual performance validation
Manual benchmark on one NVIDIA A10 GPU, local TCP Store setup, 4 GiB Store segment, 2 GiB client local buffer.
Baseline:
MC_STORE_PIN_MEMORY_MAX_BYTES=0Pinned Store segment:
MC_STORE_PIN_MEMORY_MAX_BYTES=4294967296The benchmark directly exercised the lower-level Store APIs with CUDA source/destination buffers.
The main improvement is on GPU-source writes, where the Store segment is the host destination of the device-to-host copy.
Read-side GPU destinations improve less because the current read path still stages through the client local buffer before the final CPU -> GPU copy. Optimizing that staging path is follow-up work.
Checklist
AI Assistance Disclosure