前情提要:Thinkbook 14p 锐龙版睡眠唤醒后死机-论坛-深度科技 (deepin.org)
先说结论:
- 在Linux环境下,联芸主控如MAP1202、MAP1002(光威Basic 1T固态、海康威视C2000eco等一些新的国产固态上)可能在部分机型上的ID汇报存在问题。
- 现有Linux内核NVMe代码会使用多种不同方法侦测NVMe设备的eui64值。方法返回值不一致时,会被认为是NSID发生改变,会下线固态硬盘。
和Linux内核NVMe官方模块维护组进行的交流,内容比较多,邮件有多封:[PATCH] fix: nvme_update_ns_info method should be called even if nvme_ms_ids_equal return false (infradead.org)
个人解决思路
注意:这个问题我爬了下linux内核的commit,应该影响所有5.x内核。4.x没看代码。
虽然解决思路写的不多,但是这个问题定位了很久,验证猜想给硬盘增加了上百次异常断电计数😭 (主要是为了验证,特地买了个新的SSD,结果买到的新SSD还是联芸主控的,于是有了对这个问题的深究)…但是话不多说,既然windows没有问题,那么开源的好处就来了,直接排查内核源代码。
源自休眠后唤醒时的dmesg:
第一行是我自己加的内核调试代码,这里可以发现在休眠唤醒后,硬盘的NVMe eui值出现了变更,紧接着出现了错误"nvme nvme0: identifiers changed for nsid 1"。直接定位到源代码。
这里发现当ns_ids不同的时候,最后会跳过nvme_update_ns_info方法,导致nvme信息丢失,直接掉盘。解决方案也很简单,如图,删去3987行的goto语句即可。经过了多天的测试,硬盘内核稳定运行,打比赛高负载运行没有出过问题。
提出的解决方案(在检验NVMe namespace不一致时依然尝试更新NVMe设备的info)。传送门:[PATCH] fix: nvme_update_ns_info method should be called even if nvme_ms_ids_equal return false (infradead.org)
这个问题如果大家在更新linux 5.15.24+后,如果还是睡眠存在问题,可以往我这个方面考虑一下,可能是掉盘的问题。这里官方Christoph Hellwig给出了针对MAP1202主控睡眠问题的git patch:[PATCH] fix: nvme_update_ns_info method should be called even if nvme_ms_ids_equal return false (infradead.org)。如果是其他主控的话,如果遇到这个问题,开源尝试我上面那个解决方案,算是一劳永逸的方法。就是要自己编译下内核,大家有需要的话我有空可以用Deepin的内核config编译一下。
这个patch应该能作为bugfix快速并入linux mainline,目前官方也查到了这个问题,这样推进这个问题的解决。不过最根本的还是要主控方查清原因。
另外,在研究的过程中,完成了开启Thinkbook 14p的S3睡眠+解决ACPI SB/LID0 ERROR的问题,同机型的可以参考一下:
Thinkbook 14p Gen2 ACH Ubuntu/Linux睡眠后掉硬盘「已解决」_ThinkBook-联想社区 (lenovo.com.cn)
内核修改commit传送门: fix: nvme_update_ns_info method should be called even if nvme_ms_ids_… · Kingtous/linux@2bef387 (github.com)