问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

浅析MPS对PCIe系统稳定性的影响

创作时间:
作者:
@小白创作中心

浅析MPS对PCIe系统稳定性的影响

引用
CSDN
1.
https://blog.csdn.net/zhuzongpeng/article/details/140535148

在PCIe系统中,MPS(最大有效负载大小)是一个关键参数,它不仅影响系统性能,还对稳定性有着决定性作用。本文将深入探讨MPS的原理、影响以及如何通过调整MPS和MRRS(最大读请求大小)来优化系统性能和解决稳定性问题。

MPS和MRRS基础概念

在PCIe协议中,有两个重要的参数:

  • MPS(Max Payload Size):这参数决定了TLP(事务层包)传输过程中的大小。接收端需要使用同样的MPS大小,发送端不能超过MPS的设置。协议中可以设定128B-4KB,其中默认是128B。在Device Capabilities寄存器中可以查询MPS的大小。

  • MRRS(Max Read Request Size):MRRS代表最大读数据请求大小,有6种选择:128B,256B,512B,1024B,2048B,4096B。这个参数在Configuration阶段写入设备的control寄存器。MRRS可以比MPS大,通常MRRS大于等于MPS。

MPS对系统性能的影响

随着MPS大小的增加,PCIe传输效率也在不断提升。不过,在x86的机器中,RC端的MPS通常是128B/256B。在ARM CPU中,为了追求高效性能,部分场景也会设置为512B。

在整个PCIe系统中,MPS的大小与RC、PCIe Switch、Endpoint都有相互的影响,最终TLP传输的数据大小取决于MPS最小的一个设备。比如下图示例,RC MPS=256B,PCIe Switch MPS=512B,但是EP3 MPS=128B。所以最终数据传输的大小采用的是MPS=128B。

MPS对系统稳定性的影响

除了影响系统性能,MPS对PCIe系统稳定性也起着决定性的作用。最常见的是,在系统中我们会看到pcie设备出现识别异常的情况,多数情况会看到一个“ Malformed TLP”,比如linux系统中的报错信息:

[ +0.002792] pcieport 0000:00:01.0: AER: Uncorrected (Fatal) error received: id=0020
[ +0.007830] pcieport 0000:00:01.0: PCIe Bus Error: severity=Uncorrected (Fatal), type=Transaction Layer, id=0008(Receiver ID)
[ +0.011387] pcieport 0000:00:01.0: device [10de:10e5] error status/mask=00040000/00000000
[ +0.008415] pcieport 0000:00:01.0: [18] Malformed TLP (First)
[ +0.006851] pcieport 0000:00:01.0: TLP Header: 20000080 010001ff 00000000 80004430

在PCIe spec中的Error Status Register的定义如下图:

上面linux报错信息中的error status=0x00040000,也即对应Error Status Register中的bit18被置位。

如何查询和修改MPS/MRRS参数

Linux系统中通过lspci和setpci可以查询和修改MPS/MRRS参数。比如:lspci查看设备DevCap寄存器中MPS=512B,最终传输用的MPS=256B,MRRS=4KB。

lspci -s 04:00.0 -vvv | grep DevCtl: -C 2
DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset+
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported-
RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+ FLReset-
MaxPayload 256 bytes, MaxReadReq 4096 bytes

如果需要修改MPS或者MRRS,需要先找到Device Control Register中MPS和MRRS的位置,如PCIe Spec定义,MPS在bit5-7,MRRS在bit12-14. 同时Device Control Register的offset是0x8h。

比如环境中,PCIe Capacity的位置在0x70. 结合Device Control Register的offset是0x8h,我们就可以整体看到MPS和MRRS修改的PCIe配置空间的位置是在0x78h。注意,这个不同的机器和pcie设备中,PCIe Capacity的位置可能有所不同,有些在0x70,也有在0x60的,这个在修改参数的数据一定要关注下自己机器的位置。

用setpci修改MRRS:下面修改的命令,预期结果:把Device Control Register中的bit12-bit14从原始的101b修改成了010b,也就是把MRRS从4KB修改成了512B。

# setpci -s 04:00.0 78.w
5936
#setpci -s 04:00.0 78.w=2936

这个时候用lspci查看确认,发现MRRS已经修改成了512B。符合预期,说明修改MRRS修改成功了。MPS的修改方式也跟MRRS修改方式类似,这里就不赘述了。

# lspci -s 04:00.0 -vvv | grep MaxReadReq
MaxPayload 256 bytes, MaxReadReq 512 bytes

此外,在Windows如果需要修改pci配置空间信息,也可以安装windows版本的pci工具,使用方式类似,这里就不展开了。感兴趣的同学可以自行尝试哈!

Linux内核中的MPS/MRRS配置机制

在linux内核中,MPS/MRRS这两个参数,同样会受到内核pcie_bus_config_types的影响。以linux 5.19内核源码为例,pcie_bus_config_types定义有5种:

  • PCIE_BUS_TUNE_OFF:不对MPS做任何操作
  • PCIE_BUS_DEFAULT:保证pcie设备可以满足upstream的要求。
  • PCIE_BUS_SAFE:将MPS设置为设备最大支持的值,这里也要参考水桶原理,最终采用最小MPS的EP设置。
  • PCIE_BUS_PERFORMANCE:将EP pcie设备的MPS设置为RC允许的最大值,同时MRRS也设置为最大值。
  • PCIE_BUS_PEER2PEER:相对比较简单,就是一个标准,把所有的RC/Pcie switch/EP的MPS都设置为128B,不偏不倚。

在linux中通过pcie_bus_configure_settings执行配置。在性能调优过程中,一般会选择在linux启动命令行中添加命令行参数pci=PCIE_BUS_PERFORMANCE。如果没有配置的话,会选择默认设置PCIE_BUS_TUNE_OFF。

通过pcie_write_mps函数修改MPS参数大小,这个函数只有在PCIE_BUS_PERFORMANCE模式下才会修改,其他模式就会直接使用默认MPS设置。

通过pcie_write_mrrs函数修改MRRS参数大小,这个函数只有在PCIE_BUS_PERFORMANCE模式下才会生效,其他模式就会直接return返回。

此外,还可以在驱动里面单独通过pcie_set_readrq 函数调整MRRS参数,以达到提升性能的目的。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号