首页 > 其他分享 >初识DPDK

初识DPDK

时间:2024-08-15 16:30:03浏览次数:9  
标签:中断 网卡 处理 初识 内核 数据包 cpu DPDK

DPDK是data plane developme kit的缩写,是一个c语言编写的软件开发框架,常用于高性能网络的开发。它的主要功能就是让用户绕过linux内核协议栈,将网卡收到的数据包直接在用户态空间内使用用户自定义的逻辑去处理数据包,或者将用户态空间的数据包绕过一系列的内核协议栈封装直接从网卡发送出去。这种用户直接和网卡进行交互的模式会减少内核和用户空间之间的内存拷贝,然而这只是其中一个优点。

出现dpdk的原因

linux操作系统是一个集合了计算存储网络等功能的复杂系统,网络对于linux来说只是其中一个功能模块。在早期的操作系统发展阶段,由于网卡和网络传输速度等限制,linux内核处理网络数据包并未出现太大瓶颈。然而随着网卡升级迭代,规格不断从10G到40G再到如今的100G网卡,网络数据包传输速率的瓶颈已经不在网卡。另外由于网络带宽增加,到达网卡的流量也会逐渐增大。在这种情况下操作系统处理网络数据包就会是整个链路的瓶颈。

为什么操作系统内核成为瓶颈

先介绍网卡收包部分之前是如何优化的
网卡收到数据包要经过一系列的操作处理,最后到达用户空间。早期网卡收到数据包会触发硬中断
硬中断是一个注册到cpu的信号,每一个网卡在初始化时,都会注册一个硬中断到cpu,发送信号给cpu,触发内核去进行收包操作。
如果cpu收到硬中断信号就会停下当前处理的任务,切换上下文去处理网卡发送的硬中断。如果每一次网卡触发硬中断cpu都需要立即处理,那cpu可能会话费大量时间去处理这些任务,甚至其他任务会阻塞。因此触发硬中断之后会注册一个软中断去处理,然后迅速去处理之前的任务,这里内核调用raise_softirq()来触发软中断。触发硬中断通常被称为上半部分。下半部分都是软中断处理的。软中断处理有一系列的注册函数,将每个软中断信号和一些函数关联起来。调用open_softirq()函数可以注册函数到某一个中断信号的函数集合softirq_vec中。

为什么用软中断:在内核中硬中断和软中断的优先级不同,一个硬中断信号必须立刻处理,而一个软中断信号优先级较低,可以放到一个软中断队列中稍后处理。这里的立即和稍后都是从cpu的角度来看的。由于cpu的操作时间最小单位都是时钟周期,因此对于cpu来说这个稍后操作也是在若干时钟周期内,谈不上非常的慢。以当前主流cpu的频率为4GHz为例,一秒内包含400亿个时钟周期。

ksoftirqd处理软中断

ksoftirq线程是一个内核级别的线程,每个cpu都有单独的一个ksoftirq线程用于处理本cpu的软中断。当然ksoftirqd也可以处理来自其他核的软中断,然而从性能方面考虑这种方式并不推荐,因为涉及到cpu间通信,有额外的开销。然而如果我们想实现某个类型的中断都由某个cpu处理,可以使用中断亲和性来进行绑定。这种情况下对软中断信号设置了中断亲和性,某一个软中断信号会被调度到指定的CPU上处理,即中断亲和性绑定。

ksoftirqd功能:处理软中断,是一个常驻线程,不会进行创建和销毁。这里会去调用__do_softirq()去遍历被触发的软中断信号,并顺序执行信号对应注册的函数。
__do_softirq功能:真正去处理软中断和执行对应函数,这一步并不会去创建一个子线程,所有函数都在ksoftirqd中执行

引入napi
如果每次收到数据包都经过硬中断和软中断,在流量没那么大情况下不会对负载造成太大问题。当流量到达一定程度时这种两个中断结合在一起的方式也会造成不小的开销。比如收到很多小数据包(当然可以尽量避免小包传输)。为了应对这种情况可以使用napi机制,采取轮询方式处理数据包。网卡设备如果要支持napi,需要在初始化时初始化napi_struct,这个结构体包含了驱动自定义的poll函数用于收包。在收到硬中断之后,并不会调用raise_softirq触发软中断,而是使用ISR(中断服务例程)调用__napi_schedule()函数,将网卡的poll函数注册到poll_list中。在__napi_schedule()中会调用__raise_softirq_irqoff()触发软中断,net_rx_action()会被调用,这个函数会遍历poll_list,执行每个napi_struct函数的poll函数来轮询收包。

问题1:怎么判断poll函数已经执行完成,如果没有数据包了会发生什么
napi_struct中有一个字段budget表示可以接受多少个数据包。这个是为了防止长时间陷入软中断。如果到达budget就会停下。另外一种情况没有数据包就会停止。当这一轮轮询结束之后,会调用napi_complete()函数。这个函数会将设备从poll list移除,同时使能硬中断,cpu不会忽略下一次的硬中断。下一次收到数据包会重复上述步骤。因此设备不会一直陷入poll状态中。

ISR: 一段硬件设备在初始化时注册到内核的代码,在硬中断之后会执行硬件自己的逻辑

上述过程中经过不断优化,napi成为了最终处理数据包的方案。网卡高效的处理数据包之后是如何到达操作系统的呢
网卡的DMA操作会将数据包拷贝到操作系统的内存空间,这一动作之后才触发软中断。在通过DMA之后poll函数会从DMA内存读取数据并转换成内核协议栈可以识别的数据包sk_buff,然后调用__netif_receive_skb()函数将sk_buff送入内核

内核操作
内核收到数据包会进行一系列处理,通常在OSI四层模型中从下向上处理,在物理链路层会进行二层数据包处理,二层主要信息包括目的mac地址48位,源mac地址48位,以及协议类型,内核会根据目的mac和源mac做一系列判断。协议类型是上层协议的类型,即IP层协议类型,在ip层有ip协议和arp协议等。如果数据包携带了vlan信息,需要对vlan进行处理。vlan通常携带一个12位的vlanid,因此vlan号的范围在0到4095之间。如果携带vlan信息,那么这部分就在报文中目的mac之后,上层协议信息之前。

为什么dpdk性能更高

在dpdk出现之前,一个普遍认知是intel architecture不适合处理大量网络数据包。然而dpdk并没有从本质上优化因特尔架构,而是从工程角度找到可以优化收发包的点
比如:

  1. 如果网卡驱动一直去轮询收包,cpu不会去一直切换上下文
  2. 驱动是运行在内核态的,如果使用用户态驱动可以避免内存拷贝或者系统调用,优化DMA和mbuf格式
  3. 优化cache和内存访问。如果在cpu执行任务时一直发生cache miss就需要发生cache交换,如何避免大量的cache miss和将内存指令数据载入到cache中
  4. 传统UNA架构导致cpu访问内存的速度一致,如果使用NUMA架构,并让cpu尽量访问本地内存就可以大大加速内存访问速度
  5. 亲和性与独占 如果cpu只需要处理网络数据包并将处理任务固定在某些cpu上,就可以避免cpu之间切换任务,单一cpu也不会切换上下文去处理其他任务
    还有一些可以优化的点都会在后面介绍

dpdk主要模块

核心库 core libs 提供大页,线程池,定时器,无锁队列,缓存池等功能 EAL timer ring mbuf mempool malloc
用户态驱动 PMD 支持轮询和线程绑定
精确匹配 LPM 精确匹配 最长匹配 通配符匹配
限速 Qos 原子操作包括限速等

下面以skeleton为例解释如何运行dpdk

eal初始化入口
rte_eal_init()初始化 -> rte_eal_remote_launch()启动线程并绑定到核 -> 每个核都执行传入的函数

rte_eal_init函数 主要做了如下操作

eal_create_cpu_map 获取numa信息并读取cpu信息创建逻辑核映射,读取亲和性信息
rte_eal_cpu_init 初始化cpu和numa相关信息
eal_parse_args 解析启动时的命令行参数
rte_eal_intr_init 初始化中断处理,创建一个中断处理函数
rte_eal_timer_init 初始化定时器
rte_bus_scan 扫描总线设备
后面还有一系列的初始化操作

