Linux内核3.11的socket busy poll机制避免睡眠切换

原创 2015年07月08日 06:44:14
Linux的网络协议栈非常独立,上下通过两个接口分别和用户态以及设备相连,也可以看作是北向和南向接口...北向通过socket接口,南向通过qdisc接口(你可以认为是上层的netdev queue,对于接收接口,NAPI的poll队列则是另一个例子),不管是socket还是qdisc,都是基于队列来管理的,也就是说,三个部分是独立的,socket只能看到读写队列,而看不到协议栈本身,socket在读一个数据的时候,它取的是队列里面的数据,至于说这个数据是谁放进去的,它并不知道,是不是协议栈放进去的,它也不必验证。
       socket隔离了用户进程和协议栈,RX/TX queue隔离了协议栈和设备驱动。
       这种隔离方式给编程和设计带来了简便,然而却不利于性能。
       Linux的RPS设计,旨在让一个CPU既处理数据包的协议栈接收流程(软中断内核线程上下文,或者任意上下文的软中断处理),又运行用户态处理该数据包的进程。我说这种设计有利也有弊,如果仅仅是旨在提高cache利用率,那么这种设计是对的,但是有没有想过别的情况,如果一个CPU在NET RX软中断处理的最后将一个skb推到了一个socket队列,并试图唤醒等待进程,那么它下一步该干些什么呢?实际上它下一步应该返回设备,继续去poll下一个skb,然而RPS的设计不是这样,RPS的设计旨在希望让该CPU继续处理用户态进程....这就必然要进行一次进程切换以及用户/内核态的切换,虽然服务器的CPU cache利用率提高了,但是协议栈处理相关的CPU cache利用率反而降低了。事实上,CPU cache是否在进程切换以及用户/内核态切换后刷新,这个是体系结构相关的,并不是说所有的体系结构都能带来好的结果。
       必须做进一步的测试。
       我觉得最好的办法就是用户进程和内核的NET RX软中断处在不同的CPU核心上,然而这两个CPU核心共享二级cache或者三级cache。
       ...
       Linux内核随之发展出了更好的方案,那就是突破上述的独立三大部分,让socket直接深入到设备层直接poll skb!!注意,这是一个poll操作,并不是让socket直接处理协议栈流程。socket直接poll的意思是说,socket在队列中没有读到数据包的时候,并不是睡眠,然后等待NET RX内核线程将数据包放入队列后将其唤醒,而是直接去问设备:现在有数据包吗?如果有,我直接带走它们去协议栈,而不需要你送它们去了。这是一种“拉”的方式,而不是以往的那种“推”的方式,拉和推的区别在于,对于接收者,拉是同一个实体,是主动的,而推则是被动的。
       这就解决了RPS试图解决却又没有完美解决的问题。这种机制叫做busy poll。
       RPS试图让软中断处理完数据包后,切换到用户进程,此时软中断将间歇,然后数据包中断后又要切回来...busy poll就不是这样,它直接绕过了软中断这个执行体,直接靠socket自身所在的执行体来主动拉取数据包进行处理。避免了大量的任务交接导致的切换问题。
       我不晓得对于转发的情况,是否也能采用busy poll的方式来提高性能,这需要测试。以上的阐述只是理想情况,真实情况是,socket可能替别的socket从设备拉取了一个数据包,甚至这个数据包只是转发的,不与任何socket关联...因为数据包只有经过标准的路由以及四层处理后,才能和一个具体socket关联,在设备驱动层,指望找到这个关联是徒劳且无望的!不管怎么说,控制权在用户自己手中,凭概率来讲,如果你的设备中大量的数据包都是转发包,就不要开启这个功能,如果你的进程拥有少量的socket处理大量的数据包,那就开启它,不管怎样,这只是一个用法和配置的问题,何时开启,以及份额设置多少,需要一个事前采样的过程。
       今天早上起太早,写了两篇随笔,所以也就没出去溜,现在快七点了,小小和孩她妈还睡着呢,我准备下去上班了....
版权声明:本文为博主原创,无版权,未经博主允许可以随意转载,无需注明出处,随意修改或保持可作为原创!

相关文章推荐

UDP_CORK,TCP_CORK以及TCP_NODELAY

这三个选项十分有意思,并且困扰了很多人。特别是cork选项,它到底和nodelay有什么区别,到底怎样影响了Nagle算法。在tcp的实现中(特指linux内核的协议栈实现),cork和nodelay...
  • dog250
  • dog250
  • 2010年10月14日 20:47
  • 9737

linux负载均衡调度算法的实现

按照计划,本想写一篇负载均衡的调度算法分析,但查看了网上的资料,发现这篇文章已经写的比较好,我都没用那么大的耐心写的那么详细。 下面是我在网上找到的资料,这里发个链接。 http://blog.c...
  • imtgj
  • imtgj
  • 2012年02月20日 23:11
  • 2427

Linux内核:poll机制

在编写驱动程序的过程当中我们可以使用poll机制来非阻塞的打开我们的设备文件,我们知道,在之前我们编写CC1100的驱动程序以及倒车雷达的驱动程序的时候,在read函数中都有用到过wait_event...

Linux内核:Poll机制理解

最近看了一下Linux Poll 机制的实现,看了韦老师的分析文档,总结如下: int poll(struct pollfd *fds,nfds_t nfds, int timeout); ...

linux2.6.38 linux内核poll机制解析

预备知识:

模拟linux内核进程的启动和进程的切换机制

原创作品转载请注明出处  《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000  QEMU是一套由Fabrice Be...

linux内核分析:进程切换机制

“陈涛 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”这次作业主要运行一个小程序...

Linux内核协议栈的socket查找缓存路由机制

是查路由表快呢?还是查socket哈希表快?这不是问题的根本。问题的根本是怎么有效利用这两者,让两者成为合作者而不是竞争者。这是怎么回事?       我们知道,如果一个数据包要到达本地,那么它要经过...
  • dog250
  • dog250
  • 2015年01月11日 11:18
  • 2656

socket的内核和上层通信机制(netlink) -- linux内核

需要在linux网卡驱动中加入一个自己的驱动,实现在内核态完成一些报文处理(这个过程可以实现一种零COPY的网络报文截获),对于复杂报文COPY下必要的数据交给用户态来完成(因为过于复杂的报文消耗CP...

linux内核线程睡眠与唤醒

这里以内核usb gadget driver中f_mass_storage驱动为例子进行说明。static int sleep_thread(struct fsg_common *common) { ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux内核3.11的socket busy poll机制避免睡眠切换
举报原因:
原因补充:

(最多只允许输入30个字)