NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx

上传人:b****1 文档编号:13454507 上传时间:2022-10-10 格式:DOCX 页数:18 大小:93.73KB
下载 相关 举报
NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx_第1页
第1页 / 共18页
NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx_第2页
第2页 / 共18页
NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx_第3页
第3页 / 共18页
NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx_第4页
第4页 / 共18页
NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx

《NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx》由会员分享,可在线阅读,更多相关《NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

NAPI 技术在 Linux 网络驱动上的运用跟完善文档格式.docx

  但是NAPI存在一些比较严重的缺陷:

而对于上层的应用程序而言,系统不能在每个数据包接收到的时候都可以及时地去处理它,而且随着传输速度增加,累计的数据包将会耗费大量的内存,经过实验表明在Linux平台上这个问题会比在FreeBSD上要严重一些;

另外采用NAPI所造成的另外一个问题是对于大的数据包处理比较困难,原因是大的数据包传送到网络层上的时候耗费的时间比短数据包长很多(即使是采用DMA方式),所以正如前面所说的那样,NAPI技术适用于对高速率的短长度数据包的处理,在本文的末尾提出了NAPI的改善方法,和实验数据。

  使用NAPI先决条件:

  驱动可以继续使用老的2.4内核的网络驱动程序接口,NAPI的加入并不会导致向前兼容性的丧失,但是NAPI的使用至少要得到下面的保证:

  A.要使用DMA的环形输入队列(也就是ring_dma,这个在2.4驱动中关于Ethernet的部分有详细的介绍),或者是有足够的内存空间缓存驱动获得的包。

  B.在发送/接收数据包产生中断的时候有能力关断NIC中断的事件处理,并且在关断NIC以后,并不影响数据包接收到网络设备的环形缓冲区(以下简称rx-ring)处理队列中。

  NAPI对数据包到达的事件的处理采用轮询方法,在数据包达到的时候,NAPI就会强制执行dev->

poll方法。

而和不象以前的驱动那样为了减少包到达时间的处理延迟,通常采用中断的方法来进行。

  应当注意的是,经过测试如果DECTulip系列(DE21x4x芯片)以及NationalSemi的部分网卡芯片,的测试表明如果把从前中断处理的部分都改换用设备的POLL方法去执行,那么会造成轻微的延迟,因此在进行MII(介质无关)的操作上就需要一些小小的诀窍,详见mii_check_media的函数处理流程,本文不做详细讨论。

  在下面显示的例子表示了在8139中如何把处理过程放在dev的poll方法中,把所有的原来中断应该处理的过程放在了POLL方法里面,篇幅起见,我们只介绍接收的POLL方法。

  在下面的8139CP驱动程序介绍中表明了可以把在中断程序中所做的任何事情放在POLL方法中去做,当然不同的NIC在中断中所要处理的状态和事件是不一样的。

  对于所有的NIC设备,以下两种类型的NIC接收事件寄存器响应机制:

  COR机制:

当用户程序读状态/事件寄存器,读完成的时候寄存器和NIC的rx-ring中表示的状态队列将被清零,natsemi和sunbmac的NIC会这样做,在这种情况下,必须把NIC所有以前的中断响应的处理部分都移动到POLL方法中去。

  COW机制:

用户程序写状态寄存器的时候,必须对要写的位先写1清0,如下面要介绍的8139CP就是这样的类型,大多数的NIC都属于这种类型,而且这种类型对NAPI响应得最好,它只需要把接收的数据包处理部分放置在POLL方法中,而接收事件的状态处理部分放在原先的中断控制程序中,我们等下将要介绍的8139CP类型网卡就是属于这种类型。

  C.有防止NIC队列中排队的数据包冲突的能力。

  当关断发送/接收事件中断的时候,NAPI将在POLL中被调用处理,由于POLL方法的时候,NIC中断已经不能通知包到达,那么这个时候在如果在完成轮询,并且中断打开以后,会马上有一个NIC中断产生,从而触发一次POLL事件,这种在中断关断时刻到达的包我们称为"

rotting"

这样就会在POLL机制和NIC中断之间产生一个竞争,解决的方法就是利用网卡的接收状态位,继续接收环形队列缓冲rx-ring中的数据,直到没有数据接收以后,才使能中断。

  锁定和防冲突机制:

  -1.SMP的保证机制:

