Pull Request已成功合入, 合并人@CANN-robot
(感谢 littlemons 的贡献)变更摘要
本 PR 重构远端内存(远端导入/注销)的管理归属:将原位于进程级 RoceRegedMemMgr/UbRegedMemMgr 中的 MemoryImport/MemoryUnimport 逻辑整体迁移到新增的 Endpoint 实例级 wrapper RemoteMemMgrBase(派生 RoceRemoteMemMgr/UbRemoteMemMgr),进程级 mgr 只保留本端注册/注销/导出能力。各 Endpoint(cpu_roce_endpoint、cpu_urma_endpoint、uboe_endpoint、urma_endpoint、ub_rtp_endpoint)不再将 regedMemMgr_ 强转为具体进程级类型,而是将进程级 mgr 包成实例级 wrapper 后以 RegedMemMgr 基类指针持有。远端内存归属键由仅 endpointDesc 扩展为 {endpointDesc, pid}(新增 RemoteMemOwnerKey),内存描述符(memDesc)尾部追加 u64 pid 字段,同描述符重复导入改为幂等叠加实例内引用计数(不再返回 HCCL_E_AGAIN),以解决多个 Endpoint 实例共享进程级 mgr 时的重复导入报错与引用泄漏问题。
主要改动
- 新增实例级远端内存管理 wrapper(
endpoint_remote_mem_mgr.h): 新增模板类RemoteMemMgrBase及RoceRemoteMemMgr/UbRemoteMemMgr两个具体类,本端接口(RegisterMemory/UnregisterMemory/MemoryExport/GetAllMemHandles)纯转发进程级 mgr,远端接口(MemoryImport/MemoryUnimport)由实例自管,按{endpointDesc, pid}键管理远端缓冲并支持幂等导入与引用计数递减。 - 远端内存职责从进程级 mgr 剥离:
roce_reged_mem_mgr.cc/h与ub_reged_mem_mgr.cc/h删除MemoryImport、MemoryUnimport、GetParamsFromMemDesc实现及remoteRdmaRmaBufferMgrs_/remoteUbRmaBufferMgrs_成员,reged_mem_mgr.h中这两个接口改为带默认"不支持"实现(返回HCCL_E_INTERNAL)的非纯虚函数。 - 内存描述符布局新增 pid 字段:
RoceRegedMemMgr::GetMemDesc与UbRegedMemMgr::GetMemDesc在 DTO 序列化 +EndpointDesc之后追加 u64getpid(),旧格式(不带 pid)的 desc 在解析时直接报错,强制两端同版本。 - 各 Endpoint 接入实例级 wrapper:
cpu_roce_endpoint.cc、cpu_urma_endpoint.cc、uboe_endpoint.cc、urma_endpoint.cc改为先取进程级 mgr 再std::make_shared<RoceRemoteMemMgr>/<UbRemoteMemMgr>(procMgr, ctxHandle_),ub_rtp_endpoint.cc由实例自建UbRegedMemMgr后同样包 wrapper;对应头文件中regedMemMgr_类型统一改为std::shared_ptr<RegedMemMgr>。 - 补充/调整单元测试: 新增
ut_endpoint_remote_mem_mgr.cc覆盖空指针校验、旧格式 desc 报错、同键幂等导入引用叠加、不同 pid 独立管理、末次 unimport 擦除 owner、本端接口纯转发等场景;ut_roce_mem_test.cc删除随旧实现移除的GetParamsFromMemDesc用例,ut_hcomm_mem_test.cc、ut_cpu_urma_endpoint.cc相应更新注释与 mock 描述。


