3.283. 硬件同步时间差问题的设计逻辑

本文讨论一个很多软硬件配合中经常遇到的模式。

比如IOMMU,你给某个设备的IOMMU设置了一个页表,IOMMU根据这个页表对设备的读写请求进行翻译,现在你修改了这个页表(比如unmap了一片内存),软件的后续逻辑就是根据这个新的页表来进行的(比如unmap的内存就和回收给其他人使用),但IOMMU虽然收到你的命令了,但IOMMU不是一个单点的控制点,它翻译过的那些请求,会被发到系统的其他位置,比如总线的一个Station上,它还会继续做这种请求,这是软件的假设就不对了。

同样的问题可以发生在系统级的中断控制器上,比如你设定一个中断只能报给1,2,3号三个cpu,然后现在你修改为只能报给4,5,6号CPU,这个配置发给中断控制器了,问题是这个中断可能已经被转发出去了,正停在系统总线的某个位置上呢,中断控制器收到你的请求可以管还没有发出去的中断,但发出去的它就没有办法了。

这个问题抽象起来,是说,如果我们需要在软件上执行一个影响全局的配置,但这个配置涉及到多个节点的同步问题,我们应该用什么方式去解决问题。

最极端直接的解决思路就是:

  1. 还能收回(修改)的广播全部收回(修改)

  2. 不能收回的等待结束

想想,这个好像也是唯一的思路了。

但这个东西最大的问题是软件得等,这个可能很久。IOMMU有一个经典问题就是如果消息到设备上,需要:

后面这个unmap_dma就很慢,因为要等所有请求都完成,才能继续下去。

既然前面的方案是唯一的思路,这里我们也就只能做规避,比如这样:

这样,unmap的时候,请求发出去就结束,同时挂个钩子,异步等待所有在在途请求结束才真的释放对应的资源。

好像都是这个套路了,想不出其他花样了。

我写这个分析一方面是有一个设计需要一个这样的分析,另一方面呢,我其实也想为这个文档写一个注释:架构和装修,说明高层设计确实是不需要所有细节,但逻辑仍然可以是严密的。