保证同时只有一个处理器调用网络设备的POLL方法,因为我们将在下面看到同时只有一个处理器可以对调用netif_rx_schedule挂在POLL队列中的NIC设备调用POLL方法。

  -2.网络核心层(netcore)调用设备驱动程序使用循环方式发送数据包,在设备驱动层接收数据包的时候完全无锁的接收,而网络核心层则同样要保证每次只有一个处理器可以使用软中断处理接收队列。

  -3.在多个处理器对NIC的rx-ring访问的时刻只能发生在对循环队列调用关闭(close)和挂起(suspend)方法的时候(在这个时刻会试图清除接收循环队列)

  -4.数据同步的问题(对于接收循环队列来说),驱动程序是不需要考虑的网络层上的程序已经把这些事情做完了。

  -5.如果没有把全部的部分交给POLL方法处理,那么NIC中断仍然需要使能,接收链路状态发生变化和发送完成中断仍然和以前的处理步骤一样,这样处理的假设是接收中断是设备负载最大的的情况,当然并不能说这样一定正确。

  下面的部分将详细介绍在接收事件中调用设备的POLL方法。

  

  NAPI提供的重要函数和数据结构和函数:

  核心数据结构:

  structsoftnet_data结构内的字段就是NIC和网络层之间处理队列,这个结构是全局的,它从NIC中断和POLL方法之间传递数据信息。

其中包含的字段有:

  structsoftnet_data

  {

  intthrottle;

/*为1表示当前队列的数据包被禁止*/

  intcng_level;

/*表示当前处理器的数据包处理拥塞程度*/

  intavg_blog;

/*某个处理器的平均拥塞度*/

  structsk_buff_headinput_pkt_queue;

/*接收缓冲区的sk_buff队列*/

  structlist_headpoll_list;

/*POLL设备队列头*/

  structnet_deviceoutput_queue;

/*网络设备发送队列的队列头*/

  structsk_buffcompletion_queue;

/*完成发送的数据包等待释放的队列*/

  structnet_devicebacklog_dev;

/*表示当前参与POLL处理的网络设备*/

  };

  核心API:

  1.netif_rx_schedule(dev)

  这个函数被中断服务程序调用,将设备的POLL方法添加到网络层次的POLL处理队列中去,排队并且准备接收数据包,在使用之前需要调用netif_rx_reschedule_prep,并且返回的数为1,并且触发一个NET_RX_SOFTIRQ的软中断通知网络层接收数据包。

  2.netif_rx_schedule_prep(dev)

  确定设备处于运行,而且设备还没有被添加到网络层的POLL处理队列中,在调用netif_rx_schedule之前会调用这个函数。

  3.netif_rx_complete(dev)

  把当前指定的设备从POLL队列中清除,通常被设备的POLL方法调用,注意如果在POLL队列处于工作状态的时候是不能把指定设备清除的,否则将会出错。

 

  如何在8139CP使用NAPI:

  从POLL方法的本质意义上来说就在于尽量减少中断的数目,特别在于大量的小长度的数据包的时候,减少中断,以达到不要让整个操作系统花费太多的时间在中断现场的保护和恢复上,以便把赢得的时间用来在我网络层上的处理数据的传输,例如在下面介绍的8139CP中断的处理过程中,目的就在于尽快把产生中断的设备挂在poll_list,并且关闭接收中断,最后直接调用设备的POLL方法来处理数据包的接收,直到收到数据包收无可收,或者是达到一个时间片内的调度完成。

  RTL8139C+的数据接收环形缓冲队列:

  RTL8139C+的接收方式是一种全新的缓冲方式,能显著的降低CPU接收数据造成的花费,适合大型的服务器使用,适合IP,TCP,UDP等多种方式的数据下载,以及连接IEEE802.1P,802.1Q,VLAN等网络形式;

在8139CP中分别有64个连续的接收/发送描述符单元,对应三个不同的环形缓冲队列--一个是高优先级传输描述符队列,一个是普通优先级传输符描述队列,一个是接收符描述队列,每个环形缓冲队列右64个4个双字的连续描述符组成,每个描述符有4个连续的双字组成,每个描述符的开始地址在256个字节的位置对齐,接收数据之前,软件需要预先分配一个DMA缓冲区,一般对于传输而言,缓冲区最大为8Kbyte并且把物理地址链接在描述符的DMA地址描述单元,另外还有两个双字的单元表示对应的DMA缓冲区的接收状态。

  在/driver/net/8139CP.C中对于环形缓冲队列描述符的数据单元如下表示:

  structcp_desc{u32opts1;

/*缓冲区状态控制符,包含缓冲区大小,缓冲区传输启动位*/u32opts2;

/*专门用于VLAN部分*/u64addr;

/*缓冲区的DMA地址*/};

  8139CP的NIC中断:

  staticirqreturn_t

  cp_interrupt(intirq,void*dev_instance,structpt_regs*regs)

  structnet_device*dev=dev_instance;

  structcp_private*cp=dev->

priv;

  u16status;

  /*检查rx-ring中是否有中断到达*/

  status=cpr16(IntrStatus);

  if(!

status||(status==0xFFFF))

  returnIRQ_NONE;

  if(netif_msg_intr(cp))

  printk(KERN_DEBUG"

%s:

intr,status%04xcmd%02xcpc

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1