标签:中断,网卡,处理,初识,内核,数据包,cpu,DPDK
From: https://www.cnblogs.com/Djw945/p/18361252

相关文章

  • SpringMVC - 初识
    1.简介SpringMVC是一个创建Web应用程序的框架,它是遵循Model-View-Controller的设计模式。SpringMVC通过DispatcherServlet来接收请求,然后对应对具体的controllers,models和views.2.一个HelloWorld事例1.添加maven依赖<dependency><groupId>org.springframework<......
  • 初识c语言
    什么是c语言c语言是一门计算机编程语言,可广泛用于底层开发。c语言是一种能以简易方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。第一个c语言程序入门第一个c语言代码如下:那么其运行的结果就是打印helloworld,运行结果如下:......
  • 初识Spring
    文章目录一.Spring是什么?1.为什么要学?2.学什么?3.怎么学?二.Spring相关概念1.初识Spring1.1.Spring家族1.2.了解Spring发展史2.Spring系统架构2.1.系统架构图2.2.课程学习路线3.Spring核心概念3.1.目前项目中的问题3.2.IOC、IOC容器、Bean、DI3.3.核心......
  • 0001初识MySQL
    ##内容参考网课##笔记整理一,数据库基础知识1.数据库概念英文名称:Database,即存储数据的仓库;专业解释为存储在计算机磁盘上的有组织,可供享的大量数据的集合 类型关系数据库与非关系数据库两类,前者包含MySQL,Oracle,SQL,Server,SQLite等,后者包含Redis,MongoDB等数据库管理系......
  • 1.1javaSE初识
    JDK:JDK是JavaDevelopmentKit的缩写,意为Java语言的软件开发工具包(SDK)。它是Java编程的核心工具,为程序开发者提供了一个完整的开发环境。JRE:Java运行环境,是运行Java程序所必须的环境的集合,包含了JVM(Java虚拟机)和Java核心类库。Java开发工具:包括编译器(javac)、解释器(java)、调试......
  • Java入门学习——Day01初识Java
    一、为什么学习Java1.1Java历史1.1.1背景介绍        Java语言最初由SunMicrosystems的詹姆斯·高斯林(JamesGosling)等人在1991年开始开发,当时SunMicrosystems希望开发一种能够在各种消费电子设备上运行的小型程序语言,最初命名为Oak。        1995年5月......
  • 初识LangChain的快速入门指南
    LangChain概述LangChain是一个基于大语言模型用于构建端到端语言模型应用的框架,它提供了一系列工具、套件和接口,让开发者使用语言模型来实现各种复杂的任务,如文本到图像的生成、文档问答、聊天机器人等。LangChain简化了LLM应用程序生命周期的各个阶段:开发阶段:使用Lan......
  • 算法与数据结构——初识
    算法初识算法定义:算法(algorithm)是在有限时间内解决特定问题的一组指令或操作步骤,它具有以下特性。问题是明确的,包含清晰的输入和输出定义。具有可行性,能够在有限步骤、时间和内存空间完成。各步骤都有确定的定义,在相同的输入和运行条件下,输出始终相同。数据结构定义:数据......
  • Vue初识,vue的插值语法,vue指令之文本指令,vue指令之事件指令, vue指令之属性指令
    ⅠVue初识【一】前端的发展史#1HTML(5)、CSS(3)、JavaScript(ES5、ES6、ES13):编写一个个的页面->给后端(PHP、Python、Go、Java)->后端嵌入模板语法->后端渲染完数据->返回数据给前端->在浏览器中查看#2Ajax的出现->后台发送异步请求,Render+Ajax混合#3单......
  • 三.初识C语言(3)
    1.选择语句    如果你好好学习,校招时拿一个好offer,走上人生巅峰。如果你不学习,毕业等于失业,回家卖红薯。    这就是选择。图示如下。    选择语句关键字主要有if,switch。①if语句        我们先以if语句举例,帮助我们有一个初步的了解。......