❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
✨ 1. PCIe组播基本介绍
👉1.1 背景介绍
PCIe事务传输支持单播、组播和广播三种方式,其中以单播和广播应用最多。单播是点对点的传输,只有一个请求者和一个完成者,同一时刻主机只能与众多子设备中的一个设备进行通信;广播是点到面的传输,有一个请求者和多个完成者,请求者下游全局地址范围内的所有PCIe组件作为完成者,常见于消息事务的传播,比如RC广播消息,从RC发送消息给其所有下游组件;组播是介于单播和广播之间的传输方式,有一个请求者和多个完成者,请求者下游指定地址范围内的多个PCIe组件都可以作为完成者,同一时刻允许主机向多个设备或单个设备向多个主机发送数据,用于PCIe存储器写事务或地址路由的事务。
相较于单播,组播能够把数据发给一组设备,避免了发送重复的数据流,能够提升系统传输性能;相较于广播,组播具有更好的指向性和安全性。更多PICe组播的益处,请参考 《Why PCIe-Based Systems Need Multicast》。
下图(图1)是一个日常使用PCIe组播的例子。本例中,作为EP的视频设备同时发送视频数据到显示器及两个存储器。
图1 组播系统举例
👉1.2 组播操作基本概念
组播能力结构定义了组播的地址范围,该地址范围被等分为大小相同的N个组播窗口,一个组播窗口被称为一个组播组(Multicast Group,MCG),如图2所示。每个支持组播的Function都应实现该组播能力结构,以提供事务的路由方向、决定每个MCG的事务接收或透传。PCIe 5.0中MCG是6bit位宽的域,最多能够支持64个组播组。
图2 PCIe组播地址分段示意图
❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
✨ 2. PCIe组播软件配置
👉2.1 组播能力结构
图3 组播扩展能力结构
具备PCIe组播能力的switch需要实现组播扩展能力结构,组播扩展能力结构如图1所示。组播扩展能力结构中的寄存器及其用途如下:
Multicast Extend Caoability Header
: PCIe组播扩展能力头标(图4),包含了PCIe组播扩展能力的ID、扩展能力版本,并指向下一能力。Multicast Capability Register
:组播能力寄存器(图5),MC_Max_Group用以指明该组件支持的最大组播组数目(N表示最大支持N+1组,N最大为63组),MC_Window_Size_Request用以指示EP需要的组播窗口大小,MC_ECRC_Regeneration_Supported指示是否支持ECRC重构。Multicast Control Register
:组播控制寄存器(图6),具有组播能力结构的组件在MC_Enable置一后才启动组播机制,MC_Num_Groupu用以指示用户需要启用的组播组数(N表示启用N+1组),超过MC_Max_Group的组播组将不会启用组播。MC_Base_Address Register
:组播基地址寄存器(图7),MC_Base_Address用以设置组播地址范围的基地址,基地址低12bit为0;MC_Index_Position指示基地址中最低有效位。MC_Receive Register
:组播接收控制寄存器(图8),有效位为bit[MC_Max_Group:0],bit[N]置一表示该function将复制一份组播事务并发给组播组N。MC_Block_All Register
:组播阻塞所有事务控制寄存器(图9),有效位为bit[MC_Max_Group:0],bit[N]置一表示该function不会向组播组N发送任何组播事务。MC_Block_Untranslated Register
:组播阻塞透明传输控制寄存器(图10),有效位为bit[MC_Max_Group:0],bit[N]置一表示该function不会向组播组N发送透传传输(未转换地址)的组播事务。MC_Overlay_BAR Register
:MC_Overlay控制寄存器(图11),在MC_Overlay机制中使用,用于改变组播事务中的访问地址。MC_Overlay_Size用以重新定义地址空间的大小,MC_Overlay_BAR用以设置重定向的地址。
图4 组播扩展能力头标
图5 组播能力寄存器
图6 组播控制寄存器
图7 组播基地址寄存器
图8 组播接收控制寄存器
图9 组播阻塞所有事务控制寄存器
图10 组播阻塞透明传输控制寄存器
图11 MC_Overlay_BAR register
👉2.2 组播窗口大小设置
组播事务的多个最终接收者组的播窗口大小是很有可能不同的。一个极端例子,某个组播窗口需要的窗口大小可能会覆盖整个设备的存储空间范围。反之,某个组播窗口大小可能仅需要覆盖FIFO寄存器内一小段特定的偏移。为了应对这种情况,EP通过设置其组播能力寄存器内的组播窗口大小域MC_Window_Size_Requested来表明该EP需要的窗口大小。
在可用地址空间允许的情况下,资源分配软件应尽可能满足所有组件对组播窗口大小的最低请求,并通过设置MC_Index_Position来设置组播窗口大小以满足最大请求。有些情况下,可将单个较大组播窗口的请求拆分为多个窗口较小的连续组播组,从而满足对较大窗口的需求。
👉2.3 Host组播范围配置
对于通用目的系统而言,组播地址范围通常不会配置得与主机内存空间存在交叠。若主机内存也在目标组播范围之内,RC需要有IOMMU来把组播窗口的部分地址甚至整页映射到主机内存。或则,switch上行端口中采用MC_Overlay机制来把组播窗口的部分地址映射到主机内存。
对于缺少IOMMU的嵌入式系统而言,把组播窗口内存空间配置得与主机内存直接重叠反倒更灵活一些。
👉2.4 RC组播设置
根据实际需求,支持组播能力的多RP的RC中可以实现多个组播能力结构。若需要多个组播能力结构,软件应独立设置每个组播结构中的各个域。为了支持到RCiEP的组播,实现时需要把所有经MC_Base_address确认过的组播TLP暴露给RCiEP内所有潜在的组播目标EP。RCiEP依据其组播能力结构内的MC_Receive寄存器来决定是否接收该TLP。
👉2.5 多function设备组播设置
所有作为潜在组播目标的端口function及EP function均需实现组播能力结构,并设置其MC_Receive向量。在每个组件内,软件独立配置其组播能力结构中的MC_Enable, MC_Base_Address, MC_Index_Position及MC_Num_Group域。在多function的设备内,只在该组件多个组播BAR中的一个组播BAR内实现地址解码逻辑就够了。
👉2.6 组播能力结构更新规则
组播能力结构中部分域支持随时更新,包括MC_Enable, MC_Num_Group, MC_Receive, MC_Block_All, MC_Block_Untranslated。在更新这些域的值的时候必须按顺序更新。采用相同TC的两笔TLP A和B先后从相同入端口到达,若A在某个组播域把值更新为X,则B相同域也应更新为X或者采用更新的值。
除可随时更新的域之外,其他域只有在组件内所有function的MC_Enable都清零后才能更新,这样的组播域有MC_Base_Address, MC_Index_Position。
❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
✨ 3. PCIe组播事务处理
👉3.1 组播事务触发与路由
📌 PCIe组播事务需满足以下三个条件:
- MC_enable置一;
- 所发送TLP为存储器写或地址路由的消息,两者均为转发请求;
- TLP中地址在几个MCG内存空间范围内,即 MC_Base_Addr <= AddrTLP < (2MC_Index_Position * (MC_Num_Group+1))
在支持组播的交换节点所有function及多function上行端口中,应把MC_Enable、MC_Base_Address、MC_Index_Position及MC_Num_Group等相同的域通过软件配置为相同的值,这样交换节点入端口及其他组件可以使用其任意一个function的MC相关域的值。如若不然,入端口就有可能取到不同的值而导致不确定的情况发生。
PCIe组播操作只支持P(Posted)请求,若NP(Non-Posted)请求的地址刚好在某个MCG地址范围内,这仍然不是一个组播操作,仍应按照单播的处理方式对齐进行处理。
一旦触发了组播操作,常规的地址路由规则不再适用,而是遵循以下规则:
从TLP地址中提取组播组号MCG,计算方式为MCG=((AddressTLP - MC_Base_Address) >> MC_Index_Position) & 3Fh,其中MC_Base_Address及MC_Index_Position可以采用任何一个function中该域的值。
接下来,组件根据MC_Block_All及MC_Block_Untranslated域比特向量的值来检查提取到的MCG:switch及RP采用入端口的MC_Block_All/MC_Block_Untranslated值检测入端口组播TLP,EP Function采用其function内的MC_Block_All/MC_Block_Untranslated值来检测待发的组播TLP。若MCG中存在MC_Block_All要阻塞的TLP,则对应TLP当作组播阻塞TLP处理;若MCG中存在MC_Block_Untranslated要阻塞的TLP,且TLP中的地址为未转换地址(根据头标AT域判断),则对应TLP同样当作组播阻塞TLP处理。
对于switch及RC,若TLP在该组件中没有被阻塞,且从TLP提取出的MCG在MC_Receive寄存器中的对应位都有置一,那么该TLP会被前推到该组件除入端口外的所有端口;对于EP,该TLP会被所有function接收;若没有port前推或function接收该TLP,该TLP会被静默丢掉。
为了防止形成组播环路,即便RP或Switch Port的MC_Receive设置符合转发条件,也绝对不能沿入端口推回该TLP。有一个例外,若RC收到了一笔单播请求且刚好落在了其组播窗口内,这时RC可以沿其该请求进入RC的相同入端口反向前推该请求。
组播触发后会暂停常规的地址路由,包括switch中的默认上行路由。
若开启了ACS机制,ACS服务中唯一能用于组播操作的访问控制功能是ACS源地址验证。
👉3.2 PIO组播事务的透传
由于软件没有控制PIO(Programmed I/O)请求的AT域的架构机制,所以PIO发出的储存器写请求TLP地址为未经转换的地址。正因为如此,软件应确保在switch发出组播PIO写请求之前清除掉switch上行端口中MC_Block_Untranslated相关控制比特位,否则会阻塞住送往组播窗口的合法组播PIO写请求。也正因为软件会清理switch上行端口的MC_Block_Untranslated位,建议在RC中实现以下地址转换能力:
- 实现了组播能力结构的RCiEP应支持未转换地址的组播事务访问控制;
- 实现了组播能力结构的P2P(peer-to-peer)RP应支持P2P转发未转换地址的组播事务访问控制。
同样,建议多function设备EP都能够实现组播能力结构。
👉3.3 组播事务如何重定向
ACS P2P请求重定向及ACS定向转换P2P机制提供了一种方法,可以把带有未转换地址的P2P请求进行重定向至RC并进行访问控制检查,并把经过地址转换的P2P请求直接路由到P2P目的,以此来提升系统性能。但⚠️在组播事务中是没有这种重定向机制的⚠️。
为了实现类似的功能,可以在RC内配置一块或多块内存空间,这些空间不在组播地址范围内,并在RC内对这些地址重映射到组播组的地址范围。这样,产生组播事务的发送者不管有没有ATS服务能力,都能通过访问这些组播地址范围外的地址空间并经RC地址检查及重映射后,转换成携带转换地址且目标为组播地址范围的事务,从而间接访问到组播地址范围。具备ATS服务能力的发送者可以请求及缓存转换后的地址,并直接往受保护的组播窗口发送地址转换后的写请求,而无需绕行到RC。
为确保在硬件上只能采用转换后地址直接访问组播窗口,可以通过软件设置组播组中MC_Block_Untranslated寄存器来阻塞未经转换的地址访问。
👉3.4 组播事务排序
组播事务没有其独特的排序方法。组播事务为转发请求,遵循转发请求相关的排序规则。
👉3.5 组播事务阻塞处理
若组播事务被MC_Block_All或MC_Block_Untranslated机制阻塞住了,该笔事务会被丢弃。阻塞住该笔事务的function就是该事务的完成者,完成者必须按照常规的错误处理方式记录并上报MC_Blocked TLP错误。此外,完成者必须在其状态寄存器或第二状态寄存器合适的地方将Signaled Target Abord位置一。为了隔离错误并分析错误原因,强烈建议在具有组播能力的function内实现AER。
在RC或switch内,如果入端口接收TLP时发生错误,则由入端口上报错误。若EP function在准备发送TLP的过程中出现错误,则由EP function上报错误。
❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
✨ 4. MC_Overlay机制
👉4.1 MC_Overlay机制介绍
有些EP只有一个BAR,不具备组播能力结构。为了让单BAR EP能够同时接收单播事务及组播事务,可以采用MC_Overlay机制来实现。具体实现方法为:① 软件配置switch下行端口的MC_Overlay_BAR来启动MC_Overlay机制,把全部或部分组播地址映射到EP BAR地址范围;② 在switch上行端口,MC_Overlay机制可用于把组播地址范围的一部分重映射为主内存相关联的存储空间。
下行端口的MC_Overlay机制适用于所有从该口出去的TLP,上行端口的MC_Overlay机制适用于上行退出该端口的TLP,某端口的MC_Overlay机制不适用于从该口接收到的TLP、目标地址在该端口存储空间范围内的TLP及多function上行端口中在function间P2P路由的TLP。
一旦开启了MC_Overlay机制,overlay操作会把组播TLP地址中比特数大于等于MC_Overlay_Size的部分替换为MC_Overlay_BAR中的对应比特。即:
Egress_TLP_Addr = (MC_Overlay_Size < 6) ? Ingress_TLP_Addr : { MC_Overlay_BAR[63:MC_Overlay_Size], Ingress_TLP_Addr[MC_Overlay_Size-1:0] };
👉4.2 ECRC重构
MC_Overlay机制下的ECRC如下表(表1)所示。
表1 MC_Overlay ECRC规则
如前文所述,开启了MC_Overlay机制后,TLP中的地址会被修改。这就有个问题,如果TLP开启了ECRC,TLP地址被修改了但ECRC没改,那么ECRC校验会出错。当然,switch和RC中的端口可以选择是否支持ECRC重构。若支持重构,强烈建立尽全力缩减原TLP ECRC校验到地址修改后TLP ECRC重构之间这段时间。因为中间这段时间TLP处于不受保护的状态,存在数据完整性的漏洞。
对于开启了MC_Overlay机制但不支持ECRC重构的端口,可以穿过端口的组播TLP中剥离ECRC,这是接收端EP可以开启ECRC校验。这种情况下,EP将受益于非组播TLP的ECRC,而不用检测MC_Overlay机制修改过后的组播TLP的ECRC。
若组件支持组播ECRC重构,但在TLP地址更新之前便检测到了ECRC错误,这种情况下应将重构的ECRC倒置,确保不会因为ECRC重构而漏报了这次ECRC错误。
❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
✨ 5. 其他
👉5.1 组播到不支持组播能力的EP
对于不支持组播能力结构的EP,其无法分辨接收到的TLP是组播还是单播TLP。 系统设计者可以对这一现象加以利用,即采用这样不支持组播能力的EP作为组播事务的目标。这么做有两个需求:① 该设备上游switch端点内的虚拟PCI-PCI桥base/limit寄存器应配置为与组播地址范围部分重叠,或者开启MC_Overlay机制;② 单个组播目标function可以位于PCIe to PCI/PCI-X桥的PCI/PCI-X一侧。
若不具备组播能力结构的EP被用作组播目标,且不具备MC_Overlay机制,则有必要采用与组播TLP相同的地址去读取EP存储空间。这样的话,落在组播窗口范围内的存储器读请求便不是错误。对于落在组播窗口但不在RCiEP范围或switch下行端口范围内的读请求,该请求会采用标准的地址路由规则上行,且最终会被当成UR处理。TODO
⚠️
👉5.2 组播拥塞避免
组播的使用增加了switch输出链路的使用率,组播组的越大、组播流量在总流量中占比越大,输出链路的使用率越高。这无疑会增加拥塞的风险。为了减小组播造成的拥塞风险,有意作为组播目标的组件应把组播TLP的处理速度设计得足够快(线速),有意作为组播源头的组件也应有对应机制限制组播发出的速度(不要过快)。
在许多应用程序中,应用程序的组播数据流会有一个固有的速率限制且不会造成拥塞。此外需要明确的机制来限制组播注入的速率,需要选择带有足够缓冲区的switch以在未开启流控的情况下存放burst组播数据,或选择一个能够以所需速率处理组播事务的目标组播组件。选择一套好的机制及组件来服务于应用,这是一个好的系统设计者应做到的。
❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
📚参考
- PCI Express Base Specification Revision 5.0 Version 1.0 (22 May 2019)
- PCI Express Technology - Comprehensive Guide to Generation1.x, 2.x and 3.0. Mike Jacson, Ravi Budruk, MindShare, Inc.
- Why PCIe-Based Systems Need Multicast
- 解析:单播、广播和组播的区别
- 《PCIe-Multicast(组播)实现》