Linux ,c/c++, web,前端,php,js
分类: LINUX
2013-05-29 09:12:02
数据包在网络协议栈中所走的路径根据数据包是传输、接收还是转发不同而不同:
但虚拟设备可能有所不同,如回环设备不会使用硬件设备的协议栈,而有些虚拟设备可以避免硬件的某些限制如MTU等,因而可以提高性能。
网络设备与内核通信有两种方式:
接收数据帧分为两部分工作:首先驱动程序将该数据包复制到内核可访问的输入队列,然后内核再予以处理,通常将该帧传给相关协议专用的处理函数。第一部分是在中断中完成的,可以抢占第二部分的执行。接受侦并复制到接收队列的代码优先级高于实际处理帧的代码。处理数据包时可能被新到来的数据帧打断。因此,当流量很大时,实际处理数据包的CPU可能被不断打断去接收数据包,而旧数据包得不到处理,输入队列就会溢出。这种情况就是receive-livelock现象,虽没有死锁,但系统也会崩溃。
当CPU接收到一个中断通知后,就会调用与该中断事件相关联的处理函数,这种关联性由编号识别。在处理函数执行期间,内核程序就处于中断环境,服务于该中断事件的CPU就会关闭其中断功能,而不能被抢占。无论相同类型还是不同类型的中断事件都不能打断该中断事件。
中断事件产生的一般流程是:
因此,中断处理函数是非抢占和非可重入的函数,这种设计可以降低竞争的可能性,但对CPU的性能有很大的影响。若处理一个中断的动作中有很多操作可以等待,则可以引入下半部分机制来进行处理。现代中断处理函数分为上半部和下半部两部分,上半部完成在释放CPU前必须执行的操作,以保留数据,而下半部则处理剩余可以慢慢完成的工作。
实现下半部机制有多种方式,目前常见的是由软中断soft IRQ实现的任务tasklet方式和工作队列两种方式,但工作队列可以休眠,而tasklet是在中断环境中完成的不能休眠。Linux网络系统部分主要采用tasklet方式实现下半部延期操作。
bottom half、tasklet和softirq在并发性上的区别: