传统协议栈和DPDK

上传人:re****.1 文档编号:563496453 上传时间:2022-11-22 格式:DOC 页数:9 大小:480.52KB
返回 下载 相关 举报
传统协议栈和DPDK_第1页
第1页 / 共9页
传统协议栈和DPDK_第2页
第2页 / 共9页
传统协议栈和DPDK_第3页
第3页 / 共9页
传统协议栈和DPDK_第4页
第4页 / 共9页
传统协议栈和DPDK_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《传统协议栈和DPDK》由会员分享,可在线阅读,更多相关《传统协议栈和DPDK(9页珍藏版)》请在金锄头文库上搜索。

1、一、传统协议栈之数据包从NIC到内核1、从NIC到内存概括地说,网络数据包进入内存(接收数据包)的流程为:网线 - Rj45网口 - MDI 差分线 - bcm5461(PHY芯片进行数模转换) - MII总线 - TSEC的DMA Engine 会自动检查下一个可用的Rx bd - 把网络数据包 DMA 到 Rx bd 所指向的内存,即skb-data1、首先,内核在主内存中为收发数据建立一个环形的缓冲队列(通常叫DMA环形缓冲区)。2、内核将这个缓冲区通过DMA映射,把这个队列交给网卡;3、网卡收到数据,就直接放进这个环形缓冲区了也就是直接放进主内存了;然后,向系统产生一个中断;4、内核收

2、到这个中断,就取消DMA映射,这样,内核就直接从主内存中读取数据;对应以上4步,来看它的具体实现:1、 分配环形DMA缓冲区Linux内核中,用skb来描述一个缓存,所谓分配,就是建立一定数量的skb,然后把它们组织成一个双向链表2、建立DMA映射内核通过调用dma_map_single(struct device *dev,void *buffer,size_t size,enum dma_data_direction direction) 建立映射关系。struct device *dev,描述一个设备;buffer:把哪个地址映射给设备;也就是某一个skb要映射全部,当然是做一个双向链表

3、的循环即可;size:缓存大小;direction:映射方向谁传给谁:一般来说,是“双向”映射,数据在设备和内存之间双向流动;对于PCI设备而言(网卡一般是PCI的),通过另一个包裹函数pci_map_single,这样,就把buffer交给设备了!设备可以直接从里边读/取数据。3、这一步由硬件完成;4、取消映射ma_unmap_single,对PCI而言,大多调用它的包裹函数pci_unmap_single,不取消的话,缓存控制权还在设备手里,要调用它,把主动权掌握在CPU手里因为我们已经接收到数据了,应该由CPU把数据交给上层网络栈;当然,不取消之前,通常要读一些状态位信息,诸如此类,一般

4、是调用dma_sync_single_for_cpu() 让CPU在取消映射前,就可以访问DMA缓冲区中的内容。2、从驱动到网络协议栈网络驱动收包大致有3种情况:no NAPI:mac每收到一个以太网包,都会产生一个接收中断给cpu,即完全靠中断方式来收包 缺点是当网络流量很大时,cpu大部分时间都耗在了处理mac的中断。netpoll:在网络和I/O子系统尚不能完整可用时,模拟了来自指定设备的中断,即轮询收包。 缺点是实时性差NAPI: 采用 中断 + 轮询 的方式:mac收到一个包来后会产生接收中断,但是马上关闭。 直到收够了netdev_max_backlog个包(默认300),或者收完

5、mac上所有包后,才再打开接收中断 通过sysctl来修改 dev_max_backlog 或者通过proc修改 /proc/sys/net/core/netdev_max_backlog以NAPI为例,NAPI 相关数据结构每个网络设备(MAC层)都有自己的net_device数据结构,这个结构上有napi_struct。每当收到数据包时,网络设备驱动会把自己的napi_struct挂到CPU私有变量上。这样在软中断时,net_rx_action会遍历cpu私有变量的poll_list,执行上面所挂的napi_struct结构的poll钩子函数,将数据包从驱动传到网络协议栈。接收到一个完整的

6、以太网数据包后,TSEC会根据event mask触发一个 Rx 外部中断。cpu保存现场,根据中断向量,开始执行外部中断处理函数do_IRQ()do_IRQ 伪代码 上半部处理硬中断 查看中断源寄存器,得知是网络外设产生了外部中断 执行网络设备的rx中断handler(设备不同,函数不同,但流程类似,TSEC是gfar_receive) 1. mask 掉 rx event,再来数据包就不会产生rx中断 2. 给napi_struct.state加上 NAPI_STATE_SCHED 状态 3. 挂网络设备自己的napi_struct结构到cpu私有变量_get_cpu_var(softne

7、t_data).poll_list 4. 触发网络接收软中断 下半部处理软中断 依次执行所有软中断handler,包括timer,tasklet等等 执行网络接收的软中断handler net_rx_action 1. 遍历cpu私有变量_get_cpu_var(softnet_data).poll_list 2. 取出poll_list上面挂的napi_struct 结构,执行钩子函数napi_struct.poll() (设备不同,钩子函数不同,流程类似,TSEC是gfar_poll) 3. 若poll钩子函数处理完所有包,则打开rx event mask,再来数据包的话会产生rx中断 4

