已关闭
[Bug-Report|缺陷反馈]: 服务端向多个 Endpoint 注册内存时,后续注册失败未回滚前序成功注册 #716
Polaris创建于 17 天前关闭于 13 天前
16 天前 将 lining23666 设为负责人
lining23666
16 天前 评论:
16 天前 评论:
感谢反馈,经代码检视确认该问题有效。
问题确认
HixlCSServer::RegisterMem(src/hixl/cs/hixl_cs_server.cc:322)在多 Endpoint 注册场景下确实缺少失败回滚:
- 注册循环中任一 Endpoint 注册失败时,
HIXL_CHK_STATUS_RET(hixl_cs_server.cc:346)直接返回错误,ep_mem_infos中已成功注册的 Endpoint 不会被注销; - 聚合句柄仅在全部注册成功后写入
reg_mems_(hixl_cs_server.cc:358),失败路径下调用方无法通过HixlCSServerUnregMem清理残留注册。
影响评估
- 残留注册在 Endpoint 销毁时由
Endpoint::Finalize兜底清理(endpoint.cc:142),不会永久泄漏;但在 server 存续期间会占用 HCCL 侧注册资源,且调用方重试RegisterMem会造成重复注册,进一步放大资源占用; - client 侧仅向单个 local endpoint 注册(hixl_cs_client.cc:399),不受此问题影响。
修复方案
将采用失败原子性回滚:注册循环中任一 Endpoint 失败时,对本次已成功注册的 Endpoint 逐个执行 DeregisterMem 后再返回失败,与 Endpoint::RegisterMem 内部已有的回滚模式保持一致。同时会参考您提供的测试思路补充 UT(后续注册失败时校验 Unreg 调用次数与活跃注册数)。
修复 PR 会关联本 issue,欢迎继续关注与检视。


Llining23666
16 天前 关联了pull request:[bugfix]: roll back registered endpoints when server RegisterMem fails (#716)
16 天前 关联了pull request:[bugfix]: roll back registered endpoints when server RegisterMem fails (#716)
lining23666
16 天前 评论:
16 天前 评论:
修复 PR 已提交:https://gitcode.com/cann/hixl/pull/1120 ,CI 已通过,欢迎检视。


lining23666
15 天前 评论:
15 天前 评论:
修复 PR 已合入:[bugfix]: roll back registered endpoints when server RegisterMem fails (#716)


15 天前 添加了label:wait-feedback
Llining23666
15 天前 关联了pull request:[bugfix]: roll back registered endpoints when server RegisterMem fails
15 天前 关联了pull request:[bugfix]: roll back registered endpoints when server RegisterMem fails
13 天前 issue状态由 待办的 改变为 已完成
13 天前 关闭了 issue
13 天前 添加了label:resolved
在您提交issue前,请确认以下信息:
问题定位请提供通信两端报错日志!
问题描述
问题描述
HixlCSServer::RegisterMem会依次向所有匹配的 Endpoint 注册同一块内存。当前实现中,如果前一个 Endpoint 注册成功,而后续 Endpoint 注册失败,HIXL_CHK_STATUS_RET会直接返回错误,但此前已成功完成的 Endpoint 注册不会被注销或回滚。相关代码路径
src/hixl/cs/hixl_cs_server.ccHixlCSServer::RegisterMemendpoint->RegisterMem(...)的循环内部实际行为
接口返回失败,但底层仍保留部分成功注册状态。第一个 Endpoint 的注册句柄只存在于
HixlCSServer::RegisterMem的局部ep_mem_infos中。由于函数在写入服务端reg_mems_之前已经返回,调用方无法获得可用于HixlCSServerUnregMem的聚合句柄,因此无法通过正常公开接口清理这部分注册。环境信息
HIXL 版本
cann/hixl884aad902480132a9ef3aadc73690e9fc53e590b操作系统
编译环境
重现步骤
1. 检出被测试版本
2. 应用复现测试补丁
修改以下 3 个测试相关文件:
补丁内容包括:
SetMemRegFailureOnCall,允许指定第 N 次HcommMemReg返回指定错误;HcommMemReg和HcommMemUnreg的调用次数;测试创建两个 Host
UBC_CTPEndpoint,并执行:SetMemRegFailureOnCall(2U, HCCL_E_INTERNAL);即:
HcommMemReg正常成功;HcommMemReg返回HCCL_E_INTERNAL。随后调用
HixlCSServerRegMem,并检查:EXPECT_EQ(GetMemRegCallCount(), 2U); EXPECT_EQ(GetMemUnregCallCount(), 1U); EXPECT_EQ(GetActiveMemRegCount(), 0U);3. 加载 CANN 环境并运行 HIXL C++ Suite
source /usr/local/Ascend/cann/set_env.sh bash tests/run_test.sh -t cpp -s hixl测试目标能够正常构建,但新增测试失败。Suite 的退出码为 1,唯一失败项为:
4. 定向运行复现测试
连续执行 3 次,三次结果完全一致:
HcommMemUnreg实际/预期0 / 11 / 00 / 11 / 00 / 11 / 0问题可以稳定复现。
预期结果
RegisterMem应保证失败原子性:任一 Endpoint 注册失败时,应回滚本次已成功注册的所有 Endpoint,确保接口返回失败后不残留注册状态;如果设计上无法回滚,则应返回可供调用方清理的句柄或信息。日志 / 截图
实际失败日志
日志证明:
HcommMemUnreg,实际注销次数为 0;附件
04be92372b8a4ca3bac1a9ba8038df67.log
86b4fe138de7406895ef3dd39c692105.log
备注