分享

内核抢占和低延迟相关工作

 Liucw2012 2012-03-23

低延迟

我觉得这就是对CONFIG_PREEMPT_VOLUNTARY的解释了!取自《深入Linux内核架构》

当然,即使没有启用内核抢占,内核也很关注提供良好的延迟时间。例如,这对于网络服务器是很重要的。尽管此类环境不需要内核抢占引入的开销,但内核仍然应该以合理的速度响应重要的事件。例如,如果一网络请求到达,需要守护进程处理,那么该请求不应该被执行繁重IO操作的数据库过度延迟。我已经讨论了内核提供的一些用于缓解该问题的措施:CFS和内核抢占中的调度延迟。第5章中将讨论的实时互斥量也有助于解决该问题,但还有一个与调度有关的操作能够对此有所帮助。

基本上,内核中耗时长的操作不应该完全占据整个系统。相反,它们应该不时地检测是否有另一个进程变为可运行,并在必要的情况下调用调度器选择相应的进程运行。该机制不依赖于内核抢占,即使内核连编时未指定支持抢占,也能够降低延迟。

发起有条件重调度的函数是cond_resched。其实现如下:

  1. kernel/sched.c   
  2. int __sched cond_resched(void)   
  3. {   
  4.         if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE))   
  5.                 __cond_resched();   
  6.                 return 1;   
  7.         }  
  8.         return 0;  

need_resched检查是否设置了TIF_NEED_RESCHED标志,代码另外还保证内核当前没有被抢占 ,因此允许重调度。只要两个条件满足,那么__cond_resched会处理必要的细节并调用调度器。

如何使用cond_resched?举例来说,考虑内核读取与给定内存映射关联的内存页的情况。这可以通过无限循环完成,直至所有需要的数据读取完毕:

  1. for (;;)  
  2.         /* 读入数据 */  
  3.         if (exit_condition)  
  4.                 continue;  

如果需要大量的读取操作,可能耗时会很长。由于进程运行在内核空间中,调度器无法象在用户空间那样撤销其CPU,假定也没有启用内核抢占。通过在每个循环迭代中调用cond_resched,即可改进此种情况。

  1. for (;;)  
  2.         cond_resched();  
  3.         /* 读入数据 */  
  4.         if (exit_condition)  
  5.                 continue;  

内核代码已经仔细核查过,以找出长时间运行的函数,并在适当之处插入对cond_resched的调用。即使没有显式内核抢占,这也能够保证较高的响应速度。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多