8、. 调用napi_complete(napi_struct *n) 把napi_struct 结构从_get_cpu_var(softnet_data).poll_list 上移走 同时去掉 napi_struct.state 的 NAPI_STATE_SCHED 状态gfar_process_frame() -skb-protocol = eth_type_trans(skb, dev); /确定网络层包类型,IP、ARP、VLAN等等 -RECEIVE(skb) /调用netif_receive_skb(skb)进入协议栈进入函数netif_receive_skb()后,skb正式开始协议

9、栈之旅。二、DPDK之数据包从NIC到应用程序DPDK是一套数据收发库。当一个数据包进入网卡产生中断后,响应这个中断的驱动是DPDK安装的驱动。这个驱动会通过UIO机制直接让用户态可以直接操作这个数据包。在用户态用户可以写一个程序通过DPDK提供的API处理这个数据包,比如直接在用户态写一个二层转 发实现,或者在用户态直接实现一个vRouter等。1、网卡初始化网卡驱动模型一般包含三层,即,PCI总线设备、网卡设备以及网卡设备的私有数据结构,即将设备的共性一层层的抽象,PCI总线设备包含网卡设备,网卡设备又包含其私有数据结构。在DPDK中,首先会注册设备驱动,然后查找当前系统有哪些PCI设备,

10、并通过PCI_ID为PCI设备找到对应的驱动,最后调用驱动初始化设备。一、网卡驱动注册使用attribute的constructor属性,在MAIN函数执行前,就执行rte_eal_driver_register()函数,将pmd_igb_drv驱动挂到全局dev_driver_list链表上。二、扫描当前系统有哪些PCI设备调用rte_eal_init()-rte_eal_pci_init()函数,查找当前系统中有哪些网卡,分别是什么类型,并将它们挂到全局链表pci_device_list上。1、首先初始化全局链表pci_driver_list、pci_device_list。用于挂载PCI

11、驱动及PCI设备。2、pci_scan()通过读取/sys/bus/pci/devices/目录下的信息,扫描当前系统的PCI设备,并初始化,并按照PCI地址从大到小的顺序挂在到pci_debice_list上。三、PCI驱动注册调用rte_eal_init()-rte_eal_dev_init()函数,遍历dev_driver_list链表,执行网卡驱动对应的init的回调函数,注册PCI驱动。四、网卡初始化调用rte_eal_init()-rte_eal_pci_probe()函数,遍历pci_device_list和pci_driver_list链表,根据PCI_ID,将pci_devi

12、ce与pci_driver绑定,并调用pci_driver的init回调函数rte_eth_dev_init(),初始化PCI设备。2、DPDK组件结构及功能DPDK是INTEL提供的提升数据面报文快速处理速率的应用程序开发包,它主要利用以下几个方面的支持特点来优化报文处理过程,从而加快报文处理速率: 1、 使用大页缓存支持来提高内存访问效率。 2、 利用UIO支持,提供应用空间下驱动程序的支持,也就是说网卡驱动是运行在用户空间的,减下了报文在用户空间和应用空间的多次拷贝。 3、 利用LINUX亲和性支持,把控制面线程及各个数据面线程绑定到不同的CPU核,节省了线程在各个CPU核来回调度。 4

13、、 提供内存池和无锁环形缓存管理,加快内存访问效率。 整个DPDK系统由许多不同组件组成,各组件为应用程序和其它组件提供调用接口,其结构图如下图所示:环境抽象层:为DPDK其它组件和应用程序提供一个屏蔽具体平台特性的统一接口,EAL 提供的功能主要有:DPDK加载和启动;支持多核或多线程执行类型;CPU核亲和性处理;原子操作和锁操作接口;时钟参考;PCI总线访问接口;跟踪和调试接口;CPU特性采集接口;中断和告警接口等。2、堆内存管理组件(Malloclib):堆内存管理组件为应用程序提供从大页内存分配堆内存 的接口。当需要分配大量内存小块时(如用于存储列表中每个表项指针的内存),使用这些接口

14、可以减少TLB缺页。3、环缓冲区管理组件:环缓冲区管理组件为应用程序和其它组件提供一个无锁的多生产者 多消费者FIFO队列API。 4、内存池管理组件:为应用程序和其它组件提供分配内存池的接口,内存池是一个由固定 大小的多个内存块组成的内存容器,可用于存储相同对像实体,如报文缓存块等。内存池由内存池的名称(一个字符串)来唯一标识,它由一个环缓中区和一组核本地缓存队列组成,每个核从自已的缓存队列分配内存块,当本地缓存队列减少到一定程度时,从内存环缓冲区中申请内存块来补充本地队列。 5、网络报文缓存块管理组件:提供应用程序创建和释放用于存储报文信息的缓存块的接 口,这些MBUF存储在一内存池中。提

15、供两种类型的MBUF,一种用于存储一般信息,一种用于存储报文数据。 6、定时器组件:提供一些异步周期执行的接口(也可以只执行一次),可以指定某个函数 在规定的时间异步的执行,就像LIBC中的timer定时器,但是这里的定时器需要应用程序在主循环中周期调用rte_timer_manage来使定时器得到执行,使用起来没有那么方便。定时器组件的时间参考来自EAL层提供的时间接口。除了以上六个核心组件外,DPDK还提供以下功能: 1、以太网轮询模式驱动(PMD)架构:把以太网驱动从内核移到应用层,采用同步轮询机 制而不是内核态的异步中断机制来提高报文的接收和发送效率。2、报文转发算法支持:Hash库和LPM库为报文转发算法提供支持。3、

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 模板/表格 > 财务表格

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号