目录
2.2.2.rte_eal_mp_remote_launch()
3.1.1.rte_eth_dev_count_avail()
3.1.2.rte_pktmbuf_pool_create()
3.1.4.rte_eth_dev_adjust_nb_rx_tx_desc()
3.1.5.rte_eth_rx_queue_setup()
3.1.6.rte_eth_tx_queue_setup()
3.1.8.rte_eth_promiscuous_enable()
1.运行dpdk必要条件
在dpdk官网手册中已经明确了运行dpdk程序所需要的条件,链接如下:
System Requirements — Data Plane Development Kit 25.03.0-rc0 documentationhttp://doc.dpdk.org/guides/linux_gsg/sys_reqs.html
1.1.内核版本要求
内核版本至少 >= 4.19,内核版本可以使用 uname -r 命令查看。
1.2.glibc版本要求
glibc版本至少 >= 2.7,具体版本可以使用 ldd --version 命令查看。
1.3.大页内存要求
关于大页内存的配置可以使用dpdk官网提供的dpdk-hugepages.py脚本进行设置,也可以使用命令设置大页内存,设置完成后使用命令 cat /proc/meminfo | grep Huge 应该可以看到具体的大页内存信息。
1.4. 网卡驱动绑定要求
如果需要使用dpdk抓包,则还需要将对应的网卡pcie地址绑定到igb_uio驱动上,使用命令 lspci | grep Eth 可以看到当前设备所有的pcie地址,然后使用dpdk官网提供的dpdk-devbind.py脚本来绑定网卡。
注:在前面的章节提到了dpdk模式和内核模式的区别,网口正常情况下是处于内核态模式的,此时我们使用ifconfig命令可以看到网口;但是当我们需要使用dpdk抓包时,将其绑定到igb_uio驱动,此时网口被dpdk接管,无法使用ifconfig命令看到网口,需要使用dpdk-devbind.py脚本查看,命令:./dpdk-devbind.py -s。(mlnx网卡较为特殊,不需要执行此步骤)
可以看到,有6个网口被dpdk接管,有1个网口mgmt还是使用的内核驱动。
2.简单的示例程序
其实dpdk本身在examples目录实现了很多dpdk的示例程序,方便大家学习参考。
2.1.hello world示例程序
这里简单写了一个示例程序,供大家学习参考:
源码如下:
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <pthread.h>
#include <bits/pthreadtypes.h>
#include "rte_lcore.h"
#include "rte_eal.h"
#include "rte_ethdev.h"
#include "rte_malloc.h"
void lcore_main_loop() {
while (1) {
printf("Hello world!, This is main lcore:%u!\n", rte_lcore_id());
sleep(1);
}
}
void lcore_rx_loop() {
while (1) {
printf("Hello world!, This is rx lcore:%u!\n", rte_lcore_id());
sleep(1);
}
}
/* Launch a function on lcore. 8< */
static int every_lcore_loop(void *arg) {
uint16_t lcore_id = rte_lcore_id();
if (lcore_id == rte_get_main_lcore()) {
lcore_main_loop();
}else {
lcore_rx_loop();
}
return 0;
}
/* >8 End of launching function on lcore. */
/* Initialization of Environment Abstraction Layer (EAL). 8< */
int main(int argc, char **argv) {
int ret;
ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_panic("Cannot init EAL\n");
printf("Total core num:%u\n", rte_lcore_count());
/* Launches the function on each lcore. 8< */
rte_eal_mp_remote_launch(every_lcore_loop, NULL, CALL_MAIN);
/* >8 End of launching the function on each lcore. */
unsigned char lcore_id = 0;
RTE_LCORE_FOREACH_WORKER(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0) {
break;
}
}
/* clean up the EAL */
rte_eal_cleanup();
return 0;
}
2.2.关键的接口
2.2.1.rte_eal_init()
初始化平台的接口,主要作用是负责解析运行参数、设置大页内存、设置cpu亲和性、为每一个核心创建独立的线程、扫描pcie网卡设备等。
注:有兴趣的同学可以去看源码文件在 eal.c 中。
2.2.2.rte_eal_mp_remote_launch()
这个函数是dpdk中比较关键的部分,它为每一个核心提供函数入口,每一个逻辑核心都会回调此接口,可以类似的理解成创建线程的概念pthread_create()函数。
通过这个接口我们便可以根据传入的运行参数,来