Completion
在学习Non-Posted Transaction之前,我们首先来了解一下什么是Completion(完成)。
PCIe系统里,所有的读请求(Read request)都是分离事务(split transactions)。所谓分离,是指读命令和读到的数据并不是同步返回的。Requester(发起读请求的设备)发起一个读请求,Completer(返回读取的数据给requester的设备)稍后才会把完成数据返回给Requester。数据读事务被分离成两个步骤:读请求(Read request)和完成(Completion)。
IO和配置写也是分离事务,同样有完成报文。不过IO和配置写的完成报文纯粹是为了确认当前事务真正完成而已,完成报文并无真正意义的数据。
完成报文是由Completer在Non-Poster事务中返回给Requester的。跟Posted事务类似,Completer发出完成包后,同样不知道这个包是否则真正到达了目标设备。
由于PCIe是点对点的传输,对于Completer来说,只要这个完成报文到达与Competer连接的设备,就认为这此事务完成了。
不同的是:如果完成报文并没有最终到达目标设备,Requester端会触发完成超时(Completion timeout)。
注意:完成报文是基于ID路由的。如上图:EP发起了一个读请求到RC,同时,开启一个定时器,RC收到读请求之后,稍后会把完成报文按ID路由发送给EP。如果这个完成报文在Switch中路由到下行口时,Switch到EP的链路down掉,那么这个完成报文同样会被Switch“吃掉”。同时,当Requester一直收不到完成报文,定时器超时,会触发一个完成超时(Completion timeout)的异常。