首页 > 技术文章 > [dpdk] 读开发指南(2)(内容长期整理中)

hugetong 2016-11-04 11:00 原文

接续前节。

7 PMD (Poll Mode Driver)

  A Poll Mode Driver (PMD) consists of APIs, provided through the BSD driver running in user space, to configure the devices and their respective queues. In addition, a PMD accesses the RX and TX descriptors directly without any interrupts (with the exception of Link Status Change interrupts) to quickly receive, process and deliver packets in the user’s application.

  run-to-completion mode

  pip-line mode  使用 ring 在两个处理流程间共享数据。

  在处理逻辑里禁用异步中断处理;即使在需要使用异步机制的情况下,也要尽量使用rings。

  无锁,是多核心处理环境下的关键技术。PMD尽量维护单核心内的独立资源。

7.1 设计原理

  有点晦涩,看原文。略

  逻辑核,内存,收包队列应该才numa的同一个node上。无论是run-to-completion 还是 pip-line。

  多核不要共享收包队列。

7.2 设备命名与配置

  分为设备index和设备名称,两个识别标示,其中设备名称包含设备index,以便阅读友好。

7.3 配置接收与发送队列

  这一节没看懂,先酱,之后回看。

7.4 硬件计算校验和,分片,插入vlan头等功能。

7.5 API

8 Cryptography Device Library

9 IVSHMEM LIbrary

  IVSHMEM用于host与虚拟机共享内存空间。 这个库用来让跑在虚拟机里的dpdk认识qemu的IVSHMEM设备 。

  如何使用:

  1.  使用支持IVSHMEM的指定qemu版本。

  2.  设置编译选项,启用IVSHMEM。

  3.  为虚拟机设置大页。

10 Link bonding Poll Mode Driver Library

11 Timer Library

12 Hash Library

12.1 实现原理

  略

13 LPM Library

  路由决策机制??

14 LPM6 Library

15 Packet Distributor Library

  包分发,做工作流内的负载均衡。

16 Recorder Library

17  IP Fragmentation and Reassembly Library

18 The librte_pdump library

  这个库,会把包从收包队列里完整的拷贝只mempool,性能不好。主要用来debug。

19 Multi-process Support

  英特尔架构下的多逻辑进程协作。

  两种逻辑进程类型。主要逻辑进程:可以初始化共享内存,并具有所有权限。 次要逻辑进程:不能初始化共享内存,但是可以附着,并在其中创建对象。主要逻辑进程可以单独运行,次要逻辑进程必要跟主要逻辑进程一起运行。

  对称多逻辑进程协作方式。每一个逻辑进程处理相同内容。

  非对称逻辑进程协作。

19.1 使用DPDK运行多进程程序的限制

  禁用 linux 安全特性 ASLR(Address-space Layout Randomization)。

  任意两个实例,不能使用同一个逻辑核。

  中断处理响应只能在主要逻辑进程中。

  函数指针的共享,不能夸真实进程。

  只能挂载一个HPET。

20 Kernel NIC Interface

  该接口有DPDK程序,动态创建和删除。

21 Thread safety

22 Ouality of Service Framework

23 Power Management

24 Packet Classification and Access Control

25 Packet FrameWork

25.1 设计目标

  提供可扩展的包处理方法,真的复杂的包处理流程。

  对单元处理模块,提供可扩展可替换不同软件硬件实现的能力。

  在灵活性与性能间,达到完美平衡。

  提供一个在逻辑上类似OpenFlow的框架。(不知道此OpenFlow是否为彼OpenFlow)

25.2 具体

  A  首先,有两个概念,table,port。懒得解释,看图便很好理解。(我果然不适合写博客)

  采用多个hash表项的树状级联,用来确定包转发流程中的吓一跳。如图

  B  port类型与接口

  C  table类型与接口

25.3 Hash表的设计

  Mark 需要细读

25.4 Pipeline 设计

  Pipeline由一下四类对象组成:

    输入ports,输出ports,tables,actions

  The input ports are connected with the output ports through tree-like topologies of interconnected tables. The table entries contain the actions defining the operations to be executed on the input packets and the packet flow within the pipeline.

25.4.1  port与table直接的链接

  一般原则:

  一个input port链接一个table,不应该有未连接的input port。

  表到表或者表到output port之间的链接,是通过 next hop action。表连接是流状,运行时动态变化的。基于表之间不同的entry。每一个表有很多的entry,不同的entry链接不同的output port。一个表可以有很多entry链接另一个表,所以的这些entry必须指向同一个表,为了保护树状结构

