LINux网络的NAPI机制详解一

在查看NAPI机制的时候发现一篇介绍NAPI引入初衷的文章写的很好,通俗易懂,就想要分享下,重要的是博主还做了可以在他基础上任意修改,而并不用注明出处的声明,着实令我敬佩,不过还是附上原文链接!

http://blog.csdn.net/dog250/article/details/5302853

处理外部事件是cpu必须要做的事,因为cpu和外设的不平等性导致外设的事件被cpu 当作是外部事件,其实它们是平等的,只不过冯氏机器不这么认为罢了,既然要处理外部事件,那么就需要一定的方法,方法不止一种,大致有中断和轮询以及一种 混杂又复杂的方式,也就是DMA方式。中断是cpu被动处理的一种方式,也就是说cpu不知道何时中断,只要有了中断就会通知cpu,而cpu此时必须停 下一切来处理,而轮询是cpu主动查询并处理的过程,cpu隔一会查询一下外设看有没有事情可做。 
我们看一下这两种方式,中断看似很高效,但是却会遗漏一些数据,避免遗漏的机制要么由硬件实现要么由上层的软件实现,而轮询就没有中断高效了,它会做很多 徒劳的操作,而且必须引入暂存机制,就是说由于cpu不可能在每次查询硬件的时候正好有事情可做,为了不使请求遗漏,随时到来的请求必须暂存在一个私有的 区域内,只要这些都做好了,轮询是不会造成请求遗漏的,中断在很多中断高频触发的时候会造成大量遗漏和竞争,毕竟只有一个cpu,同一个时间点只能有一个 请求被处理,而轮询由于是cpu分批打包处理请求的,因此不会遗漏。 
以上的论述有点像我讨论过的inotify和rsync实现的文件同步,inotify的实现就是中断,很显然有遗漏,而rsync实现的就是轮询,显然 没有遗漏,cpu主动做的事情它自己最明白了,但是它要是被动应对就不会这么明白了,它只是按照规则应对罢了,丝毫不会存在任何策略。如果中断过于频繁也 是不好的,因为cpu必须处理中断,这会导致cpu没有时间做正经事,此时最好用轮询,但是外设活动很缓和的时候,用轮询就不合适了,因为询也是白询,此 时比较适合用中断,可是系统怎么知道何时外设活跃何时外设缓和呢?啊哈,可以用智能预测算法嘛,以历史值为依据!不,不能那样的,因为这是在内核,内核不 是秀算法的地方,我另外的文章强调过这一点。那么怎么办?好办,还是约定,就是将中断和轮询相结合,这就是linux网卡驱动中的NAPI的方式,它的设 计十分巧妙,就是在第一个包到来的时候中断,然后关闭中断开始轮询,等某一次轮询完毕后发现没有数据了,那么内核默认此次数据已经传输完毕,短时间内不会 再有数据了,那么停止轮询,重新开启中断,这样会减少很多次的中断,虽然某次轮询完毕发现没有数据并不能代表1ms以后不会再有数据,但是刚才说了,要想 使算法简单,必须做一个合理的约定,人性化的约定,如果说加上判定什么情况下百分之九十五的可能不需要轮询了并不是不可能,只是维护那个算法的开销太大, 它直接抵消了算法带来的优势。用人的思想考虑,如果一个饭店的服务员不停的从厨房接菜然后送到餐桌,注意是不停的,10秒一趟,但是突然隔了半分钟没有厨 房的人吆喝接菜,如果你是服务员,难道你还会去窗口等菜吗?反正我不会,我会蹲下来稍微休息一下,即使刚蹲下来就会有新活我也愿意赌一把,虽然输得可能性 很大很大。 
如此一来,我们看一下NAPI解决了什么问题,第一,它限制了中断的数量,一旦有中断过来就停掉中断改为轮询,这样就不会造成cpu被频繁中断,第 二,cpu不会做无用功,就是所谓的无用的轮询,因为只有在中断来了才改为轮询,中断来了说明有事可做,看看NAPI将中断和轮询结合的是多么巧妙啊。以 往的实现中,在硬件网卡中断中将skb排入队,然后在软中断中出队并交由上层处理,一切配合的看起来那么好,可是在遇到突发快速小包传输的时候就会导致频 繁中断,因为是突发的包,因此不能用轮询,因为是快速小包,因此不适合用中断,最终二者巧妙结合,各取优势,优势互补,绝了!这个框架适合一切的网卡模 式,因此就将传统的网卡收发机制也纳入到了NAPI框架,很简单,就是用原来的逻辑实现dev的poll回调函数即可,至于传统的非NAPI方案,完全可 以用一个桩子代替。 
      cpu利用率和频繁的中断问题通过NAPI机制解决了,但是这又引入了一个新的问题,就是这可能造成cpu利用率的失衡,这个怎么理解呢?NAPI启动之 后,网卡的中断就会变得很少,要知道中断balance的目前实现是基于中断数量的均衡,它根本不管中断数量均衡之后引起的softirq导致的cpu使 用率是否均衡,softirq的均衡也是一样,比如一个是磁盘softirq,一个是网卡的NAPI的softirq,前者瞬间就可以完成但是来得频繁, 而后者要轮询网卡并且处理协议栈很耗时但是来得不频繁,可是balancer不管这么多,它只是觉得磁盘的softirq太多了而为了数量均衡会将更多的 softirq发布到softiqr少的cpu上,它根本不在乎这些更多的softirq是否会带来更高的cpu负载。NAPI削弱了中断/软中断均衡的 作用,毕竟它的主导在轮询,轮询会占用很多的处理器资源,而中断和软中断数量很少。中断或者软中断特别是软中断数量在cpu间的均衡可能造成各个cpu负 载的严重不均衡,因为各个硬中断几乎都是瞬间完成的,硬中断不能耽搁太久的,但是各个不同软中断的任务量缺是千差万别的,因此绝对不能按照数量来均衡软中 断,然而一般都是硬中断触发软中断,它们都在同一个cpu上,因此如果想简单的实现NAPI在多cpu上的cpu使用率均衡,那么必须重新实现硬件的负载 均衡机制,这样可以吗?不!因此这样会使得两个部分耦合过重,因此必须让硬中断的均衡和cpu的均衡解耦合,其实现在的内核就是这么做的,所以才会造成 cpu不均衡,硬件中断的均衡和cpu均衡的解耦合带来的好处就是我们可以对软中断均衡做文章,而硬中断的负载均衡还是用数量均衡实现,软中断彻底从硬件 中断中解放出来,不再是在处理硬中断的cpu上触发软中断,而是可以在任何cpu上触发软中断,由于不同软中断的任务量千差万别,因此我们定义一个软中断 的“权值”,然后按照不同软中断这个权值和数量的积的和来均衡软中断,这样的话,我想各个cpu的负载就均衡了,现在问题是,各个不同的软中断的“权值” 的计算问题,呵呵。累了,有时间再说。一个论坛上一哥们儿写了一个patch,很有创意,比我这里的软中断均衡的粒度要小得多,这个补丁不是均衡软中断, 而是将软中断进一步也分成了上下两部分,和cpu相关的上半部必须加急处理,这样不会对cpu造成太大负载,仍然用硬件中断均衡,因为硬件中断的cpu触 发软件中断,这部分不变,但是软中断的下半部就需要均衡了,该补丁为每一个cpu创立了一个工作队列,然后将ip_rcv 这种操作的cpu相关的工作放到软中断的上半部,其实就是从一个cpu的skb队列中抽取一个skb,然后将这个skb随机放到这些工作队列中进行处理, 和整个软中断均衡有何不同吗?大大不同。软中断均衡针对的是一个poll_list里面的所有的skb,而这哥们儿的补丁针对的是一个skb,粒度十分 小,但是没有测试,是不是太小了呢?这其实也是一个模式方法,逐步的将粒度精细化,类似将中断分成上半部和下半部的做法是放之四海而皆准的,这是一种哲 学,也是一种风格。 
