精华内容
下载资源
问答
  • DPDK

    2017-10-18 19:03:20
    DPDK

    环境

    1. Ubuntu-16.04 LTS
    2. dpdk-16.11.3.tar.xz (LTS), from DPDK
    3. pktgen-3.4.2.tar

    安装DPDK和Pktgen

    1. tar -xf *.tar to extract the files

    2. Set the environment variable:

      export RTE_SDK=” (dpdk files directory, 参阅其他安装说明)
      export RTE_TARGET=” (the setting of the installation)
      edit the ~/.profile, reboot and make it enable(永久生效)

    3. Install the DPDK

      run the ./tools/dpdk-setup.sh
      then, step 1-4:

      1. install the DPDK environment(‘x86_64-native-linuxapp-gcc’)
      2. setup linuxapp environment(drivers, e.g. IGB UIO; hugepage bind the network devices )
      3. test
      4. Install the pktgen
    4. Download Pktgen and Install
      直接通过github指示或者官网下载pktgen解压安装即可,该过程中可能存在的问题:
      First, use ‘sudo apt-get install libpcap-dev’ to install pcap library( the pktgen used).
      Second, use the tools/setup.sh to test if the environment is OK
      Finally, make the pktgen

    测试环境

    可以使用DPDK自带的一些examples来测试,这些examples的使用方法直接参考DPDK文档即可.

    1. l2fwd
      Iocation: dpdk-…/examples/l2fwd/build/ (Before using, please ‘make’)
      ./l2fwd -c 0xf -n 3 – -p 0x3 -q 1
      前面的参数称为EAL,属于DPDK通用初始化参数(参看help,编程时通过rte_eal_init(argc, argv)直接完成)
      -c 0xf 运行的十六机制掩码核心数。在这里指分配4个core
      -n 3 每个处理器的内存通道数
      – 表示之后的为次参数(每个程序可以进行自定义,使用Linux的getopt_long()进行自定义处理);
      -p 0x3 设置起点的端口数对应掩码,0x3=0b11,即起点两个端口
      -q 确定每个core的队列的数量,表示每个逻辑核心有一个队列

    2. pktgen
      location: pktgen home directory ( Before using, ‘make’)
      ./app/build/pktgen -c e -n 3 –proc-type auto –file-prefix pg – -p 0x14 -P -m “2.0, 3.1” -f test/set_seq.cmd
      Similar to the l2fwd, for more information, look at the help
      [查看文档时通过 Shift+PgDn/PgUp 上下翻页].

    3. 程序运行中的其他事情
      If the warning is the hugepage, try:
      3.1 原程序前加sudo -E
      3.2 尝试运行下面命令后再运行程序(delete the too many pages)

      sudo rm -rf /dev/hugepages/*


    Pktgen Usage

    Start Usage

    sudo -E ./app/build/pktgen [EAL options] – [-h] [-P] [-G] [-T] [-f cmd_file] [-l log_file] [-s P:PCAP_file] [-m ]

    使用-f cmd_file进行定制化配置(配置在文件里,也可以在启动后pcktgen的命令行里进行相关设置操作–设置报文的内容,速率,存储等)
    TODO:
    [ ] 尝试使用-f 的方法进行配置并总结, 搭配出自定义的网络测试环境(在不同的报文构成下, size,burst等; 速率和丢包率–pktgen保存对应结果)

    启动后的命令行操作

    可以使用的命令:
    help, ls (-l)… 各种命令的使用说明参看4
    切换页面page < page name >

    cpu:查看CPU
    log: 查看log
    main: 主页
    range: 查看range的相关设置

    命令举例如下为:
    str/stp: 全部端口开始/停止发包;
    start/stop port-number: 开始/停止某些端口的发包
    clr: 全部清零;
    clear port-number: 清除某个端口的相关统计信息

    set < port list > < type > value: 把端口列表进行配置
    比较重要的一些配置方案有
    1. set 0 count 10 //0端口发送10个报文就结束
    2. set all size 100 //所有端口发送的报文内容大小为100
    3. set 0,1 rate 70 //端口0,1的速率设置为70%
    4. set 1 burst 100 // 1端口的burst为100
    5. set 1 dump 100 // 记录之后收到的100个报文到?log?(还没搞清楚)
    注意使用range 设置相关随机设置前,需要使用enable < portlist > range操作打开相关选项
    注意set,range,sequence的使用,可以配置速率,IP,MAC等信息
    参考文档: https://media.readthedocs.org/pdf/pktgen-dpdk/latest/pktgen-dpdk.pdf

    使用DPDK做自定义开发

    Environment

    为了方便查看函数调用,使用Eclipse CDT进行编辑, 拷贝DPDK的example文件夹下的makefile类工程, 同时增加DPDK的include文件夹到工程的include目录内(这样可以方便地查看DPDK自定义的函数在头文件里的说明–等价于查看文档)

    rte_eal_init(argc, argv); 初始化操作,返回值<0表示出错
    rte_exit(EXIT_FAILURE, “Port %d RX queue setup error (%d)\n”, port_rx, ret);退出操作,可以提示错误信息(注意后面的字符串的使用)
    rte_

    Reference

    1. http://blog.csdn.net/linzhaolover/article/details/9290083
      About the Pktgen
    2. http://blog.csdn.net/weicuidi/article/details/52925527
      About the l2fwd
    3. https://github.com/pktgen/Pktgen-DPDK/issues/4
      About the pcap.h question
    4. http://pktgen-dpdk.readthedocs.io/en/latest/commands.html
      About the pktgen usage
    展开全文
  • dpdk

    2020-05-25 20:21:42
    https://blog.csdn.net/rocson001/article/details/72967473/
    展开全文
  • DPDKDPDK APP 的指令行参数

    万次阅读 2020-05-12 14:58:45
    文章目录目录DPDK APP 的指令行参数Lcore-related options(逻辑线程相关参数)Device-related options(设备相关参数)Multiprocessing-related options(多进程相关参数)Memory-related options(存储相关参数)...

    目录

    Lcore-related options(逻辑线程相关参数)

    • -c <coremask>:选项参数可以使用指定的 lcore 来运行 DPDK 应用程序,是一个十六进制的掩码,掩码的每个位对应于 Linux 提供的 lcore ID。例如:-c 3,3 的十六进制为 0x03、二进制为 11,假设有 8 个 Core,那么二进制 00000011,从右到左依次代表核 0-7,使用 0、1 号核。

    • --lcores <lcores[@cpus]>[<,lcores[@cpus]>...]:EAL Thread 的 CPU 亲和性。

    --lcores='(0,4,5)@2,1@3,2@4,3@5'
    
    # lcores 0,4,5 绑定在 CPU2
    # lcore 1 绑定在 CPU3
    # lcore 2 绑定在 CPU4
    # lcore 3 绑定在 CPU5
    
    • -l <core list>
    • --master-lcore <core ID>:Master Core 的 CPU 亲和性。
    • -s <service core mask>:Slave Core 的 CPU 亲和性。

    在指定 lcpu mask 参数之前,需要了解平台的 CPU 布局,可以通过 hwloc 来查看:

    yum install hwloc -y
    

    在这里插入图片描述
    如果没有图形化界面则使用指令:

    $ lstopo-no-graphics
    Machine (9835MB)
      Package L#0 + L3 L#0 (16MB) + L2 L#0 (4096KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
      Package L#1 + L3 L#1 (16MB) + L2 L#1 (4096KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#1)
      Package L#2 + L3 L#2 (16MB) + L2 L#2 (4096KB) + L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2 + PU L#2 (P#2)
      Package L#3 + L3 L#3 (16MB) + L2 L#3 (4096KB) + L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3 + PU L#3 (P#3)
      Package L#4 + L3 L#4 (16MB) + L2 L#4 (4096KB) + L1d L#4 (32KB) + L1i L#4 (32KB) + Core L#4 + PU L#4 (P#4)
      Package L#5 + L3 L#5 (16MB) + L2 L#5 (4096KB) + L1d L#5 (32KB) + L1i L#5 (32KB) + Core L#5 + PU L#5 (P#5)
      Misc(MemoryModule)
      HostBridge L#0
        PCI 8086:7010
        PCI 1013:00b8
        PCI 1af4:1000
        PCI 1af4:1001
        3 x { PCI 15b3:1018 }
    

    也可以使用 DPDK 自带的 CPU layout 工具:

    $ cd ${RTE_SDK}/usertools/
    
    $ ./cpu_layout.py
    ======================================================================
    Core and Socket Information (as reported by '/sys/devices/system/cpu')
    ======================================================================
    
    cores =  [0]
    sockets =  [0, 1, 2, 3, 4, 5]
    
           Socket 0    Socket 1    Socket 2    Socket 3    Socket 4    Socket 5
           --------    --------    --------    --------    --------    --------
    Core 0 [0]         [1]         [2]         [3]         [4]         [5]
    

    Device-related options(设备相关参数)

    • -b, --pci-blacklist <[domain:]bus:devid.func>:PCI 设备黑名单,避免 EAL 使用指定的 PCI 设备。可以使用多次。
    • -w, --pci-whitelist <[domain:]bus:devid.func>:PCI 设备白名单,可以使用多次。
    • --use-device [domain:]bus:devid.func:仅使用指定的以太网设备。使用逗号分隔,不能与 -b 选项一起使用。

    注:黑白名单是互斥的。

    • --vdev <driver><id>[,key=val, ...]:添加一个虚拟设备,e.g. --vdev 'net_pcap0,rx_pcap=input.pcap,tx_pcap=output.pcap'
    • –vfio-intr <legacy|msi|msix>:为绑定到 VFIO 内核驱动的设备指定中断模式(如果不支持 VFIO,则配置无效)。
    • –create-uio-dev:为设备创建 /dev/uioX 文件并绑定指定的 igb_uio 内核驱动。
    • -d <path to shared object or directory>:加载额外驱动,参数可以是一个驱动文件或是包含了多个驱动文件的文件夹。可以使用多次。
    • –no-hpet:禁止使用 HPET 定时器。
    • –no-pci:禁止 PCI 总线。
    • –vmware-tsc-map:使用 VMware TSC 映射而不是本地 RDTSC。

    Multiprocessing-related options(多进程相关参数)

    • --file-prefix <prefix name>:用于 hugepage 文件名的前缀文本,为每个 DPDK App 设置一个不同的共享文件前缀,以及配置目录(默认为:/var/run/dpdk/rte/config)。使用多个不同的前缀文件允许运行多个独立的 DPDK 进程组。DPDK 支持多进程协同完成工作,多进程使用相同的共享文件组成进程组(进程组里的进程分为 primary 和 secondary)。e.g.
    # --file-prefix=vhost-1
    /dev/hugepages/vhost-1map_12
    /dev/hugepages/vhost-1map_11
    /dev/hugepages/vhost-1map_10
    
    • --proc-type <primary|secondary|auto>:设置当前的进程类型。
    • --base-virtaddr <address>:指定基本虚拟地址。DPDK 的 primary 进程尝试使用一个不同的内存映射开始地址。对于因为地址映射冲突而不能启动的 secondary 进程非常有用。

    当我们使用 --file-prefix 可以在响应的路径中找到内存的内置文件 config、hugepage 的信息文件,以及对于 dpdk-pdump 而言非常重要的 server-socket-file mp_socket。dpdk-pdump 通过 mp_socket 来向 DPDK app 发送抓包的请求。反之,如果 dpdk-pdump 找到不这个文件则无法抓包。

    $ ll /var/run/dpdk/vhost-1/
    总用量 228
    -rw-r----- 1 root root  11396 6月   8 23:22 config
    -rw------- 1 root root   4096 6月   8 23:22 fbarray_memseg-1048576k-0-0
    -rw------- 1 root root   4096 6月   8 23:22 fbarray_memseg-1048576k-0-1
    -rw------- 1 root root   4096 6月   8 23:22 fbarray_memseg-1048576k-0-2
    -rw------- 1 root root   4096 6月   8 23:22 fbarray_memseg-1048576k-0-3
    -rw------- 1 root root 188416 6月   8 23:22 fbarray_memzone
    -rw-r--r-- 1 root root  12432 6月   8 23:22 hugepage_info
    srwxr-xr-x 1 root root      0 6月   8 23:22 mp_socket
    

    Memory-related options(存储相关参数)

    • --socket-mem <amounts of memory per socket>:从特定的处理器 Socket 上的 hugepage 分配内存,参数用逗号分隔列表值。建议使用。
    # 在 Socket 0 上预分配1024M,在 Socket 1 上分配 2048M。
    --socket-mem 1024,2048
    
    • --socket-limit <amounts of memory per socket>:设置每个 Socket 的内存上限(仅仅是非传统存储模式),0 代表关闭限制。

    • --huge-dir <path to hugetlbfs directory>:使用指定的 hugetlbfs 目录,而不是自动检测的。hugetlbfs 是大页使用目录。e.g. --huge-dir /dev/hugepages

    • -n <number of channels>:设置每个 Socket 的内存通道数。

    • -r <number of ranks>:设置内存 Ranks 数,默认为自动检测。

    • -m <megabytes>:从 hugepage 分配内存,不考虑处理器 Socket。不建议使用。

    • –single-file-segments:在 hugetlbfs 中创建少量的文件(仅仅是非传统存储模式)。

    • –huge-unlink:创建大页文件后 Unlink (暗指不支持多进程)。

    • –match-allocations:释放 hugepages 回到系统完全像他们最初分配前一样。

    • –in-memory:不要创建任何共享数据结构,完全运行在存储中。暗指 --no-shconf 和 --huge-unlink。

    • –iova-mode <pa|va>:强制设置 IOVA 模式为指定值。

    • –no-shconf:不创建共享文件。暗指不支持多进程。

    • –no-huge:使用匿名存储而不是大页。暗指不支持多进程。

    • –legacy-mem:使用传统 DPDK 存储分配模式。

    Debugging options

    • --log-level <type:val>:为一个特定的组件指定日志级别,e.g. --log-level eal:8,可以使用多次。
    • --syslog <syslog facility>:设置日志设备,有效的日志设备如下:
      • auth
      • cron
      • daemon
      • ftp
      • kern
      • lpr
      • mail
      • news
      • syslog
      • user
      • uucp
      • local0
      • local1
      • local2
      • local3
      • local4
      • local5
      • local6
      • local7

    指定 DPDK App 使用的大页内存

    建议使用 --socket-mem 选项指定 DPDK App 使用的大页内存与预留的 hugepage 内存一致。例如:–socket-mem=0,512 指定在 Socket0(一般就是 NUMA0)上预留 512MB 内存(从 Socket1 上预留的大页内存中分配)。

    如果没有指定,则由 DPDK App 在启动时自动完成确定。如果指定的内存大小超出了预留值,则 DPDK App 启动失败。如果指定的内存大小小于预留值,也可能会导致 DPDK App 启动失败,尤其是在使用 -m(不建议使用)选项的时候,这里需要注意。

    隔离 DPDK App 使用 lcore

    虽然 DPDK App 已经是绑定核心的,但 Linux 调度程序仍然会使用这些 lcore 来运行其他的任务,所以为了防止在这些核上运行额外的工作负载,可以使用 isolcpus Linux 内核参数来将其与通用的 Linux 调度程序隔离开来。

    isolcpus=2,4,6
    

    使用基于 Intel VT-d 的 Linux IOMMU Pass-Through 来运行 DPDK App

    要在 Linux 内核中启用 Intel VT-d 硬件辅助的 IO 技术,必须配置一系列内核选项,包括:

    • IOMMU_SUPPORT
    • IOMMU_API
    • INTEL_IOMMU

    要使用 Intel VT-d 来运行 DPDK App,在使用 igb_uio 驱动时,Grub 参数必须携带 iommu=pt 参数。 这使得主机可以直接通过 DMA 重映射查找网卡的存储空间。另外,如果内核中没有设置 INTEL_IOMMU_DEFAULT_ON 参数,那么还必须要使用到 intel_iommu=on 参数。这可以确保 Intel IOMMU 被正确初始化。而在使用 vfio-pci 驱动程序时,则直接同时使用 iommu=pt intel_iommu=on

    展开全文
  • DPDK技术介绍

    万次阅读 2020-11-27 16:43:10
    1. DPDK技术介绍 1) 简介 DPDK全称Intel Data Plane Development Kit,是intel提供的数据平面开发工具集,为Intel architecture(IA)处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持。通俗地说,...

    1. DPDK技术介绍

    1) 简介

    DPDK全称Intel Data Plane Development Kit,是intel提供的数据平面开发工具集,为Intel architecture(IA)处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持。通俗地说,就是一个用来进行包数据处理加速的软件库。

    DPDK不同于Linux系统以通用性设计为目的,而是专注于网络应用中数据包的高性能处理。具体体现在DPDK应用程序是运行在用户空间上利用自身提供的数据平面库来收发数据包,绕过了Linux内核协议栈对数据包处理过程。它不是一个用户可以直接建立应用程序的完整产品,不包含需要与控制层(包括内核和协议堆栈)进行交互的工具。

    相比原生 Linux(Native Linux),采用Intel DPDK技术后能够大幅提升IPV4的转发性能,可以让用户在迁移包处理应用时(从基于NPU的硬件迁移到基于Intel x86的平台上),获得更好的成本和性能优势。同时可以采用统一的平台部署不同的服务,如应用处理,控制处理和包处理服务。

    2) 技术优点

     通过UIO技术将报文拷贝到应用空间处理,规避不必要的内存拷贝和系统调用,便于快速迭代优化。

     通过大页内存HUGEPAGE,降低cache miss(访存开销),利用内存多通道交错访问提高内存访问有效带宽,即提高命中率,进而提高cpu访问速度。

     通过CPU亲和性,绑定网卡和线程到固定的core,减少cpu任务切换。特定任务可以被指定只在某个核上工作,避免线程在不同核间频繁切换,保证更多的cache命中。

     通过无锁队列,减少资源竞争。cache行对齐,预取数据,多元数据批量操作。

     通过轮询可在包处理时避免中断上下文切换的开销。

    3) DPDK、网卡、用户应用程序、内核之间的关系

     PMD:Pool Mode Driver,轮询模式驱动,通过非中断,以及数据帧进出应用缓冲区内存的零拷贝机制,提高发送/接受数据帧的效率。

     流分类:Flow Classification,为N元组匹配和LPM(最长前缀匹配)提供优化的查找算法。

     环队列:Ring Queue,针对单个或多个数据包生产者、单个数据包消费者的出入队列提供无锁机制,有效减少系统开销。

     MBUF缓冲区管理:分配内存创建缓冲区,并通过建立MBUF对象,封装实际数据帧,供应用程序使用。

     EAL:Environment Abstract Layer,环境抽象(适配)层,PMD初始化、CPU内核和DPDK线程配置/绑定、设置HugePage大页内存等系统初始化。

    2. 源程序包组成1) Makefile &&CONFIG

    MakeFile文件主要位于位于 $(RTE_SDK)/mk 中。此处留在后面第5节进行讨论

    配置模板位于 $(RTE_SDK)/config。这些模板描述了为每个目标启用的选项。 配置文件许多可以为DPDK库启用或禁用的选项,包括调试选项。用户应该查看配置文件并熟悉这些选项。配置文件同样也用于创建头文件,创建的头文件将位于新生成的目录中。一般可以根据用户编译的编译器和操作系统来直接选择配置项。

    2) Lib库

    库文件源码位于目录$(RTE_SDK)/lib中。按照惯例,库指的是为应用程序提供API的任何代码。通常,它会生成一个(.a)文件,这个目录中可能也保存一些内核模块。

    Lib常用库文件包含以下内容

    lib

    +-- librte_cmdline # 命令行接口

    +-- librte_distributor # 报文分发器

    +-- librte_eal # 环境抽象层

    +-- librte_ether # PMD通用接口

    +-- librte_hash # 哈希库

    +-- librte_ip_frag # IP分片库

    +-- librte_kni # 内核NIC接口

    +-- librte_kvargs # 参数解析库

    +-- librte_lpm # 最长前缀匹配库

    +-- librte_mbuf # 报文及控制缓冲区操作库

    +-- librte_mempool # 内存池管理器

    +-- librte_meter # QoS metering 库

    +-- librte_net # IP相关的一些头部

    +-- librte_power # 电源管理库

    +-- librte_ring # 软件无锁环形缓冲区

    +-- librte_sched # QoS调度器和丢包器库

    +-- librte_timer # 定时器库

    3) 应用程序

    应用程序是包含 main() 函数的源文件。 他们位于 $(RTE_SDK)/app 和 $(RTE_SDK)/examples 目录中。

    常用示例文件:

    examples

    +-- cmdline # Example of using the cmdline library

    +-- exception_path # Sending packets to and from Linux TAP device

    +-- helloworld # Basic Hello World example

    +-- ip_reassembly # Example showing IP reassembly

    +-- ip_fragmentation # Example showing IPv4 fragmentation

    +-- ipv4_multicast # Example showing IPv4 multicast

    +-- kni # Kernel NIC Interface (KNI) example

    +-- l2fwd # L2 forwarding with and without SR-IOV

    +-- l3fwd # L3 forwarding example

    +-- l3fwd-power # L3 forwarding example with power management

    +-- l3fwd-vf # L3 forwarding example with SR-IOV

    +-- link_status_interrupt # Link status change interrupt example

    +-- load_balancer # Load balancing across multiple cores/sockets

    +-- multi_process # Example apps using multiple DPDK processes

    +-- qos_meter # QoS metering example

    +-- qos_sched # QoS scheduler and dropper example

    +-- timer # Example of using librte_timer library

    +-- vmdq_dcb # Example of VMDQ and DCB receiving

    +-- vmdq # Example of VMDQ receiving

    +-- vhost # Example of userspace vhost and switch

    3. DPDK架构分析

     

    4. Dpdk基础库介绍

    1) EAL 环境适配层

    环境抽象层为底层资源如硬件和内存空间的访问提供了接口。 这些通用的接口为APP和库隐藏了不同环境的特殊性。 EAL负责初始化及分配资源(内存、PCI设备、定时器、控制台等等)。

    典型函数:rte_eal_init

    抄自dpdk网站:

    EAL提供的典型服务有:

    • DPDK的加载和启动:DPDK和指定的程序链接成一个独立的进程,并以某种方式加载

    • CPU亲和性和分配处理:DPDK提供机制将执行单元绑定到特定的核上,就像创建一个执行程序一样。

    • 系统内存分配:EAL实现了不同区域内存的分配,例如为设备接口提供了物理内存。

    • PCI地址抽象:EAL提供了对PCI地址空间的访问接口

    • 跟踪调试功能:日志信息,堆栈打印、异常挂起等等。

    • 公用功能:提供了标准libc不提供的自旋锁、原子计数器等。

    • CPU特征辨识:用于决定CPU运行时的一些特殊功能,决定当前CPU支持的特性,以便编译对应的二进制文件。

    • 中断处理:提供接口用于向中断注册/解注册回掉函数。

    • 告警功能:提供接口用于设置/取消指定时间环境下运行的毁掉函数。

    2) Ring 库

    环形缓冲区支持队列管理。rte_ring并不是具有无限大小的链表,它具有如下属性:

    先进先出(FIFO)

    最大大小固定,指针存储在表中

    无锁实现

    多消费者或单消费者出队操作

    多生产者或单生产者入队操作

    批量出队 - 如果成功,将指定数量的元素出队,否则什么也不做

    批量入队 - 如果成功,将指定数量的元素入队,否则什么也不做

    突发出队 - 如果指定的数目出队失败,则将最大可用数目对象出队

    突发入队 - 如果指定的数目入队失败,则将最大可入队数目对象入队

    单生产者入队:

     

    单消费者出队

     

    3) Mempool 库

    DPDK提供了内存池机制,使得内存的管理的使用更加简单安全。在设计大的数据结构时,都可以使用mempool分配内存,同时,mempool也提供了内存的获取和释放等操作接口。对于数据包mempool甚至提供了更加详细的接口-rte_pktmbuf_pool_create()

     mempool的创建

    内存池的创建使用的接口是rte_mempool_create()。在仔细分析代码之前,先说明一下mempool的设计思路:在DPDK中,总体来说,mempool的组织是通过3个部分实现的

     mempool头结构。mempool由名字区分,挂接在struct rte_tailq_elem rte_mempool_tailq全局队列中,可以根据mempool的名字进行查找,使用rte_mempool_lookup()接口即可。这只是个mempool的指示结构,mempool分配的内存区并不在这里面,只是通过物理和虚拟地址指向实际的内存地址。

     mempool的实际空间。这就是通过内存分配出来的地址连续的空间,用来存储mempool的obj对象。主要利用rte_mempool_populate_default()进行创建

     ring队列。其作用就是存放mempool中的对象指针,提供了方便存取使用mempool的空间的办法。

     mempool的常见使用是获取元素空间和释放空间。

     rte_mempool_get可以获得池中的元素,其实就是从ring取出可用元素的地址。

     rte_mempool_put可以释放元素到池中。

     rte_mempool_in_use_count查看池中已经使用的元素个数

     rte_mempool_avail_count 查看池中可以使用的元素个数

    4) 定时器库

    定时器库为DPDK执行单元提供定时器服务,使得执行单元可以为异步操作执行回调函数。定时器库的特性如下:

    定时器可以周期执行,也可以执行一次。

    need-to-insert-img

    定时器可以在一个核心加载并在另一个核心执行。但是必须在调用rte_timer_reset()中指定它。

    定时器提供高精度(取决于检查本地核心的定时器到期的rte_timer_manage()的调用频率)。

    如果应用程序不需要,可以在编译时禁用定时器,并且程序中不调用rte_timer_manage()来提高性能。

    具体使用参考:http://blog.csdn.net/linzhaolover/article/details/9410529

    5. 库的编译(Makefile)及使用(API使用方案)

    need-to-insert-img

    makefile位于目录: /examples/xxx/Makefile。 文件中真正必须的为两个变量APP和SRCS-y,前者为示例程序编译生成的目标文件名称,后者为要编译的源文件。

    另外两个必须的为makefile文件rte.vars.mk和rte.extapp.mk。前者定义一些全局的编译打包链接用到的选项,如CFLAGS、ASFLAGS、LDFLAGS等变量,头文件位置和库路径等和体系架构相关编译选项。后者rte.extapp.mk内部又包含了重要的mk/rte.app.mk文件,首先变量LDLIBS初始化为DPDK核心编译生成的所有静态库文件。

    makefile编写

    在DPDK中,Makefiles的套路是

    1.在文件开头,包含$(RTE_SDK)/mk/rte.vars.mk

    2.设置RTE构建系统的变量,比如设置RTE_SDK和RTE_TARGET环境变量

    3.包含指定的 $(RTE_SDK)/mk/rte.XYZ.mk,其中XYZ 可以填写app, lib, extapp, extlib, obj,依赖构建的目标类型.

    3.1 应用程序类型(application)

    - rte.app.mk

    - rte.extapp.mk

    - rte.hostapp.mk

    3.2 库类型 (library)

    - rte.lib.mk

    - rte.extlib.mk

    - rte.hostlib.mk

    3.3 安装类型(install)

    rte.install.mk

    没有生成任何文件,仅仅用于创建链接和将文件拷贝到安装目录.

    3.4 内核模块(Kernel Module )

    rte.module.mk

    用于构建内核模块,在dpdk开发包框架中.

    3.5 Objects类型

    - rte.obj.mk

    - rte.extobj.mk

    3.6 Misc类型

    - rte.doc.mk

    - rte.gnuconfigure.mk

    - rte.subdir.mk

    4.包含用户自定义的规则和变量

    常用的变量

    系统构建变量

    RTE_SDK

    RTE_TARGET

    编译变量(库文件,库目录,C编译标志,C++编译标志)

    CFLAGS: C编译标志. 使用 += 为变量添加内容

    LDFLAGS: 链接标志

    need-to-insert-img

    CPPFLAGS: C++编译标志. 使用 += 为变量添加内容

    LDLIBS: 待添加的库文件的列表

    SRC-y: 源文件列表

    警告变量

    WERROR_CFLAGS:在dpdk示例makefile中是加上此标志的.

    CFLAGS += $(WERROR_CFLAGS)

    6. 性能优化1) 内存

     内存拷贝:不要在数据面程序中使用libc

    通过Linux应用程序环境,DPDK中可以使用许多libc函数。 这可以简化应用程序的移植和控制平面的开发。 但是,这些功能中有许多不是为了性能而设计的。 诸如memcpy() 或 strcpy() 之类的函数不应该在数据平面中使用。 要复制小型结构体,首选方法是编译器可以优化一个更简单的技术。

    对于经常调用的特定函数,提供一个自制的优化函数也是一个好主意,该函数应声明为静态内联。DPDK API提供了一个优化的rte_memcpy() 函数。

     内存申请

    need-to-insert-img

    libc的其他功能,如malloc(),提供了一种灵活的方式来分配和释放内存。 在某些情况下,使用动态分配是必要的,但是建议不要在数据层面使用类似malloc的函数,因为管理碎片堆可能代价高昂,并且分配器可能无法针对并行分配进行优化。

    如果您确实需要在数据平面中进行动态分配,最好使用固定大小对象的内存池。 这个API由librte_mempool提供。 这个数据结构提供了一些提高性能的服务,比如对象的内存对齐,对对象的无锁访问,NUMA感知,批量get/put和percore缓存。 rte_malloc() 函数对mempools使用类似的概念。

     内存区域的并发访问

    need-to-insert-img

    几个lcore对同一个内存区域进行的读写(RW)访问操作可能会产生大量的数据高速缓存未命中,这代价非常昂贵。 通常可以使用per-lcore变量来解决这类问题。例如,在统计的情况下。 至少有两个解决方案:

    使用 RTE_PER_LCORE 变量。注意,在这种情况下,处于lcore x的数据在lcore y上是无效的。

    使用一个表结构(每个lcore一个)。在这种情况下,每个结构都必须缓存对齐。

    如果在同一缓存行中没有RW变量,那么读取主要变量可以在不损失性能的情况下在内核之间共享。

     NUMA

    need-to-insert-img

    在NUMA系统上,由于远程内存访问速度较慢,所以最好访问本地内存。 在DPDK中,memzone,ring,rte_malloc和mempool API提供了在特定内存槽上创建内存池的方法。

    有时候,复制数据以优化速度可能是一个好主意。 对于经常访问的大多数读取变量,将它们保存在一个socket中应该不成问题,因为数据将存在于缓存中。

     跨存储器通道分配

    need-to-insert-img

    现代内存控制器具有许多内存通道,可以支持并行数据读写操作。 根据内存控制器及其配置,通道数量和内存在通道中的分布方式会有所不同。 每个通道都有带宽限制,这意味着如果所有的存储器访问都在同一通道上完成,则存在潜在的性能瓶颈。

    默认情况下, Mempool Library 分配对象在内存通道中的地址。

    2) lcore之间的通信

    need-to-insert-img

    为了在内核之间提供基于消息的通信,建议使用提供无锁环实现的DPDK ring API。

    该环支持批量访问和突发访问,这意味着只需要一次昂贵的原子操作即可从环中读取多个元素(请参阅 Ring 库 )。

    使用批量访问操作时,性能会大大提高。

    出队消息的代码算法可能类似于以下内容:

    #define MAX_BULK 32

    while (1) {

    /* Process as many elements as can be dequeued. */

    count = rte_ring_dequeue_burst(ring, obj_table, MAX_BULK, NULL);

    if (unlikely(count == 0))

    continue;

    my_process_bulk(obj_table, count);

    }

    3) PMD 驱动

    DPDK轮询模式驱动程序(PMD)也能够在批量/突发模式下工作,允许在发送或接收功能中对每个呼叫的一些代码进行分解。

    避免部分写入。 当PCI设备通过DMA写入系统存储器时,如果写入操作位于完全缓存行而不是部分写入操作,则其花费较少。 在PMD代码中,已采取了尽可能避免部分写入的措施。

     低报文延迟

    need-to-insert-img

    传统上,吞吐量和延迟之间有一个折衷。 可以调整应用程序以实现高吞吐量,但平均数据包的端到端延迟通常会因此而增加。 类似地,可以将应用程序调整为平均具有低端到端延迟,但代价是较低的吞吐量。

    为了实现更高的吞吐量,DPDK尝试通过突发处理数据包来合并单独处理每个数据包的成本。

    以testpmd应用程序为例,突发大小可以在命令行上设置为16(也是默认值)。 这允许应用程序一次从PMD请求16个数据包。 然后,testpmd应用程序立即尝试传输所有接收到的数据包,在这种情况下是全部16个数据包。

    在网络端口的相应的TX队列上更新尾指针之前,不发送分组。 当调整高吞吐量时,这种行为是可取的,因为对RX和TX队列的尾指针更新的成本可以分布在16个分组上, 有效地隐藏了写入PCIe 设备的相对较慢的MMIO成本。 但是,当调优为低延迟时,这不是很理想,因为接收到的第一个数据包也必须等待另外15个数据包才能被接收。 直到其他15个数据包也被处理完毕才能被发送,因为直到TX尾指针被更新,NIC才知道要发送数据包,直到所有的16个数据包都被处理完毕才被发送。

    为了始终如一地实现低延迟,即使在系统负载较重的情况下,应用程序开发人员也应避免处理数据包。 testpmd应用程序可以从命令行配置使用突发值1。 这将允许一次处理单个数据包,提供较低的延迟,但是增加了较低吞吐量的成本。

    4) 锁和原子操作

    need-to-insert-img

    原子操作意味着在指令之前有一个锁定前缀,导致处理器的LOCK#信号在执行下一条指令时被断言。 这对多核环境中的性能有很大的影响。

    可以通过避免数据平面中的锁定机制来提高性能。 它通常可以被其他解决方案所取代,比如percore变量。 而且,一些锁定技术比其他锁定技术更有效率。 例如,Read-Copy-Update(RCU)算法可以经常替换简单的rwlock

    7. 遇到的问题及解决方法

    https://www.xuebuyuan.com/1149388.html

    https://blog.csdn.net/hz5034/article/details/78811445



    作者:Aubrey_de6c
    链接:https://www.jianshu.com/p/86af81a10195
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • Understanding DPDK

    2018-08-07 14:25:34
    Understanding DPDK,Understanding DPDK,Understanding DPDK
  • DPDK技术峰会讲稿分享,DPDK开发者大会讲稿分享,DPDK Accelerated Load Balancer 演讲者Lei CHEN @ IQIYI.com, DPVS: open source HIGH PERFORMANCE l4 Load balancer BASED ON DPDK DPVS是基于DPDK的高性能四层...
  • DPDK Cookbook

    2019-03-14 16:27:16
    Intel 28年开发经验的资深工程师写得ebook,作者从2009年就参与于DPDK开发,Cookbook介绍了DPDK入门方法,使用DPDK盒子作为流量生成器,提供了DPDK性能优化的建议,深入浅出,值得DPDK开发入门者学习或资深开发者...
  • DPDK技术峰会 PPT讲稿分享,DPDK开发者大会讲稿分享,文档讨论了中国及世界范围内DPDK社区及生态系统状态、关键方向:Opening – Heqing Zhu @ Intel
  • intel dpdk

    2017-12-20 16:31:00
    Intel内部DPDK培训文档, 详细说明DPDK的工作原理
  • DPDK技术峰会PPT讲稿分享,DPDK开发者大会讲稿分享,演讲者 胡兵全ARM Corp,演讲内容 DPDK Multiple Sized Packet Buffer Pool,DPDK 多尺寸网络包内存池优化
  • dpdk document 17.05

    2021-07-29 18:00:02
    dpdk document 17.05
  • [done]DPDK Usability for OVS DPDK.pdf
  • dpdk-ans:DPDKDPDK本机TCPIP堆栈上的ANS(加速网络堆栈)
  • DPDK编程指南

    2018-07-19 11:26:10
    DPDK编程指南;DPDK编程指南;DPDK编程指南;DPDK编程指南
  • DPDK BPF

    2021-05-28 15:57:27
    DPDK BPF DPDK 自版本 18.05 已集成了 librte_bpf, 主要利用rte_eth_rx_burst/rte_eth_tx_burst 回调函数机制, 执行eBPF字节码. 当前支持以下特性: base eBPF ISA (except tail-pointer) JIT (x86_64 and arm64 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,310
精华内容 3,724
关键字:

DPDK