最近某开发嵌入式平台的客户到我们的协议测试Open Lab分析底层PCIe的问题。问题症状看起来很简单,开发板上DSP主芯片的RC(Root Complex)端通过PCIe链路直连M.2 NVMe SSD,读操作没有任何问题,但是写操作会失败。前后折腾了6个多月,最后找到我们实验室通过SerialTek公司的Kodiak系列PCIe协议分析仪通过协议抓包的方式快速解决了问题。
下面是分析的大致步骤和过程。
1.我们先抓取一个read操作,读取一个扇区512字节。
从上图,我们看到,蓝色底色部分是NVMe SSD controller去主内存里面拿这个read command,成功完成。紧接着,SSD controller从NAND拿到数据后将这些数据通过4个128byte的memory write写到主内存。
2.我们再来抓取一个write操作,写一个扇区512字节。执行命令后,发现写失败。
从上图可以看出,SSD controller在时间戳16.353.876.194.000这一行取到write command后,在蓝色底色这一行报错,Unsupported Request。这一行是SSD controller发送Memory Read命令到内存读取512byte的数据,但是被RC端拒绝了。
在问题未仔细分析之前,我们开始觉得这是否可能和SSD的sector扇区的block size有关,因为一般都是512byte,也有1K, 2K, 4K block size的。所以,我们就用ChatGPT先问了一下业内是否有支持256byte sector大小的NVMe SSD。参看下图。
结果找到全球只有Micron 一个M.2 SSD支持。
结果发现ChatGPT弄了一个大乌龙,整个Micron产品单页中确实出现好多256,但是要么是256GB,AES Key Size 256 Bits,SHA 256,甚至256 sector或者256 words。所以,看来使用ChatGPT来给出建议还不是很靠谱啊。
我们再次仔细来分析该错误,同时比对为什么read command可以成功,但是write command却失败了。直观的对比发现可能和Max Read Request Size 有关。我们查找RC的手册,发现它的规格Spec里面明确写明RC接受的远端device的Max Read Request Size为256byte,但是我们抓包发现SSD的PCIe memory read request size是512 byte,这个应该就是RC回复SSD的Unsupported Request的直接原因。
为了验证这个想法,我们在RC端在初始化的时加入一行代码设置device端的Max Read Request Size为001 (该字段为3bit, 二进制001表示256byte)。然后重新开机运行写操作,这次写2048个字节,结果成功了。2048个字节分解成8次memory read,每次256字节,参见下图。
至此,问题得到有效解决。当然,平时有的时候也会发现你请求512byte,结果发送4次128 byte的情况,就像我们上面的read command一样,解释如下。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !