已合并
[fix]multi_stream_lazy_reclaim coredump error #42424
xuyun15创建于 7月22日
[fix]multi_stream_lazy_reclaim coredump error #42424
已合并
Pull Request已成功合入, 合并人@ascend-robot
(感谢 xuyun15 的贡献)ascend-robot
7月22日 评论:
7月22日 评论:
atomgit-bot
7月22日 评论:
7月22日 评论:
变更摘要
此 PR 修复了 multi_stream_lazy_reclaim 特性在大量事件积压(sum > kLazyQuerySize)时触发 coredump 的问题。根因在于原代码在 get_free_block() 之后才调用 process_events():此时已选中的 block 被移出池但尚未标记为已分配(仍显示为 free 状态),若 process_events() 释放相邻 block 后触发 try_merge_blocks() 合并,会将待分配 block 错误删除,导致分配器损坏。修复方案是将 sum > kLazyQuerySize 触发的 process_events() 移到 get_free_block() 之前,同时引入 reaped 变量避免同一轮 malloc() 中重复调用 process_events()。
主要改动
NPUCachingAllocator.cpp:将惰性回收的process_events()移至 block 选择之前:在get_free_block()调用前新增一段逻辑,当lazy_reclaim启用且事件队列大小超过kLazyQuerySize时先执行process_events()并设置reaped = true,消除"未最终分配的 block 被合并删除"的竞态条件NPUCachingAllocator.cpp:引入reaped变量防止重复调用process_events():在 block 未找到的分支中增加!reaped条件判断,确保process_events()在同一轮malloc()中最多执行一次,与原有调用次数保持一致test_allocator_envs.py:新增回归测试用例test_multi_stream_lazy_reclaim_trigger_event:通过子进程创建超过kLazyQuerySize阈值(512)的带record_stream的 tensor,随后释放并分配新 tensor 以触发事件回收路径,验证子进程正常退出无崩溃


atomgit-bot
7月22日 评论:
7月22日 评论:
代码审查
审查总结
本次审查覆盖了全部 2 个变更文件:
| 文件 | 审查结论 |
|---|---|
torch_npu/csrc/core/npu/NPUCachingAllocator.cpp |
无问题 — 将 process_events() 移到 get_free_block() 之前的修复逻辑正确,reaped 守卫变量设计合理,所有场景下的行为与原代码一致且避免了 use-after-free。 |
test/npu/test_allocator_envs.py |
2 个问题 — 见下方 |
问题按优先级统计:
- P2:1 个(
subprocess.run缺少timeout参数) - P3:1 个(断言错误消息中
\\n应为\n)
整体风险评估:低风险。 C++ 核心修复逻辑正确,从根本上解决了 block_found=true 时 process_events() 可能合并删除已取出 Block 的 use-after-free 问题。测试文件存在两个小瑕疵,但不影响代码正确性。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 0 |
| 🟡 建议 | 1 |
💬 仅评论


此处折叠了42条消息 查看更多
7月23日 添加了label:lgtm
7月23日 合入了pull request
ascend-robot
7月23日 评论:
7月23日 评论:
Pull Request 已合并或已关闭。
If you want to solve this problem, you can click here to do it in the FAQs.


ascend-robot
7月23日 评论:
7月23日 评论:
流水线 pytorch_gitcode_PR_multiVersion#12968 [ commitID:72621fcd ] 已完成


【合入来源】
【修改方案】
选取issue中方案2作为解决方案
方案2:将 sum > kLazyQuerySize 的 process_events 移到 get_free_block 之前(推荐)
将
sum > kLazyQuerySize触发的process_events()移到get_free_block之前,保持与原生 PyTorch 相同的安全时序。同时引入reaped变量避免process_events()的冗余二次调用。2.1 process_events() 二次调用问题分析
方案2将
process_events()的调用拆分为两段:sum > kLazyQuerySize时在get_free_block之前调用!block_found时在get_free_block之后调用当
sum > kLazyQuerySize且get_free_block()仍然失败时,两段都会触发process_events(),导致同一轮malloc()中process_events()被调用两次。【资料变更】
不涉及:当前pr不涉及,但是后续会持续跟踪搜集用户诉求,逐步补齐对应的资料和用例
【接口变更】
不涉及
【功能验证】
修复前:


修复后:
【CheckList】