读拷贝更新RCU和中断延迟
原文网址:https://lwn.net/Articles/65832
原文作者:Corbet
原文时间:2004年1月10日
自从RCU算法被kernel 2.5接纳之后,就获得大量应用。在很多场景下,RCU避免了对锁的竞争,可以大幅度提高多处理器系统的性能和可扩展性。更多关于RCU的工作原理,请参考 https://lwn.net/Article/4974和https://lwn.net/Article/37889这两篇讨论,或者参与SCO小组的讨论。
但RCU还存在一个小问题,它影响了*软*件*中断响应时间【its effect on interrupt response times】。对于内核近期不会引用的数据结构,RCU的清零工作会延迟/拖后进行。清理工作是在软中断上下文中执行的,也就是说,在硬中断之后或在重调度期间【at rescheduling time】才会执行RCU清理工作。RCU需要清理的、受保护的数据链表,可能相当长;例如,目录入口缓存【dentry cache】。这样一来,软件中断上下文的执行时间可能很长。换句话说,RCU清理程序代码就会长期霸占处理器,这导致高优先级进程一直处于等待状态。
Dipankar Sarma 观察到这种现象,发现RCU回调函数在某些情况下需要400毫秒。这看上去好像不长,但这种响应延迟也足够长了。因此,他提供补丁来解决这个问题。
基于现代内核编程思想,这种问题似乎存在一个标准处理方法:创建一个新的内核线程。Dipankar的补丁确实也是这么做的;它在每个CPU上都绑定了一个krcud线程,只有在RCU回调列表比较长的时候才负责清理工作。如果回调列表比较短,还是在软件中断上下文中来处理,因为这样会更快些;但是如果列表比较长,默认超过256项时,一旦检测到有高优先级的实时进程需要执行时,RCU的软中断处理就会将CPU控制权返还给内核调度器,将列表尾部的数据留到krcud线程来处理。
Dipankar补丁的测试效果比较好,整个系统延迟小于400毫秒。但是他还没有得出最后的结论,因为补丁还需要更多的测试。如果事情进展顺利,linux2.6内核会很快响应这个补丁。