关闭

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

2879人阅读 评论(1) 收藏 举报
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处理大量的数据包,那就开启它,不管怎样,这只是一个用法和配置的问题,何时开启,以及份额设置多少,需要一个事前采样的过程。
       今天早上起太早,写了两篇随笔,所以也就没出去溜,现在快七点了,小小和孩她妈还睡着呢,我准备下去上班了....
2
0
查看评论

Socket层实现系列 — 睡眠驱动的同步等待

主要内容:Socket的几个I/O事件、Socket的同步等待机制。 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd   概述   socket上定义了几个IO事件:状态改变事件、有数据可读事件、有发送缓存可写事件、有IO错误事件。 ...
  • zhangskd
  • zhangskd
  • 2015-05-23 22:24
  • 3783

Linux和windows下内核socket优化项

Linux: net.core.netdev_max_backlog = 30000  每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目 net.core.somaxconn = 262144   用来限制监听(LISTEN)队列最大数据...
  • lcx46
  • lcx46
  • 2013-10-08 09:45
  • 12203

提高 Linux 上 socket 性能

使用 Sockets API,我们可以开发客户机和服务器应用程序,它们可以在本地网络上进行通信,也可以通过 Internet 在全球范围内进行通信。与其他 API 一样,您可以通过一些方法使用 Sockets API,从而提高 Socket 的性能,或者限制 Socket 的性能。本文探索了 4...
  • q454684431
  • q454684431
  • 2016-01-25 11:24
  • 4148

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

Linux的网络协议栈非常独立,上下通过两个接口分别和用户态以及设备相连,也可以看作是北向和南向接口...北向通过socket接口,南向通过qdisc接口(你可以认为是上层的netdev queue,对于接收接口,NAPI的poll队列则是另一个例子),不管是socket还是qdisc,都是基于队列...
  • dog250
  • dog250
  • 2015-07-08 06:44
  • 2879

linux poll 和 等待队列休眠的关系

说明:linux版本2.6.37.1 结合相关资料的概括和总结,在此做个记录,有误之处请网友指正,谢谢! 1.poll机制和等待队列 应用层通过系统调用poll函数进入内核,内核执行相应的sys_poll函数。在sys_poll函数中调用do_sys_poll函数。do_sys_p...
  • rockrockwu
  • rockrockwu
  • 2012-03-01 19:24
  • 5465

Linux内核:poll机制

在编写驱动程序的过程当中我们可以使用poll机制来非阻塞的打开我们的设备文件,我们知道,在之前我们编写CC1100的驱动程序以及倒车雷达的驱动程序的时候,在read函数中都有用到过wait_event_interruptible_timeout这个函数,这个函数的主要作用就是采用非阻塞的read,因...
  • JansonZhe
  • JansonZhe
  • 2015-09-19 16:20
  • 3018

Linux网络编程——tcp并发服务器(poll实现)

想详细彻底地了解poll或看懂下面的代码请参考《Linux网络编程——I/O复用之poll函数》 代码: #include #include #include #include #include #include #include #include #include #incl...
  • lianghe_work
  • lianghe_work
  • 2015-06-17 17:13
  • 3063

sk_buff

位置:include/linux/skbuff.h
  • u014211079
  • u014211079
  • 2014-09-02 09:08
  • 1827

sock结构

/**   * struct sock - network layer representation of sockets   * @__sk_common: shared layout with inet_timewait_sock   * @sk_shutdown:...
  • sunlei0625
  • sunlei0625
  • 2017-03-13 08:14
  • 227

Linux下的socket编程实践(八) Select的限制和poll(并发的初步知识)

select的限制 用select实现的并发服务器,能达到的并发数一般受两方面限制: 1)一个进程能打开的最大文件描述符限制。这可以通过调整内核参数来改变。可以通过ulimit -n(number)来调整或者使用setrlimit函数设置(需要root权限),但一个系统所能打开...
  • NK_test
  • NK_test
  • 2015-10-20 22:44
  • 3000
    个人资料
    • 访问:7038017次
    • 积分:84471
    • 等级:
    • 排名:第18名
    • 原创:1434篇
    • 转载:2篇
    • 译文:0篇
    • 评论:3111条
    文章存档
    最新评论