[DPDK编程手册]3环境抽象层

环境抽象层:

环境抽象层(EAL)主要负责对底层资源(如硬件和内存空间)的访问,通过通用的接口对应用程序和库实现环境细节的封装或者隐藏。其初始化例程决定如何分配这些底层资源(如PCI设备、计时器、控制台、内存空间等)。

EAL提供的典型服务包括:

  • 加载和启动DPDK:DPDK及其应用程序会被链接为单一应用,因此需要通过某种方式进行加载DPDK。
  • 核关联/分配过程:EAL提供了将执行单元分配给特定核并创建执行实例的机制。
  • 预留系统内存:EAL便于预留不同的内存区域,例如用于设备交互的物理内存区域。
  • 抽象PCI地址:EAL提供了访问PCI地址空间的接口。
  • 跟踪和调试功能:日志、堆栈转储等。
  • 实用的功能:libc中所没有提供的自旋锁和原子计数器。
  • CPU功能识别:在运行时确定CPU是否支持特定功能,确定当前CPU是否支持编译产生的二进制指令集。
  • 中断处理:向特定中断源注册/注销回调的接口。
  • 时钟功能:用于设置/删除在特定时间运行的回调函数接口。


3.1Linux用户态执行环境中的EAL

    在Linux用户空间环境中,DPDK应用程序使用pthread库作为作为用户空间应用程序运行。有关设备和地址空间的PCI信息要通过内核接口和内核模块来获得(如uio_pci_generic或igb_uio)。请参阅Linux内核中的用户空间驱动程序文档。

    EAL在hugetlbfs(使用大页面可以提升性能)中使用mmap()来执行物理内存分配,这些内存对DPDK服务层是可见的,如Mempool库。

    此时,DPDK服务层将被初始化,之后通过调用pthread_setaffinity()为每个执行单元分配一个特定的逻辑内核,且执行单元作为用户级线程运行。

    时间参考通过CPU的时间戳计数器(TSC)或内核高精度定时器(HPET)API来获得。

3.1.1初始化与内核启动

    初始化的部分工作是由glibc的启动函数来完成的,在初始化时也会执行检查,以确保CPU能够支持配置文件中所选择的微架构类型。然后,main()函数被调用。内核的初始化和启动在rte_eal_init()中完成(参见API文档)。其主要由对pthread库的调用组成(更具体的来说,包括pthread_self(),pthread_create()和pthread_setaffinity_np())。

         图3.1 Linux应用环境中EAL的初始化

    注:对对象的初始化(如内存区、环、内存池、lpm表和hash表)应该作为主lcore上整体应用程序初始化的一部分来完成。这些对象的创建和初始化是非多线程安全的。但是,一旦初始化完成,这些对象就可以同时在多线程环境下安全的使用。

3.1.2多进程支持

    Linux应用中,EAL允许多进程和多线程的部署模型。详细信息,请参阅多进程支持章节。

3.1.3内存映射获取和内存预留

    使用hugetlbfs内核文件系统来完成大块连续物理内存的分配。EAL提供了在这块连续内存中预留内存区域并进行命名的API。这块命名的预留内存的物理地址会返回到给预留内存区API的调用者。

注:通过rte_malloc()这个API完成内存预留的返回也是通过hugetlbfs的页面完成。

3.1.4Xen Dom0不支持hugetlbs

    现有内存管理的实现基于Linux内核的大页面机制。但是,Xen Dom0不支持大页面,因此通过添加一个新的Linux内核模块rte_dom0_mm来解决这一限制。

    EAL通过IOCTL接口通知Linux内核模块rte_dom0_mm分配指定大小的内存,并从该模块中获取内存段的所有信息,此外,EAL使用MMAP接口来映射分配的内存。对于每一个内存段,其物理地址在内部都是连续的,但实际的硬件地址的连续限制在2MB。

3.1.5PCI访问

    EAL使用内核提供的/sys/bus/pci实用例程来获取PCI总线上的内容。为访问PCI内存,名为uio_pci_generic的内核模块提供了/dev/uioX设备文件和/sys中的资源文件,这些文件使得在从应用程序中可以获取对PCI地址空间的访问权限。DPDK的igb_uio模块也可用于此目的。这两种驱动程序都使用了UIO内核功能。

3.1.6逻辑内核与共享变量

    逻辑内核是指处理器的逻辑执行单元,有时称为硬件线程。

    共享变量是默认特性。使用为单个线程提供局部存储的线程局部存储(TLS)来实现每个逻辑内核的变量。

3.1.7日志

    EAL提供了记录日志的API。在Linux应用中,日志默认情况下会发送到syslog和控制台。但是,日志功能可以被重载,以实现不同的日志记录机制。在glibc中有一些用于转储堆栈的调试函数。而rte_panic()函数会自动引发SIG_ABORT信号,从而触发生成gdb可读的内核文件。

3.1.8CPU特性识别

    EAL能够在运行时通过使用rte_cpu_get_feature()函数来判断CPU的那些功能是可用的。

3.1.9用户空间的中断事件

在主线程中处理用户空间的中断和定时。

    EAL创建一个通过轮询UIO设备文件描述符来检测中断的主线程。针对于特定中断事件,可以通过EAL的函数进行注册和注销回调函数,并且回调函数在主线程中可以以异步方式进行调用。此外,EAL还允许以和NIC中断相同的方式使用定时回调。

RX中断事件

    PMD提供的接收和发送例程都不限于在线程轮询的模式下执行。为了减轻小吞吐量时的空闲轮询,在唤醒事件到来之前停止轮询。RX中断事件是这种情况下的首选唤醒事件,但这不是唯一的选择。

    EAL为事件驱动线程模式提供了事件API。以linuxAPP为例,用epoll()来实现。它的每个线程都可以监视一个epoll实例,且在实例中添加了所有唤醒事件的文件描述符。这些事件文件描述符依据UIO/VFIO规范来创建并映射到中断向量。在bsdapp中,kqueue是一种替代方法,但还尚未实现。

    EAL初始化事件文件描述符和中断向量之间的映射,而设备初始化中断向量和队列之间的映射。在这种情况下,EAL实际上并不清楚特定向量的中断原因,而后一种映射关系由eth_dev驱动程序负责。

    RX中断由ethdevAPI控制/启动/禁用,这些API均以‘rte_eth_dev_rx_intr_*’来命名。如果PMD还不支持这些函数的话,他们会返回失败。intr_conf.rxq标志用于打开每个设备的RX中断能力。

3.1.10黑名单

    EAL中PCI设备的黑名单功能可用于将某些NIC端口标记为黑名单,以使他们被DPDK忽略。使用PCIe描述方法(域:总线:设备功能)来识别被标记为黑名单的端口。


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值