如果你说你没有见过linux的方式,那么只要你上过枯燥的计算机课或者读过枯燥的教科书或者你是天才你就知道一个叫做生产者/消费者的模型,它其实和 linux的中断的上半部和下半部很类似,上半部是生产者,只管将环境搭建好,数据准备好,然后触发下半部,其实就是唤醒消费者,这个思想在多线程并发中 很著名,而并发就是为了提高系统吞吐量,在SMP环境中也是为了并发,因此我们何尝不用用生产者/消费者模型呢?它也是一种低耦合的各司其职的模型。如果 你想不到NAPI的中断+轮询的方式,那么你听说过linux下怎样做文件同步的吗?rsync+inotify的方式听说过吗?如果没有就赶快 google一下吧。rsync+inotify其实就是中断+轮询,rsync是轮询,而inotify是中断,这个同步方案十分高效,保证只有在 inotify监控到文件变化的时候才开始轮询,平时就睡觉,inotify不再需要监控到具体的文件,因为它只负责告知事件,具体工作由rsync完 成,inotify只需要告诉一端文件变化了即可,那岂不是要全部同步了即使你只改了一个字符,别忘了rsync的算法,这就是另一篇文章了。所以不要再 觉得linux内核深不可测了,它的特点只有一个就是简单,比起用户应用那些复杂的算法,内核的算法一向简单易懂,其实内核的每一个机制,都可以在用户空 间找到原型的。 
可是cpu对NAPI处理的均衡真的有意义吗?用户难道就不能忍受一个cpu占用100%而另一个0%吗?表面上看是那样的,但是如果考虑cache或者 切换代价的话就不一样了,性能因素不仅仅是cpu使用率还有别的,如果一件事的开销过大,即使cpu使用率再均衡也是划不来的。这就好像初学者用free 命令看内存时总是吓一大跳。特别是NAPI的网络数据包操作,比如TCP的IP包的分段重组问题,一旦乱序就要重传,这种情况下,一个linux主机如果只是作为一台路由器的话,那 么进入系统的一个TCP包的不同分段如果被不同的cpu处理并向一个网卡转发了,那么同步问题会很麻烦的,如果你不做同步处理,那么很可能后面的段被一个 cpu先发出去了,那么在真正的接收方接收到乱序的包后就会请求重发,这是不希望的,因此还是一个cpu串行处理好,这也许是TCP/IP协议栈的缺陷, 但是没有办法,协议是那样的,只能那样去应对。在大流量下,由于napi的缘故,网卡的中断被关闭了,此时那个第一次被中断的cpu正在poll这个网卡,因此所有的流量都会聚集到这个cpu上,这可能是一个设计的缺陷吧。



