✨前言:
PCIe总线的存储器写请求、存储器读完成等TLP中含有数据负载,即Data Payload。Data Payload的长度和MPS(Max Payload Size)、MRRS(Max Read Request Size)和RCB(Read Completion Boundary)相关。
✨一、RCB介绍
🌟1.1 什么是RCB?
RCB(Read Completion Boundary)是PCI Express(PCIe)总线中定义的一个参数,它指定了在完成PCIe内存读取请求时可以返回的数据包的最大对齐字节边界。RCB的值通常可配置为64字节或128字节。
这个参数的作用是确保读取响应(Completion)数据包中包含的数据不会跨过特定的对齐边界。简而言之,RCB定义了数据包中的数据应该如何在一个或多个连续的PCIe包中被分割传输,以便于数据的处理和高效率的内存访问。
RCB的设置在系统性能优化中很重要,因为它影响着数据在PCIe接口上传输的效率。合适的RCB设置可以帮助减少延迟和提升带宽的利用率,从而提高整个系统的性能
🌟1.2 RCB配置
在PCIe规范中,RCB主要有两个可选的大小:64字节和128字节。**RC 的 RCB 可以为 64B 或 128B,默认 64 B;EP、Bridge、Switch 等其他设备的 RCB 只能为 128 B。**这意味着当设备完成读请求时,返回的数据包大小不超过设置的RCB值。选择适合系统需求的RCB大小,可以在保证数据传输稳定性的同时,优化系统性能。
64字节RCB:较小的RCB设置会导致更频繁的数据包传输,这在某些情况下可能提高小数据块传输的效率。例如,对于一些需要低延迟的应用,较小的数据包可能意味着更快的响应时间。
128字节RCB:较大的RCB设置减少了数据包传输的频率,有利于大量数据的传输效率。在数据吞吐量要求较高的应用场合,较大的RCB可以减少系统的总体开销,提高数据传输速度。
🌟1.3 RCB的应用
当主机或设备在PCI Express (PCIe) 总线上发出一笔Memory Read请求(MRd)时,目标设备或内存控制器需要按照相应的规则进行处理,并生成一个或多个完整的响应(Completion,Cpl)。为了满足RCB(Read Completion Boundary)规则,返回的数据可能需要被拆分成多个CplD(Completion with Data)数据包。这里是一个简化的步骤说明,展示满足RCB规则的Completion响应策略:
步骤 1: 分析MRd请求 设备首先分析MRd请求,获取以下信息: 读取的起始地址(Address) 读取的数据长度(Length)
请求者的ID和Tag,以便之后能将完成数据与请求正确匹配 步骤 2: 检查RCB设置
确认当前系统设置的RCB值(通常是64或128字节),这将影响拆分策略。 步骤 3: 计算是否跨越RCB边界
检查请求读取是否会跨越RCB边界。例如,如果RCB是64字节,确保读取操作不会在一个64字节的对齐边界开始,并在另一个64字节的对齐边界结束,而是在RCB定义的同一个边界内完成。
步骤 4: 拆分完成数据
如果MRd请求的长度过长,使得数据不能在一个CplD中返回,或者读取操作跨越了RCB边界,那么目标设备需要将数据拆分成几个CplD数据包。每个数据包都需要:
遵守MPS(Max Payload Size)的限制 确保CplD中的数据不会跨越RCB边界 遵循系统内存及对齐规则 步骤 5:
构建CplD数据包 为每一段数据构建CplD数据包,包括必要的头部信息,如请求者ID、Tag、完成状态、Byte
Count等,并将实际数据附加到数据包中。 步骤 6: 发送CplD数据包
依次发送所有CplD数据包,包括可能因RCB而被拆分的多个数据段。 步骤 7: 等待所有CplD被确认
请求方接收到所有的CplD数据包,并确认数据是否完整和正确。
通过以上步骤,一个MRd请求得到满足RCB规则的Completion响应。这种拆分策略有助于维持PCIe系统的稳定性和数据完整性,同时也确保了数据在不同的设备间能够高效地传输。这个过程有时也可以由硬件逻辑自动完成,无需软件参与。
🌟1.4 举例说明:
假设RCB(Read Completion Boundary)设置为64字节(即RCB = 64B),并且Root Complex(RC)收到了一笔起始地址为0x0010h(即16字节偏移),长度为256字节(即64字节 x 4)的Memory Read请求(MRd)。为了满足RCB规则,RC在回复CplD(Completion with Data)时,需要确保每个CplD数据包中的数据不会跨越64字节的边界。
首先,考虑到RCB是64字节,我们可以把内存空间想象为由64字节大小的块组成。并且,由于MPS(Max Payload Size)或设备设置的其他限制,以及PCIe TLP的格式要求,一个CplD可能包含的数据量也是有上限的。
由于读取请求的起始地址是0x0010h,我们知道第一个数据包不能从0字节地址开始,它会从16字节地址开始并延伸到下一个64字节边界。此后,每个数据包都会尝试填充完整的64字节,直到所有的256字节都被读取。
以下是RC回复256字节MRd请求时,可能的CplD分包情况:
⭐️1.4.1 情况1:4个CplD,每个64字节
第一个CplD包含数据0x0010h到0x003Fh(64字节 - 16字节的偏移 = 48字节)
第二个CplD包含数据0x0040h到0x007Fh(64字节)
第三个CplD包含数据0x0080h到0x00BFh(64字节)
第四个CplD包含数据0x00C0h到0x00FFh(64字节)
⭐️1.4.2 情况2:如果MPS更小
如果设备有一个更小的MPS值的限制(例如128字节),那么CplD数据包将进一步分割,以不超过MPS的限制。例如,前两个CplD可能包含以下数据:
第一个CplD包含数据0x0010h到0x003Fh(如上)
第二个CplD包含数据0x0040h到0x006Fh(48字节,因为MPS限制)
剩下的数据需要在后续CplD中完成。
⭐️1.4.3 情况3:1个CplD,128字节 + 2个CplD,64字节
在某些情况下,可能会根据MRRS或其他系统限制合并响应,例如:
第一个CplD包含数据0x0010h到0x007Fh(48字节 + 64字节)
第二个CplD包含数据0x0080h到0x00BFh(如上)
第三个CplD包含数据0x00C0h到0x00FFh(如上)
这种合并必须在保证不会跨过64字节边界的前提下进行,并且每个CplD的大小依旧不能超过设定的MPS。
总的来说,在处理CplD时,会遵循几个基本的规则:
数据不跨越64字节的RCB边界。
数据负载在MPS的限制内。
尝试以最有效的方式(取决于MPS和MRRS)响应整个读请求。
✨二、MPS介绍
🌟2.1 什么是MPS?
MPS(Max Payload Size)表示TLP报文中数据负载的长度。PCIe总线规MPS的最大值为4KB,但PCIe设备并不一定都能够按照最大长度发送数据负载。因此实际使用的MPS由链路两端的设备Function协商决定。当发送的数据长度超过MPS时,这段数据会被分割成多个TLP报文发送,若接收的TLP报文数据负载超过MPS,则接收端会认为这是一个非法的TLP。对于存储器读完成TLP报文,数据负载的长度也不能超过MPS,如果超过MPS,则需要发送多个读完成报文,同时也要满足RCB的要求。
在PCIe配置空间中,有两个寄存器,Device Capabilities记录的是PCIe Function的MPS能力,Device Control寄存器可以配置MPS的大小
Max_Payload_Size Supported的值和MPS对应关下如下:
🌟2.2 不同的MPS的作用
📌MPS的大小在系统初始化或配置时设定,通常可以从128字节到4096字节不等。不同大小的MPS对PCIe系统的性能有不同的影响,主要体现在以下几个方面:
提高数据传输效率
较大的MPS可以减少为传输相同数据量需要的TLP数量,因此可以减少交易层包的开销(如头部、确认等),从而提高数据传输的整体效率。例如,当传输大量数据时,使用较大的MPS可以减少总线事务次数,并且由于每次事务都有相对固定的开销,因此更大的MPS通常意味着更高的吞吐率。降低延迟
小的MPS意味着数据包快速完成,这可能对于延迟敏感的应用非常关键,如实时系统或某些互动游戏。较小的数据包可以更快地被处理和确认,从而降低了数据传输的延迟。兼容性
在多个设备连接的PCIe网络中,MPS的大小必须在所有设备之间进行协调,因此需要选择一个所有设备都支持的MPS值。选择过大的MPS可能会引起兼容性问题,因为不是所有设备都能处理大尺寸的数据包。资源利用
较大的MPS可能需要更多的系统内存和缓存来缓存数据包,这对较小的或资源受限的系统可能是一个问题。相反,小的MPS则可能允许系统更节省地使用内存资源。系统性能平衡
较大的MPS可能有助于实现更高的数据吞吐率,但如果总线或设备负载较重,大的数据包可能导致队列延迟增加。因此,根据系统的特定需求和工作负载,可能需要调整MPS以实现性能和响应时间之间的最佳平衡。流量控制
大尺寸的MPS可能导致部分设备在短时间内被大量数据所淹没,这就需要更精细的流量控制机制。较小的MPS可以让流量控制更为灵活,减少因缓冲区溢出而导致的传输延迟或中断。
综上所述,MPS的不同大小直接影响数据在PCIe总线上传输的方式,以及系统性能的多个方面。因此,选择合适的MPS值非常重要,需要充分考虑系统的设计、工作负载类型和设备能力。
✨三、MRRS介绍
🌟3.1 什么是MRRS?
MRRS(Max Read Request Size)参数决定了PCIe设备Function使用存储器读请求,一次能从目标设备读取多少数据,即PCIe设备Function的读请求TLP中的Lewngth字段不能超过MRRS。若PCIe设备Function使用存储器读请求读取的数据长度超过了MRRS,则需要发送多个存储器读请求TLP。PCIe总线规定MRRS最大值为4KB,通常情况下PCIe设备Function的MRRS都会小于这个值。
在PCIe设备配置空间中,PCI Express Capability Structure的Device Control寄存器用于设置MRRS。对于多Function的PCIe设备,每个Function的MRRS可能不同。若PCIe设备Function的Max_Read_Request_Size固定为128字节,则Max_Read_Request_Size位域可实现为只读,且值为000b。
MRRS对照如下
🌟3.2 MRRS作用
📌在PCI Express (PCIe) 架构中,MRRS(Max Read Request Size)是指设备在发出单个读请求(MemoryRead TLP)时所能请求的最大数据量。
与MPS(Max PayloadSize)相似,MRRS也是在系统初始化或配置时设定的,并且通常也可以从128字节到4096字节不等。
不同大小的MRRS会对PCIe系统的性能产生以下影响: 提升带宽利用率
较大的MRRS值允许发出读请求的设备一次性请求更多的数据,这在读取大块数据时提高了带宽利用率。如果设备需要连续的大量数据,较大的MRRS可以减少所需的总请求次数,从而减少请求的开销并提高效率。
降低延迟
对于需要频繁访问但数据量较小的应用,较小的MRRS可能更有利。小的MRRS可以减少在任何给定时间内未完成请求的数量,因此可以在高负载系统中降低延迟。这对于延迟敏感的任务很关键。提高系统响应性
MRRS较小可以使系统更快地响应各种大小的读取请求,尤其是在多任务环境中,可以帮助平衡不同设备之间的响应时间,从而提高整体系统的响应性。缓存和内存管理
大的MRRS值可能需要更多的缓存空间和内存资源来处理单个较大的数据请求。对于资源有限的系统,较大的MRRS可能会造成资源压力。而较小的MRRS可帮助系统优化内存和缓存的使用。流量控制
系统需适当处理较大的MRRS请求,否则可能会造成数据包占有总线时间过长,导致其他设备无法及时发送或接收数据。因此,大的MRRS可能需要更精细的流量控制策略。兼容性问题
在多设备环境中,MRRS需要在所有设备间有良好的协调性。如果一台设备具备较大的MRRS而另一台设备不支持,就可能导致兼容性问题,因为不是所有设备都能处理或响应大尺寸的数据请求。系统性能平衡
正确的MRRS设置可以帮助平衡传输效率与系统响应性之间的关系。系统设计师需要根据具体的应用工作负载和系统的硬件能力来确定最合适的MRRS大小。
✨四、MPS、MRRS的修改
这里主要拿Linux举例
我们先用lspci 查看当前这个RC的MPS和MRRS
⚠️注意:这里的能力寄存器显示MaxPayload最大只能到512bytes,所有这里配置512以上也是没有用的。
然后我们Device Control Register的偏移为0x8,这里的基地址是0x70,所以这里我们偏移就是0x78。这里我们修改的MPS为128bytes,这里修改的就是寄存器的bit5-7,所以这里就是0x10。修改完可以retrain一下link,让EP和RC协商到一致的MPS。
这里看到MPS就已经修改为128bytes了,MRRS的修改方式也是一样,只是修改的bit位不一样,MRRS为bit12-14。