25.4.2  port action handler

  在收包之后,或发包之前执行。可以disable。

25.4.3  table action handler

   table lookup完成之后,找到了相应的table entry之后,handler可以被执行。只能执行用户定义的action,next hop等保留action将有框架执行。但是可以丢弃包。

  保留action:Drop /  Send to output port / Send to table.

  用户action:每个表,每个entry,可以有不同的action。包括单不限于:statics /  appid / push pop label / nat / ttl

25.5 多核处理

  复杂的程序,一般会跨越多个CPU逻辑核心进行处理。可以使用SW ring 进行通信。其性能通常受限与表查询,action处理,硬件条件。

  一个应用场景的典型描述: Pipeline1 跑在 Core A上,Pipeline2 跑在 Core B上,P1与P2的通信使用SW queue。output port for P1 and input port for P2.

26 vHost Library

  虚拟机相关,略。

27 Port Hotplug Framework

  热插拔,略。

28 源码目录结构介绍。

29 编译系统介绍

  两个步骤:1,通过编译DPDK源码,获得DPDK的二进制库与头文件等。2. 编使用了dpdk的用户程序。

29.1  编库

  通过源码编译方式:可以通过一份源码编译生成多份基于不同配置的目标文件目录。

  步骤如下:my_sdk_build_dir 为自定义的目录。

cd ${RTE_SDK}
make config T=x86_64-native-linuxapp-gcc O=my_sdk_build_dir

cd my_sdk_build_dir
make
或
make O=my_sdk_build_dir

 

29.2 编程序

  设环境变量:

export RTE_SDK=/opt/DPDK
export RTE_TARGET=x86_64-native-linuxapp-gcc
cd /path/to/my_app

  写makefile。。。

30. (Things about Make)

31  扩展dpdk

32 building your own application

32.1  把example下边的helloword目录cp出来,作为一个开始。

33  (Things about Makefile)

34  性能优化guideline

35  写出高效的代码

  For additional and more general information, please refer to the Intel® 64 and IA-32 Architectures Optimization Reference Manual which is a valuable reference to writing efficient code.

35.1 Memory

  A. 不要使用libc。 (这么嚣张。。。)

  B. 别用malloc-like函数,就是别动态分配内存。(在数据面,就是数据相关的进程?!) 一定要用,就用固定长度的内存池,librte_mempool.

  C  concurrent access the same memory area

    大概明白,不懂原理。

  D  NUMA

  E  分布式利用内存channel。

35.2 逻辑核通信

  尽量使用dpdk 无锁ring。支持 bulk 和 burst 访问方式。使用bulk对性能有很大的提升。

35.3 PMD 驱动

  同样支持 bulk和burst 方式,

  当PCI设备通过DMA写入系统内存时,按cache line大小写入,效率更高。

35.3.1 高吞吐与低延迟的平衡

  等包缓冲队列饱和之后一次处理,可以得到高吞吐能力。当时同时,第一个入队的包需等待整个队列满了之后才能处理,自然造成了该包的高延迟。

35.4 锁与原子操作

  原子操作隐含了一个锁,在原子操作开始之前。

  在数据面避免锁机制,是改善处理性能的好方法。比如通过 per-lcore variables进行避免。以及通过RCU(Read-Copy-Update)算法来替换频繁的读写锁。

35.5 编码优化

  内联函数: 不一定会生效,更多的依赖编译器的行为。

  分支预测:icc/gcc 函数 likely() unlikely() (不太懂,不太会用)

35.6 设置CPU类型

  编译器会做针对运行CPU环境所特有的优化。可以设置DPDK参数 CONFIG_RTE_MACHINE

36 性能优化

  (待细研究

-------------------------------------------------------------------------------------------------------------------------------------------------

过了一遍,内容太丰富了,而且很多底层细节。所以略过了很多,也有很多没有看懂的地方。

目前只是有了一个大框架上的人,很多细节还有反复的回来多次阅读,同时也会慢慢的丰富这篇笔记博文。

下一步学习内容包括:

1. 代码中附带的例子,及说明文档《Simple Applications User Guide》 同时实操开始写一部分代码。

2. Intel 官方教程

3. API

 

推荐阅读