在解释completion timeout机制前,我们首先说一下PCIe split transaction协议是什么,以及为什么PCIe要选择split transaction?
Split transaction协议是从PCI-X总线的引入的一个重要特性,该传输协议替代了PCI总线的delayed 数据传输方式,提高了Non-Posted transaction的传输效率。
Split transaction交互过程,如果上图所示:
requester 发起一个read transaction。
read请求到达completer,但是completer不能马上返回data(completer需要准备对应的数据)。
completer会记住这个transaction(address、transaction type、byte count、requester ID等)。
completer 返回split的response(ACK或者NCK),此时对PCI-X总线而言, requester可以结束整个read request的bus cycle,其他的request可以继续占用总线了。
completer准备好数据后,重新申请总线,初始化一个split completion bus cycle并使用split completion返回数据。
requester收到completion with data,整个read request完成。
相对PCI而言,PCI-X这种completer准备好数据后,主动发起split completion的方式类似write bus cycle。在两个bus transaction(read request和split completion transaction直接)之间,bus可以被其他的transaction利用,这种处理方式有效提高了PCI-X总线的使用效率。PCIe总线继承了PCI-X的这种 splittransaction。
根据PCI Express System Architecture的数据,相对PCI的50%-60%的传输效率,这种split的方式可以把PCI-X传输效率提高到85%。
Split transaction带来效率提升的好处,也带来了风险:requester可能无法接收到期望的completion(可能是completion被错误地路由到别的地方导致requester永远不能收到completion,也可能是completer返回completion比较慢,或者requester和completer之间链路的问题导致超过了requester的等待时间,completion都没有返回到requester)。当这种情况发生时,为了让requester有一个恢复机制,就定义了completion timeout机制。
针对completion timeout机制,协议规定如下:
(1)具备发出需要completion的request(Non-Posted request)能力的PCIe设备,必现要实现completion timeout机制。
由于switch不会主动发出需要completion的请求,因此,completion timeout机制仅仅适用于RC、PCIe-PCI bridge和endpoint。
(2)Configuration software可以disable掉completion timeout机制。Completion timeout的大小可以通过Device ctrl 2 寄存器的completion timeout value字段设置。Completion timeout通过requester来报错,也就说了completion timeout的错误是requester发出的。
(3)对于memory read request,可能需要多个completion,只有当requester收到了所有的completion后才认为request完成了。如果在completion timeout前,requester只收到了部分但不是全部的completion,requester可以保存或者丢弃completiontimeout前接收到的数据。
Device capabilities 2 reg 的bit[3:0] Completion Timeout Ranges Supported,这个字段规定device function支持的completion timeout value。值得注意的是It is strongly recommended that theCompletion Timeout mechanism not expire in less than 10 ms,也就说Range A 50us to 10ms的这个Range是不被推荐的。
Device capabilities 2 reg 的bit[4] Completion Timeout Disable Supported字段显示是否支持disable completion timeou机制。
对于RootPort来说,Completion Timeout Disable Supported是可选的。
Device control 2 reg 的bit[3:0] Completion Timeout Value,这个字段规定device function等待completion的时间。该字段必须是Devicecapabilities 2 reg 的bit[3:0] Completion Timeout Ranges Supported的range。
Software可以在任何时候改变completion timeout value字段。如果在completion timeout字段被修改时,还有pending的request,对于outstanding的request,hardware可以使用新的或者旧的completion timeout value。hardware计算completion超时的起始时间可以从completion timeout value被修改的时间点算,也可以从request发出的时间点算。
值得注意的是Spec再一次强调:It is strongly recommended that the Completion Timeout mechanism not expire inless than 10 ms。
Device control 2 reg 的bit4 Completion Timeout Disable用来disable completion timeout机制(必须要Device capabilities 2 reg 的bit[4] Completion Timeout Disable Supported字段为1b时,才能设置该bit)。
当requester发出Non-Posted request,并且直到requester的completion timeout超时,requester都没有收到对应的completion。那么,允许requester通过发出新的请求来recover这个错误。允许requester尝试恢复0次,1次或者多次,但是次数必须是有限的。如果没有后续的recovery动作,requester必须通过uncorrectable error message来标识错误。
如果completion timeout的severity是non-fatal的,并且requester 选择了通过发送一个新的请求尝试recovery,requester必须首先把当前的错误当做Avisroy Non-Fatal的错误处理。支持AER的requester通过发送ERR_CORmessage来标识这个错误。
CPU型号 |
Code name |
Cap: Completion Timeout Ranges Supported |
Ctrl: Completion Timeout Value |
11th Gen Intel(R) Core(TM) i7-11700K |
Rocket Lake |
ABC |
50us-50ms |
12th Gen Intel(R) Core(TM) i5-12600K |
Alder Lake |
ABC |
50us to 50ms |
Intel(R) Xeon(R) Silver 4309Y |
Ice Lake |
ABC |
260ms-900ms |
Intel(R) Xeon(R) Gold 6130 |
Sky lake |
BCD |
260ms-900ms |
Intel(R) Xeon(R) Gold 6430 |
Sapphire Rapids |
ABC |
260ms to 900ms |
AMD Ryzen 7 5700G |
|
ABCD |
65ms-210ms |
PCIe spec强烈推荐completion timeout的时间不要少于10ms。按照经验,intel CPU一般会设置在65ms-210ms(sandy bridge)或者下一档次260ms-900ms(Ivy bridge及其之后的微架构)。
intel CPU不同代的CPU微架构改变很大,下面是sky lake的CPU架构。
在sky lake CPU中有非常多的timer(见下图table6-30),每个timer对应不同sub-modules的超时时间。RootPort的completion timeout只是IIO到PCIe/DMI的超时,IIO后面还有一个Cbo的TOR timeout和Core的3-strike。
sky lake CPU中有个CHA(caching home agent)模块,该模块内有个Cbo的模块,在CBo内部有个TOR的模块,其全称是 table of request,TOR用来track pending CBo transaction。sky lake CPU的MCE的一种叫做TOR timeout就是说这个模块中的transaction超时了。
由于CPU内部每个timer计算超时的起始时间点不同,CPU操作都是流水线的,再加上PCIe是spilt transaction协议,不用等上一笔request返回completion,只需要completer返回ACK或者NCK,CPU(requester)就可以发起下一笔请求,并且Non post、post、completion之间是有order要求的,这样会导致大量的transaction的累积效应和反压。因此,尽管Root Port的completion timeout的超时时间(通常都是几百毫秒级别的)小于MCE的时间(通常都是秒级别的)。在外设异常的场景,completion timeout仍然无法保证CPU访问外设时不出现MCE。
如果RootPort出现completion timeout的错误,应该去读header log reg或者抓trace,来看看是否是访问外设导致的,如果是访问外设导致,则需要分析是RootPort的completion timeout value设置不合理,还是switch 路由问题,或者外设响应缓慢。如果不做分析,也不管CPU架构和其他的几个timer的大小,贸然把RootPort的completion timeout改大。当外设异常时,可能会掩盖RootPort的completion timeout错误,但是这种做法可能会导致TOR timeout或者3-strike。