mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #3329] [Bug]: store_kv_bench --io-api zcopy always fails on non-NOF builds: "direct hugepage alloc failed for zcopy pool" #845
Labels
No labels
ascend
auto-closed
bug
bug
CI/Build
Common
documentation
enhancement
feature request
good first issue
help wanted
high priority
MetaX
nightly-failure
pull-request
PyTorch Backend
question
RFC
Roadmap
stale
Store
Tests
Transfer Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/Mooncake#845
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @mzygQAQ on GitHub (Aug 7, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/3329
Bug Report
Environment
a2966b6aUSE_NOF=OFF), store wheel built without SPDK/NoF--io-api zcopySummary
Running
mooncake-store/benchmarks/store_kv_bench.pywith--io-api zcopyalways fails during session setup on a memory-only (non-NOF) build:
The benchmark's zcopy path is hard-coupled to the NOF build option, even
though the zero-copy store APIs themselves (
put_from/get_into/batch_put_from/batch_get_into) have nothing to do with NOF and workfine on memory-only clusters.
Steps to reproduce
Memory-only cluster (1+0), no
--nof-replica-num:Note the failure is unrelated to replica count — it triggers before any I/O.
Actual behavior
Expected behavior
--io-api zcopyshould work on non-NOF (memory-only) builds. The zero-copyAPIs are orthogonal to NOF.
Root cause
ZcopyBufferPoolinmooncake-store/benchmarks/store_kv_bench.pyallocatesits registered buffer pool via
get_alloc_func_addr()/get_free_func_addr()(exported inmooncake-integration/store/store_py.cpp),which point to
hugepage_memory_alloc/hugepage_memory_freeinmooncake-store/src/memory_alloc.cpp:hugepage_memory_alloconly has a real implementation when the store is builtwith
USE_NOF=ON(defaultOFF); otherwise it always returnsnullptr, sothe zcopy pool construction always fails. This helper was originally added for
the SPDK/NoF worker pool (#2172) and later reused by the benchmark's zcopy
path (#2273), creating an unintended coupling between
--io-api zcopyand theNOF build option.
Before submitting...
@github-actions[bot] commented on GitHub (Aug 7, 2026):
Thanks for opening this issue, @mzygQAQ!
30590325A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide
@fcczzz commented on GitHub (Aug 7, 2026):
Thanks for the detailed report. I reproduced the allocation failure locally with USE_NOF=OFF.
The root cause is as described: get_alloc_func_addr() is exported in non-NoF builds, but the underlying hugepage_memory_alloc() implementation always returns nullptr. Therefore, ZcopyBufferPool fails before register_buffer() or any Store I/O is reached.
The benchmark should not use this NoF/SPDK-specific allocator for its generic zcopy path. Mooncake already provides the native BufferPool / BufferLease API for zero-copy buffers. It allocates from the Store’s setup-time registered local buffer, which uses normal host memory in non-NoF builds and SPDK DMA memory in NoF builds.
A suitable fix would be to migrate store_kv_bench.py to BufferPool, keep the lease alive for the benchmark lifetime, and require the zcopy pool size to fit within --local-buffer-size unless NoF-safe overflow allocation is explicitly supported.
We should also add a TCP + non-NoF + zcopy regression test.
@030611 commented on GitHub (Aug 9, 2026):
I reproduced the code path and prepared a local migration of
store_kv_bench.pyfrom the NoF/SPDK hugepage helpers to the nativeBufferPool/BufferLeaseAPI.The patch keeps one lease alive for the full benchmark lifetime, uses
lease.ptrfor the existing slot arithmetic, and releases the lease before closing the pool. It also fails early whenvalue_size * slotsexceeds--local-buffer-size, so the generic benchmark does not silently depend on overflow registration semantics.I added a CPU-only regression that imports a store module with
BufferPoolbut no NoF alloc/free helpers, then checks acquisition, slot pointer I/O, cleanup, and the local-buffer capacity guard. The benchmark unit suite passes 7/7,py_compilepasses, andgit diff --checkpasses.Before opening a PR, would you prefer the capacity guard above, or should the benchmark permit
BufferPooloverflow registration on TCP builds? I have not yet run the full TCP +USE_NOF=OFFintegration case on Linux, so I would keep that limitation explicit in the PR.@mzygQAQ commented on GitHub (Aug 10, 2026):
@030611 Sorry, I am just a user of store_kv_bench and haven't read the code carefully, so I can't provide relevant feedback. I suggest you refer to the opinions of other maintainers. Thank you for your PR.