Repository navigation
Description
OCm 多进程共享注册主机内存崩溃问题 — 求助描述
环境
硬件:4 × AMD RX 7900 XTX(gfx1100,RDNA3),单颗 EPYC 7K62(48核96线程),128GB DDR4-3200 ECC,NVMe
系统:Ubuntu 24.04.5,内核 6.8.0-147,amdgpu 内核驱动(系统自带,四卡识别正常)
ROCm 用户态:TheRock pip 轮子(装在 venv 内),先后试过 7.10.0a20251120 和 7.14.0a20260612,均复现
应用:Strata 推理引擎 0.1.45(https://github.com/Niko1221/Strata,C++/HIP),LLM MoE 推理,64GB 共享专家池
相关配置:BIOS 未动,内核已试过 iommu=pt ttm.pages_limit=67108864 ttm.page_pool_size=67108864 + amdgpu gttsize=262144(无效)
想做什么(业务目标)
4 个独立引擎进程(数据并行,每个进程独占一张卡)共享同一份 64GB 专家权重:权重放在一个 MAP_SHARED 文件(/dev/shm/tmpfs,也试过 NVMe 上的普通文件)里,每个进程 mmap 后用 cudaHostRegister(hipHostRegister)(base, 64GB, Portable|Mapped) 注册给自己的 GPU,供 PCIe DMA 零拷贝直读。这是 Strata 引擎自带的 --shared-expert-arena 功能(带魔数+哈希头校验,首个进程创建,后续进程验证后映射同一物理页)。
现象
1 个或 2 个进程这样注册 + 跑推理:完全正常(2 进程实测 50.6 tok/s/进程,连续稳定服务)
4 个进程:每个进程都注册成功、装载完成、打印 "session is up",随后在启动尾声(验证窗口/首个 GEMM 分配处)SIGSEGV,四个进程几乎同时崩,受害者随机
3 进程未单独测;2 与 4 之间是分界
没有 3 进程同时就不行的硬证据,但 4 进程是确定性崩溃(多轮复现)
崩溃证据
dmesg(四个进程同一指令偏移,空指针):
text
strata[...]: segfault at 8 ip ...b71c9 ... error 6 in libamdhip64.so.7
gdb backtrace(ROCm 7.10 版,7.14 同样崩但未再符号化):
text
#0-#5 libamdhip64.so.7 内部(无符号,同一偏移 b71c9)
#6 strata::core::Verifier::init(...) ← 引擎在初始化验证窗口(分配 device buffer / pinned host buffer)
#7 main ()
已排除(全部无效)
去掉 cudaHostRegisterPortable 标志(自打引擎补丁,每进程只向自己的卡注册)→ 仍崩
STRATA_ARENA_PIN_GIB=27 削减每进程注册量到 25GB(4×25=100GB < 2进程×56=112GB 已验证安全的总量)→ 仍崩(排除"注册总字节超限")
HSA_USERPTR_FOR_PAGED_MEM=0 → 仍崩
tmpfs(/dev/shm) vs NVMe 普通文件做映射后端 → 都崩
ROCm 7.10 → 7.14 升级 → 仍崩
内核 iommu=pt + GTT 256GB(ttm.pages_limit/amdgpu.gttsize)→ 仍崩
RLIMIT_MEMLOCK=infinity 已设;无 OOM(dmesg 干净);内存余量充足(总占用 ~74GB/125GB)
我们的判断
进程内视角 2 进程与 4 进程完全相同(同样的映射+注册+装载),所以触发条件在系统级全局资源上:嫌疑集中在 amdgpu/KFD 驱动对"多个进程注册同一批物理页"的处理——某个内部查找返回 null 未被运行时检查。KFD 每进程队列/doorbell、GTT 表项、IOMMU 映射都查过或调过参,均未命中。
想请教的问题
有没有人见过 ROCm 下多进程 hipHostRegister 同一共享内存映射的类似崩溃或已知限制(进程数阈值)?
KFD/amdgpu 有没有未文档化的参数与此相关(如每进程绑定数、共享绑定上限)?
有没有推荐的诊断手段能进一步定位(amdttd/ROCr tracing、KFD debug 接口等)?
旁路建议:除了"每进程私有拷贝"(内存不够)之外,还有什么办法让 4 个进程零拷贝共享一份大权重给各自 GPU?(GPU一侧的shared memory/peer access不适用——每进程各用一张不同的卡)
English summary (for AMD/ROCm communities)
SIGSEGV in libamdhip64 when 4 processes hipHostRegister the same 64GB MAP_SHARED region (2 processes fine)
4x RX 7900 XTX (gfx1100), EPYC 7K62, 128GB RAM, Ubuntu 24.04.5, kernel 6.8.0-147
ROCm userspace from TheRock wheels: 7.10.0a20251120 and 7.14.0a20260612 both affected
Data-parallel engines, one process per GPU, sharing one 64GB expert-weight pool backed by a MAP_SHARED tmpfs file (also tried a regular file): each process mmaps it and calls cudaHostRegister(hipHostRegister)(Portable|Mapped) on the whole range for zero-copy PCIe reads
With 1-2 processes: registration succeeds, inference runs stable for hours. With 4 processes: all four register OK, reach "session is up", then SIGSEGV almost simultaneously at the next allocation phase (Verifier::init → 5 internal HIP frames → fault at address 8, identical instruction offset in libamdhip64.so.7 in every process, victim varies per run)
Ruled out: Portable flag (registered per-device only — still crashes), registration size cap (4x25GB < proven-safe 2x56GB — still crashes), HSA_USERPTR_FOR_PAGED_MEM=0, tmpfs vs file backing, ROCm 7.10→7.14, kernel iommu=pt + GTT enlarged to 256GB (ttm.pages_limit + amdgpu.gttsize), RLIMIT_MEMLOCK=infinity, OOM (none; plenty of free RAM)
Suspicion: a KFD/amdgpu-side limit or race when N≥3-4 processes register the same physical pages, leaving a null internal descriptor that the runtime dereferences
Questions: known limitation or threshold for multi-process hipHostRegister of shared pages? Undocumented KFD knobs? Recommended tracing to pin it down? Alternative ways for 4 processes (one GPU each) to zero-copy share one large host weight buffer?
Activity
jangatzke commentedon Oct 18, 2026
This issue is hard to read because of the mix of Chinese and Englisch. You may want to post in Englisch to increase your chance of getting help. ;)
Niko1221 commentedon Oct 19, 2026
Thanks for taking the time to report this.
We're resetting the tracker for 0.2.0-beta. There are more than 1,300 open issues and pull requests, too many for us to read properly, so we're closing everything that isn't being worked on right now. Closed here does not mean rejected.
To reopen it takes about two minutes:
/reopen. A check runs and either reopens the issue or lists what is still missing.The rules are in CONTRIBUTING.md.