求助,7900xtx上 SDMA 读主机内存越界导致 HIP 进程崩溃
-
配置:7900 XTX(gfx1100,XNACK off)、Ubuntu 24.04、内核 7.0.0-42、ROCm 7.2、PyTorch 2.14.1+rocm7.2,amdgpu.mes=0(默认值,非 MES 路径)。
现象:长上下文推理和视频生成(ComfyUI,20GB DiT + 15GB 文本塔)偶发 hipErrorIllegalAddress,进程直接死。dmesg 同一签名:
代码块
amdgpu 0000:09:00.0: [gfxhub] page fault (src_id:0 ring:128 vmid:8 pasid:3)
amdgpu 0000:09:00.0: in page starting at address 0x00000000e35e0000 from client 10
amdgpu 0000:09:00.0: Faulty UTCL2 client ID: SDMA1 (0xe)
amdgpu 0000:09:00.0: MAPPING_ERROR: 0x1
偶发:同一工作流第一次成功、第二次崩,重试又成功。关掉会话缓存后 145 次请求 0 崩;缓存全开 + HSA_ENABLE_SDMA=0 压测 120 次 0 崩(冷 prefill 慢约 21%)。上游 drm/amd #5475 定位到 gfx1030 的 SDMA mid-command 偏移越界,但补丁只对 gfx10 生效;gfx11 默认走 MES,和我们这条非 MES 路径不一样。
想请教两个问题:
有人在 gfx1100 + mes=0(非 MES) 上见过同样的 SDMA page fault 吗?
除了关缓存和 HSA_ENABLE_SDMA=0,有没有参数或补丁层面的解法?
附件:完整 dmesg、崩溃调用栈、复现脚本。
sdma-pagefault-evidence.zip -
gfx1100 + mes=0 是非默认路径,ROCm 7.2 的 gfx11 默认走 MES;上游 drm/amd #5475 只修 gfx10,gfx11 的非 MES SDMA 路径没有对应补丁,所以别指望某个参数能根治。
从 dmesg 看是 SDMA1 在 UTCL2 上碰到未映射页(MAPPING_ERROR 0x1),典型是「拷贝过程中源/目标映射已被回收」。20GB DiT + 15GB 文本塔在 24G 卡上必然大量 evict/migrate,长上下文 KV 又在涨,ComfyUI 换模型时 free/mmap 与 SDMA 搬运竞争就会偶发。你关会话缓存不崩、HSA_ENABLE_SDMA=0 不崩,正好对应「少走 SDMA 的 host
VRAM 搬运」。另外 XNACK off 时 GPU 页错误不会重试,任何失效映射都直接 illegal address,这解释了同一工作流时好时坏。建议按这个顺序试:
- 先做对照:mes=1(默认)跑同一套 145 次压测。若稳定,问题基本锁定在非 MES 路径,生产别用 mes=0,把两组 dmesg 一起提给 ROCm/amd。
- 必须 mes=0 时,把「同时驻留」降下来:ComfyUI 用 --normalvram/--lowvram 分批换模型,文本塔跑完即卸,别让 DiT 和文本塔同时压满;长上下文任务别和视频生成并发。
- 保留 HSA_ENABLE_SDMA=0 作生产兜底(你已测 120 次 0 崩),冷 prefill +21% 比崩进程划算。
- 补一组内核对照:7.0.0-42 很新,ROCm 7.2 的 amdgpu 与内核版本错配也会出 UTCL2 错,换 ROCm 官方支持的内核(6.8/6.11 LTS)跑同样压测,能排除内核侧回归。
- 复现时开 AMD_LOG_LEVEL=3,把崩溃前的 HSA 调用尾部一起留档;有 debugfs 权限的话再抓 amdgpu_vm_info,定位是哪个 BO 没映射。
结论:mes=0 在 gfx11 上属未验证路径,先证明 mes=1 稳,再决定要不要为它继续投入。
-
谢谢,两组都做了,结论反过来了。
- mes=1(dmesg 确认 mes_v11_0_0 / sdma_hqd_mask 0xfc):同配置 26 条崩 2 次,报错和 mes=0 一字不差(conversation snapshot copy + SDMA1/MAPPING_ERROR 0x1)。不是非 MES 路径的问题。
- 6.8.0-147(mes=0、ROCm 7.2 不变):Strata 缓存全开 120/120、0 page fault(40.8 min,32K 10.5 s);ComfyUI 10 s 工作流 3/3,热跑 361.8 s(7.0 是 361.7 s)。
- 7.0.0-42 同配置约 30 次崩 4 次。
所以 7.0 这代内核是放大器(和 #5475 的 6.18+ 概率上涨对得上),已切 6.8 默认并重开缓存,HSA_ENABLE_SDMA=0 留兜底。6.8 不是根治,只是 120 次没触发。
补一句:这台 7.0 的 amdgpu 编译默认就是 mes=0,不是我们关的。
问一下:6.18+ 的 userptr 回归有 upstream 确认或测试内核吗?