代码审查
已完成对全部 20 个变更文件的逐一审查。以下为结论。
审查结论
发现 4 项问题(1 项 P0、1 项 P2、2 项 P3):
- P0(高置信 0.85):
src/base_comm/resources/endpoints/cpu_roce_endpoint.cc:72将std::make_shared<RoceRemoteMemMgr>赋给成员regedMemMgr_,但同 PR 未修改cpu_roce_endpoint.h(不在变更清单内),其成员声明仍为std::shared_ptr<RoceRegedMemMgr>;RoceRemoteMemMgr与RoceRegedMemMgr无继承关系,shared_ptr 无法转换,属直接编译失败。其余四个 endpoint 头文件均已同步改为shared_ptr<RegedMemMgr>,唯独 RoCE 头被遗漏。 - P2(置信 0.55):
endpoint_remote_mem_mgr.h新解析器只校验 descLen 下限,旧版本无 pid 的 desc(DTO 长度 ≥8 时)可绕过检查被静默错位解析(pid/desc/DTO 偏移全错),混合版本滚动升级时导致导入记账错误、注销 E_NOT_FOUND 泄漏或 Deserialize 异常穿出 C-API。 - P3(置信 0.70):
GetParamsFromMemDesc中resize(TRANSPORT_EMD_ESC_SIZE)后立即被assign覆盖,无用预分配(可选优化)。 - P3(置信 0.40):
RemoteMemOwnerKey::operator==对 EndpointDesc 整结构体(含 padding)memcmp,与仓库内既有"字段级 hash/compare 规避 padding 误判"的做法相悖,padding 不稳定时同一远端内存可能被识别为不同 owner。
逐文件核对:
cpu_roce_endpoint.cc— 发现 P0(见上)cpu_urma_endpoint.cc/cpu_urma_endpoint.h— 无问题(AttachCache/Init 与头文件类型一致,ctxHandle_ 先于 wrapper 构造赋值)ub_rtp_endpoint.cc/ub_rtp_endpoint.h— 无问题(两次 EXCEPTION_CATCH 覆盖两个分配步骤,失败均回滚 ReleaseEndpointCtx)uboe_endpoint.cc/uboe_endpoint.h— 无问题urma_endpoint.cc/urma_endpoint.h— 无问题endpoint_remote_mem_mgr.h(新增)— 发现 P2 + 2 项 P3(见上)reged_mem_mgr.h— 无问题(MemoryImport/Unimport 改为带默认报错实现的虚函数,Hccs/AicpuTs/UbMem 等派生类仍自行覆盖,无行为回归)roce_reged_mem_mgr.cc/roce_reged_mem_mgr.h— 无问题(pid 追加有 memcpy_s 校验;远端逻辑已正确迁移至 wrapper)ub_reged_mem_mgr.cc/ub_reged_mem_mgr.h— 无问题test/ut/framework/next/CMakeLists.txt— 无问题(新增 UT 源文件路径与文件存在性一致)ut_hcomm_mem_test.cc— 无问题(仅注释修改)ut_endpoint_remote_mem_mgr.cc(新增)— 无确认问题(用例覆盖幂等导入/分 pid 管理/最后引用注销等关键路径;测试以 nullptr rdmaHandle 构造 RemoteRdmaRmaBuffer 的可行性依赖其构造函数实现,未能静态确认,但生产路径同构)ut_roce_mem_test.cc— 无问题(删除的用例与被移除的 GetParamsFromMemDesc API 配套)ut_cpu_urma_endpoint.cc— 无问题(mock 派生自 UbRegedMemMgr,可赋给基类指针成员)
总体风险判断: 本次改动(远端内存导入/注销从进程级 mgr 下移到 Endpoint 实例级 wrapper)设计方向清晰,本端接口转发与实例级 refcount 语义自洽,测试覆盖了核心路径。但存在一个必须修复的 P0 编译问题(cpu_roce_endpoint.h 类型未同步),以及一个影响混合版本部署的 desc 格式兼容性缺口(P2),建议修复后再合入。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 1 |
| 🟡 建议 | 0 |
⛔ 需要修改


Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
For more, you also can visit HICANN.
PR Approval Progress
✅ Congratulations! All modules have met the lgtm and approve requirements.
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| docs | ✅ 颜业峰, 严正行 (2/2) | ✅ 颜业峰 (1/1) |
| src/base_comm | ✅ 孙哲芃, 颜业峰, 严正行 (3/2) | ✅ 孙哲芃, 颜业峰 (2/1) |
| src/base_comm/resources/endpoints/endpoint.h | ✅ 严正行, 颜业峰 (2/2) | ✅ 颜业峰 (1/1) |
| src/base_comm/resources/reged_mems/reged_mem_mgr.h | ✅ 颜业峰, 严正行 (2/2) | ✅ 颜业峰 (1/1) |
| test | ✅ 颜业峰, 严正行, 孙哲芃 (3/2) | ✅ 孙哲芃, 颜业峰 (2/1) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
littlemons, thanks for your pull request. All authors of the commits have signed the CLA. 👍


/lgtm


描述
改动原因:多个 endpointHandle/endpoint 实例若持有相同的 endpointDesc,对相同远端内存执行 HcommMemImport 时会误判为重复导入而报
HCCL_E_INTERNAL(原 E_AGAIN),且进程级共享 mgr 的引用计数跨实例串账,存在 ref 泄漏。改动方法:将内存管理的"本端"与"远端"两条线拆开,各自回到正确的归属层:
RegedMemMgr拆为LocalRegedMemMgr(注册/注销/导出/枚举)、RemoteRegedMemMgr(导入/关闭)两个独立接口。hccs/aicpu_ts/NIC 插件等本远端操作天然耦合的形态只继承LocalRegedMemMgr(消除多继承的菱形风险),其远端接口经RemoteRegedMemMgrForwarder(RemoteRegedMemMgr派生的纯转发视图)包装后由GetRemoteRegMemMgr()对外暴露,转发到同一 mgr 对象的同一实现,行为与拆分前一致。EndpointRemoteRegedMemMgr(RemoteRegedMemMgr的唯一实现,RoCE/Ub 两族差异通过 MemDescParser/RemoteBufferCreator 注入适配),远端导入的引用计数收缩到 Endpoint 实例内;相同 endpointDesc 的不同实例互不干扰,重复导入在本实例内幂等成功(ref+1),不再报错。进程级 mgr(RoceRegedMemMgr/UbRegedMemMgr/UbMemRegedMemMgr)瘦身为只管本端内存。Endpoint::GetRegedMemMgr()拆为GetLocalRegMemMgr()(纯虚)+GetRemoteRegMemMgr()(默认 nullptr,不支持远端导入的 endpoint 无需 override),C API 适配层按操作类型分发到对应 mgr。reged_mem_mgr.h中的BuildMemDesc/ParseMemDesc一对函数,同文件成对维护,RoCE/Ub 的导出与导入路径统一复用;解析侧保留长度校验、DTO 回读校验(拦截旧格式错位)与异常兜底。本变更为内部实现重构 + 行为修复,对外 C API 签名无变化,
include/头文件无变更,不涉及 API 兼容性问题。变更类型
请选择本次引入的变更类型:
关联的Issue
NA
测试
已完成的测试用例和场景:
ut_endpoint_remote_mem_mgr.cc,覆盖实例级远端内存管理核心场景:GetLocalMemMgr(),mock 按 Local/Remote 接口分别打桩,C API 转发路径用例全部适配。bash build.sh -u(编译并运行 UT)。补充的UT用例:
test/ut/framework/next/comms/endpoints/reged_mems/ut_endpoint_remote_reged_mem_mgr.cc(新增 10 个用例)文档更新
合入检查