已关闭
[Bug-Report|缺陷反馈]: Translate() 访问 kernelMap_ 时使用的锁与 Register/UnRegister 不一致 #285
MBpanzz创建于 6月24日关闭于 7月8日
Leewis
7月8日 评论:
7月8日 评论:
您好,相关问题已合入,当前issue将闭环,后续有相关问题欢迎提交issue交流讨论。
https://gitcode.com/cann/hcomm/pull/3119


您好,相关问题已合入,当前issue将闭环,后续有相关问题欢迎提交issue交流讨论。
https://gitcode.com/cann/hcomm/pull/3119


Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.
Describe the current behavior / 问题描述 (Mandatory / 必填)
CcuKernelMgr::Translate()在遍历kernelMap_时持有translateMutex_,而Register()和UnRegister()写kernelMap_时持有的是另一把锁kernelMapMutex_。由于两段逻辑使用不同的锁来保护同一份共享数据
kernelMap_,当同一设备上多个线程分别执行Register()/UnRegister()和Translate()时,kernelMap_可能被一边写入(插入/删除节点)一边读取(find遍历),在unordered_map的并发读/写上存在未定义行为的风险。在单线程串行调用场景下(先完成所有 Register,再统一调用 Translate)不存在此问题;但在同一设备的多个线程分别操作不同
CcuInsHandle时可能触发。相关的代码路径:
Translate(读 kernelMap_,持 translateMutex_):
// ccu_kernel_mgr.cc:503-521 CcuResult CcuKernelMgr::Translate(const std::vector<CcuKernelHandle> &kernelHandles) { std::unique_lock<std::mutex> lock(translateMutex_); // 锁 A ← 与 Register/UnRegister 不同 std::vector<CcuKernel *> kernels{}; for (const auto kernelHandle : kernelHandles) { const auto &iter = kernelMap_.find(kernelHandle); // ← 读 kernelMap_ if (iter == kernelMap_.end()) { return CcuResult::CCU_E_NOT_FOUND; } kernels.push_back(iter->second.get()); } // 后续翻译操作耗时较长 CCU_CHK_RET(TransRepResToPhyRes(kernels, devLogicId_)); CCU_CHK_RET(TransRepSequenceToMicrocode(kernels, isFuncBlock)); ... }Register(写 kernelMap_,持 kernelMapMutex_):
// ccu_kernel_mgr.cc:106+133 std::unique_lock<std::mutex> lock(kernelMapMutex_); // 锁 B ... kernelMap_[kernelId_] = std::move(currKernel_);UnRegister(删 kernelMap_,持 kernelMapMutex_):
// ccu_kernel_mgr.cc:550+561 std::unique_lock<std::mutex> lock(kernelMapMutex_); // 锁 B ... kernelMap_.erase(kernelHandle);Environment / 环境信息 (Mandatory / 必填)
该问题与特定运行环境无关
Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)
该问题出现的可能性较小,但在以下场景中可能有风险:
CcuInsHandle,一个线程调用HcommCcuKernelRegister(持kernelMapMutex_写),另一个线程调用HcommCcuKernelRegisterEnd(持translateMutex_读)CcuKernelMgr是 per-device 单例,两个线程不同的锁不能互斥,导致对kernelMap_的读写并发Describe the expected behavior / 预期结果 (Mandatory / 必填)
kernelMap_的所有访问路径应使用同一把锁保护Related log / screenshot / 日志 / 截图 (Mandatory / 必填)
无
Special notes for this issue/备注 (Optional / 选填)
该问题可能不存在实际危害