LINux网络的NAPI机制详解一

时间: 2024-10-22 14:40:02

LINux网络的NAPI机制详解一的相关文章

Linux网络安全模型及iptables详解(1)

Linux网络安全模型及iptables详解 基本概念 Firewall:工作在主机或网络边缘,对进出的报文按事先定义的规则进行检查, 并且由匹配到的规则进行处理的一组硬件或软件,甚至可能是两者的组合 硬件防火墙:在硬件级别实现部分功能的防火墙:另一个部分功能基于软件实现 软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙: 主机防火墙:工作于主机边缘,只能对一台主机起到保护作用 网络防火墙:工作于网络边缘,对多台主机起到保护作用(定向规则) iptables:防火墙规则编写工具,位于用

linux网络防火墙-iptables基础详解(重要)

一:前言 防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种.无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘.而我们的任务就是需要去定义到底防火墙如何工作,这就是防火墙的策略,规则,以达到让它对出入网络的IP.数据进行检测. 目前市面上比较常见的有3.4层的防火墙,叫网络层的防火墙,还有7层的防火墙,其实是代理层的网关. 对于TCP/IP的七层模型来讲,我们知道第三层是网络层,三层的防火墙会在这层对源地址和目标地址进行检测.但是对于七层的防火

Linux网络服务(深入详解)

本篇结构: 查看网络配置测试网络连接设置网络地址参数建立双网卡 一.查看网络配置 查看所有活动网络接口信息 众所周知,上网需要网卡.在微软环境下,使用ipconfig命令就能查看到该设备的IP地址,而在Linux环境中,则使用: ifconfig命令 //查看本机网络设备信息 其中, ens33--为该设备网卡名称,跟PC机网卡功能相同lo--回环网卡(专门用于自测的网卡,检测TCP服务是否上线)virbr0--虚拟桥接网卡 查看并修改主机名 查看主机名使用"hostname"命令进行

Linux下OOM Killer机制详解

http://www.cnblogs.com/ylqmf/archive/2012/11/05/2754795.html http://wuquan-1230.blog.163.com/blog/static/298111532011112851419497/ http://www.linuxidc.com/Linux/2013-09/90092.htm http://www.cnblogs.com/GoodGoodWorkDayDayUp/p/3473348.html http://www.t

Java网络编程和NIO详解6:Linux epoll实现原理详解

Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO https://blog.csdn.net/column/details/21963.html 部分代码会放在我的的Github:https://github.com/h2pl/ Linux epoll实现原理详解 在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者pol

Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理

Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO https://blog.csdn.net/column/details/21963.html 部分代码会放在我的的Github:https://github.com/h2pl/ 浅谈 Linux

Linux学习总结之LVM2详解

大纲: 简介 版本 LVM基本术语 LVM模块 具体操作 对添加的硬盘进行分区( fdisk /dev/[hs]d[a-z] ) 对创建的分区创建物理卷(pvcreate) 给逻辑卷创建逻辑容器(卷组) 在卷组创建大小不同的逻辑卷(lvcreate) 给已存在的卷组扩大容量 实现在线扩大LVM容量 实现缩减LVM容量(不支持在线缩减) 减小卷组容量 利用给LVM创建快照,并完成备份并还原 简介: LVM是Logical Volume Manager(逻辑卷管理器)的简写,又译为逻辑卷宗管理器.逻

Linux下DNS服务器搭建详解

 Linux下DNS服务器搭建详解 DNS  即Domain Name System(域名系统)的缩写,它是一种将ip地址转换成对应的主机名或将主机名转换成与之相对应ip地址的一种机制.其中通过域名解析出ip地址的叫做正向解析,通过ip地址解析出域名的叫做反向解析. 下面对DNS的工作流程及原理进行简要说明 DNS的查询流程:需要解析服务的Client先查看本机的/etc/hosts:若无结果,则client查看本地的DNS缓存服务器:若无结果,则查找所属域的首选DNS服务器:若此时本地首选DN

Linux逻辑卷管理LVM2详解

一. 前言LVM是逻辑卷管理(Logical Volume Manager)的简称,它是建立在物理存储设备之上的一个抽象层,允许你生成逻辑存储卷,与直接使用物理存储在管理上相比,提供了更好灵活性.LVM将存储虚拟化,使用逻辑卷,你不会受限于物理磁盘的大小,另外,与硬件相关的存储设置被其隐藏,你可以不用停止应用或卸载文件系统来调整卷大小或数据迁移.这样可以减少操作成本.LVM与直接使用物理存储相比,有以下优点:1. 灵活的容量.当使用逻辑卷时,文件系统可以扩展到多个磁盘上,你可以聚合多个磁盘或磁盘