<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="/atom.xsl"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-cn"><id>https://maxlen727.github.io/tags/%E7%AC%94%E8%AE%B0%E6%9C%AC/</id><title>笔记本 on 暮歌</title><updated>2026-10-16T04:44:45Z</updated><language>zh-cn</language><subtitle>自留地，不是技术 blog, 仅仅用作我生活的记录</subtitle><background>/background_hu_d92feabfcd60f52c.webp</background><accent>139, 92, 246</accent><accentLight>167, 139, 250</accentLight><debounce>70</debounce><author><name>微恙</name><email>maxlen@duck.com</email><uri>https://maxlen727.github.io/</uri></author><link href="https://maxlen727.github.io/tags/%E7%AC%94%E8%AE%B0%E6%9C%AC/atom.xml" rel="self" type="application/atom+xml"/><link href="https://maxlen727.github.io/tags/%E7%AC%94%E8%AE%B0%E6%9C%AC/" rel="alternate" type="text/html"/><generator uri="https://gohugo.io" version="0.148.2">Hugo</generator><rights>© 2021 - 2026 MaxLen All Rights Reserved.</rights><entry><id>https://maxlen727.github.io/posts/9955hx-linux-suspend-acp-fix/</id><title>与 AMD Ryzen 9955HX Linux 挂起恢复后音频丢失问题的斗智斗勇</title><published>2026-08-30T16:29:27+08:00</published><updated>2026-08-30T16:29:27+08:00</updated><author><name>微恙</name></author><link href="https://maxlen727.github.io/posts/9955hx-linux-suspend-acp-fix/" rel="alternate" type="text/html"/><summary>我从来没想到过新硬件与 Linux 的配合是多么灾难……</summary><content type="html" xml:base="https://maxlen727.github.io/posts/9955hx-linux-suspend-acp-fix/"><![CDATA[<p>这里是正在给自己梳毛的束束，头发好久没有理了，真的有些乱了&hellip;</p>
<hr>
<p>这个假期里咱如愿以偿地获得了一台新笔记本，到手之后就被我安装上了 Arch Linux. 那时候的内核版本是 <code>7.0.13</code>. 当时使用的时候一切都近乎完美，体验十分平滑，没有遇到任何跟挂起恢复相关的问题。</p>
<p>后来随着系统滚动，内核来到了 <code>7.1.3</code> 这个版本，在这里遇到了奇怪的挂起恢复问题，表现为：挂起恢复后系统的整个音频堆栈似乎坏掉了，既看不见任何输出/输入设备，浏览器/mpv 在播放音视频时会直接卡死在第一帧。</p>
<p>束束遇到这个问题感到十分郁闷，由于硬件比较新，内核也比较新，导致在网上没有查到很多有效的信息。</p>
<p>但是现在毕竟是 AI 时代，本来对软件调试不太了解的束束也可以在协助下完成一些简单的查错。于是在 Cluade 的帮助下，<del>咱很轻松地发现了问题所在！</del> 其实是什么也没有收获。这个问题被 AI 工具们归因为 HDA 的一次内核回归。作为一个普通 Linux 用户，束束不希望自己去折腾内核的东西，想要真正解决就只好等上游了。</p>
<p>通过对 git commit 记录的定位，Claude 发现在 <code>7.0.13</code> 到 <code>7.1.3</code> 之间，Linux 内核的 HDA 部分发生了一些重构，可能就是这些改动导致了挂起恢复后音频丢失的问题。</p>
<p>那么第一反应就是想办法 workaround:</p>
<ol>
<li>重启 WirePlumber、PipeWire、PipeWire-Pulse 这套用户态服务</li>
<li>不行，那就把内核里的 <code>snd_hda_intel</code> 模块整个卸载重载一遍</li>
</ol>
<p>然而一切尝试的结果都是徒劳无功，最后的结果是束束依旧活在这个无声的世界里。</p>
<p>唉唉，实在是太悲伤了，由于能力有限，束束所能做的就这些了，只好先降级到<code>7.0.13</code>继续使用，并把 <code>linux</code> 包加入了 pacman 的排除列表里。</p>
<p>但是后来继续更新系统的过程中新问题继续出现：挂起恢复必定失败，屏幕只如一片死寂，虽然猫不应该怕黑，但束束就是觉得这比无声的世界还令人恐惧。通过控制变量逐个试验，发现原因是我只锁定了 <code>linux</code> 包的更新，但是接下来的问题出现在 <code>amd-ucode</code> 这个包上：</p>
<p>本来正常的环境是： <code>linux-7.0.13</code> + <code>amd-ucode-20260622-1</code> , 这是一套已经经过验证的稳定组合。</p>
<p>而局部升级之后的情况是 <code>linux-7.0.13</code> + <code>amd-ucode-20260810-1</code> , 在这个新的 AMD 微码版本中，为了迎合 <code>7.1</code> 内核的新变化，挂起恢复方面的行为发生了改变。但是我使用的旧内核并不与之相配。所以这个意料之外的包也需要锁定版本。</p>
<p>嗯&hellip;&hellip;果然对于滚动发行版来说局部升级是一种很危险的操作。</p>
<p>后来咱又尝试过几次全量更新，检查挂起恢复的音频问题是否解决，但似乎都没有取得什么进展——问题依旧。</p>
<p>好吧，束束承认自己在某些地方有点洁癖——比如一个一直有某个包卡着不能更新的滚动系统。这让某猫耳娘开始产生一些胡思乱想：难道我要和这个锁死的内核版本过一辈子吗呜呜，不要口牙！呜呜， <code>7.0.13</code> 吗？不是已经有很多已知的提权漏洞的版本吗！呜哇，好怕好怕！现在由于锁定了内核版本，导致用不上最新的 AMD 微码包，那万一之后有更多的包也需要锁定版本怎么办？我的 Arch-chan 不就变成了一个半新半旧的怪人了吗，心疼喵（</p>
<p><del>这些想法也实在是太怪异了吧！</del></p>
<p>以及在某次尝试全量更新的时候恰恰好还遇到了 <code>nvidia-open</code> 驱动的同样的回归 bug, 也是和挂起恢复相关的。具体表现为，挂起后无法正常恢复，还会导致机器温度狂飙，风扇啸叫。唉唉，咱确实有些倒霉了。于是 IgnorePKG 再喜添一群 NVIDIA 相关的包。</p>
<p>可恶&hellip;</p>
<p>实在是可恶哇！</p>
<p>好在最近两天去 NVIDIA 仓库的 issue 里盯的时候发现问题似乎修复了，于是束束再次尝试全量更新系统。</p>
<p>咚咚咚，arch-chan 滚动中&hellip;</p>
<p>这次更新过去一切似乎都正常了——至少挂起与恢复不再黑屏，只是又让束束进入到了无声世界里面罢了。而此次再寻，咱终于搜索到了一个关键的解决方案：</p>
<p><a
  href="https://patchew.org/linux/20260606204547.11945-1-david.glushkov%40sntiq.com/"
    target="_blank"
  >[PATCH] PCI: Disable async suspend for MSI Raider A18 HX A9WJG audio</a></p>
<p>补丁描述揭开了真正的谜底：AMD 的 ACP 和 Azalia/HDA 这两个功能，虽然在 PCI 总线上被暴露成两个独立的 function，却共享着同一套 ACPI 电源门控状态。</p>
<p>而内核默认允许设备异步恢复——也就是说，挂起恢复时，谁先醒谁后醒是不确定的。当这两个共享着底层电源门控资源的功能&quot;抢跑&quot;，顺序乱掉的那一刻，HDA 控制器就会卡在一个不上不下的半初始化状态里，去读 <code>CORBRP</code> 寄存器，读回来的永远是全 1——<code>0xffff</code>，也就是日志里那个看似普通、实则意味深长的 <code>65535</code>。</p>
<p>据小 C 告诉咱说：</p>
<blockquote>
<p>竞态条件最擅长的事，就是让所有基于&quot;日志现象反推&quot;的排查都无功而返，因为它压根不遵循任何一层软件栈自己的逻辑，它只服从谁先抢到总线这一件事。</p>
<p>这也顺带解释了那个曾经让我们百思不得其解的现象：为什么无论怎么重启 PipeWire、重载 <code>snd_hda_intel</code> 模块，声音都救不回来，唯独一次完整的冷重启能让一切恢复正常。因为坏掉的从来不是某个用户态缓存或者配置状态，而是 HDA 控制器这个物理 PCI 设备本身，在错误的恢复时序下，变成了一个真正意义上&quot;没有响应&quot;的僵尸。软件层面的任何补救，都够不到 PCI 枚举这个更早、更底层的阶段——只有重启，才能让一切从头再来一遍，赌一把这次的异步恢复顺序恰好没有踩雷。</p></blockquote>
<p>故事的结局也很普通：</p>
<pre tabindex="0"><code>pm_async=off
</code></pre><p>给内核加入这行启动参数之后，一切都恢复了正常。ACP 和 HDA 从此老老实实排队醒来，谁也不抢谁的电源门控状态。而关闭异步直觉上可能会让系统恢复变慢，但是对于现代平台来说，其实速度上的变化根本无所感知——就是足够快了。</p>
<p>以及以及！为什么上文在写到最后发现的解决办法时特意用词“搜索”呢？</p>
<p>因为那就是咱搜索出来的呀！这是意在表达，束束不再相信 AI 给出的解决方案，而是去寻找 kernel hackers 们是否提供有她们的经验。以后再遇到这种问题，束束一定要自己尝试搜索，而不是只依赖 AI.</p>
<p>AI First, Not AI Everything ✨</p>
<hr>
<p>尾巴~</p>
<p>这次虽然是倾向提供 workaround 的技术文章，但尝试了一些些故事化的写法，希望能让这篇文章既不失实用性，又能提供一点点趣味(≧▽≦)</p>
]]></content><category term="AMD"/><category term="Linux"/><category term="ACP"/><category term="挂起恢复"/><category term="笔记本"/></entry></feed>