目录
helloworld源代码
helloword编译
helloworld代码解析
DPDK的helloworld示例程序,用以示例DPDK应用程序的编写和使用。
helloworld源代码
helloworld代码构成:
/* 省略系统头文件*/
/* DPDK相关的rte头文件 */
#include <rte_memory.h>
#include <rte_launch.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_debug.h>
static int
lcore_hello(__attribute__((unused)) void *arg)
{
unsigned lcore_id;
lcore_id = rte_lcore_id();
printf("hello from core %u\n", lcore_id);
return 0;
}
int
main(int argc, char **argv)
{
int ret;
unsigned lcore_id;
ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_panic("Cannot init EAL\n");
/* call lcore_hello() on every slave lcore */
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
rte_eal_remote_launch(lcore_hello, NULL, lcore_id);
}
/* call it on master lcore too */
lcore_hello(NULL);
rte_eal_mp_wait_lcore();
return 0;
}
helloword编译
在hellowworld目录下Makefile文件
/home/user/dpdk-stable-18.11.11/examples/helloworld
[root@localhost helloworld]# ls
build main.c Makefile meson.build
使用DPDK的环境编译过程如下:
$ cd examples/helloworld/
$ export RTE_SDK="/home/user/dpdk-stable-18.11.11"
$ export RTE_TARGET="build"
$ make
CC main.o
LD helloworld
INSTALL-APP helloworld
INSTALL-MAP helloworld.map
解析DPDK编译helloworld的过程
Makefile里主要涉及到的实现文件为:
/home/user/dpdk-stable-18.11.11/mk/rte.app.mk
rte.app.mk文件内必要的include文件为
include $(RTE_SDK)/mk/internal/rte.compile-pre.mk
include $(RTE_SDK)/mk/internal/rte.build-pre.mk
将编译命令打印出来如下:
rte.compile-pre.mk文件里的C_TO_O_DO将源文件main.c生成目标文件main.o
# gcc -Wp,-MD,./.main.o.d.tmp -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/wq/dpdk-stable-18.11.11/examples/helloworld/build/include -I/home/wq/dpdk-stable-18.11.11//build/include -include /home/wq/dpdk-stable-18.11.11//build/include/rte_config.h -D_GNU_SOURCE -O3 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wdeprecated -Wno-address-of-packed-member -o main.o -c main.c && if grep -q 'RTE_PMD_REGISTER_.*(.*)' main.c; then echo " PMDINFO main.o.pmd.c" && /home/wq/dpdk-stable-18.11.11//build/app/dpdk-pmdinfogen main.o main.o.pmd.c && echo " CC main.o.pmd.o" && gcc -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/wq/dpdk-stable-18.11.11/examples/helloworld/build/include -I/home/wq/dpdk-stable-18.11.11//build/include -include /home/wq/dpdk-stable-18.11.11//build/include/rte_config.h -D_GNU_SOURCE -O3 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wdeprecated -Wno-address-of-packed-member -c -o main.o.pmd.o main.o.pmd.c && echo " LD main.o" && ld -r -L/home/wq/dpdk-stable-18.11.11/examples/helloworld/build/lib -L/home/wq/dpdk-stable-18.11.11//build/lib --as-needed -o main.o.o main.o.pmd.o main.o && mv -f main.o.o main.o; fi && /home/wq/dpdk-stable-18.11.11//buildtools/check-experimental-syms.sh /home/wq/dpdk-stable-18.11.11/examples/helloworld/ main.o && echo 'cmd_main.o = gcc -Wp,-MD,./.main.o.d.tmp -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/wq/dpdk-stable-18.11.11/examples/helloworld/build/include -I/home/wq/dpdk-stable-18.11.11//build/include -include /home/wq/dpdk-stable-18.11.11//build/include/rte_config.h -D_GNU_SOURCE -O3 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wdeprecated -Wno-address-of-packed-member -o main.o -c main.c ' > ./.main.o.cmd && sed 's,'main.o':,dep_'main.o' =,' ./.main.o.d.tmp > ./.main.o.d && rm -f ./.main.o.d.tmp
rte.app.mk文件里的O_TO_EXE_DO将目标文件main.o链接成可执行文件helloworld
# gcc -o helloworld -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/wq/dpdk-stable-18.11.11/examples/helloworld/build/include -I/home/wq/dpdk-stable-18.11.11//build/include -include /home/wq/dpdk-stable-18.11.11//build/include/rte_config.h -D_GNU_SOURCE -O3 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wdeprecated -Wno-address-of-packed-member main.o -L/home/wq/dpdk-stable-18.11.11//build/lib -Wl,-lrte_flow_classify -Wl,--whole-archive -Wl,-lrte_pipeline -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_table -Wl,--no-whole-archive -Wl,--whole-archive -Wl,-lrte_port -Wl,--no-whole-archive -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_metrics -Wl,-lrte_bitratestats -Wl,-lrte_latencystats -Wl,-lrte_power -Wl,-lrte_efd -Wl,-lrte_bpf -Wl,--whole-archive -Wl,-lrte_cfgfile -Wl,-lrte_gro -Wl,-lrte_gso -Wl,-lrte_hash -Wl,-lrte_member -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_bbdev -Wl,-lrte_cryptodev -Wl,-lrte_security -Wl,-lrte_compressdev -Wl,-lrte_eventdev -Wl,-lrte_rawdev -Wl,-lrte_timer -Wl,-lrte_mempool -Wl,-lrte_mempool_ring -Wl,-lrte_ring -Wl,-lrte_pci -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_reorder -Wl,-lrte_sched -Wl,-lrte_kni -Wl,-lrte_common_cpt -Wl,-lrte_common_octeontx -Wl,-lrte_common_dpaax -Wl,-lrte_bus_pci -Wl,-lrte_bus_vdev -Wl,-lrte_bus_dpaa -Wl,-lrte_bus_fslmc -Wl,-lrte_mempool_bucket -Wl,-lrte_mempool_stack -Wl,-lrte_mempool_dpaa -Wl,-lrte_mempool_dpaa2 -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_ark -Wl,-lrte_pmd_atlantic -Wl,-lrte_pmd_avf -Wl,-lrte_pmd_avp -Wl,-lrte_pmd_axgbe -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_dpaa -Wl,-lrte_pmd_dpaa2 -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enetc -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_failsafe -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_kni -Wl,-lrte_pmd_lio -Wl,-lrte_pmd_nfp -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_softnic -Wl,-lrte_pmd_sfc_efx -Wl,-lrte_pmd_tap -Wl,-lrte_pmd_thunderx_nicvf -Wl,-lrte_pmd_vdev_netvsc -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_ifc -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_bus_vmbus -Wl,-lrte_pmd_netvsc -Wl,-lrte_pmd_bbdev_null -Wl,-lrte_pmd_null_crypto -Wl,-lrte_pmd_qat -Wl,-lcrypto -Wl,-lrte_pmd_octeontx_crypto -Wl,-lrte_pmd_crypto_scheduler -Wl,-lrte_pmd_dpaa2_sec -Wl,-lrte_pmd_dpaa_sec -Wl,-lrte_pmd_caam_jr -Wl,-lrte_pmd_virtio_crypto -Wl,-lrte_pmd_octeontx_zip -Wl,-lrte_pmd_skeleton_event -Wl,-lrte_pmd_sw_event -Wl,-lrte_pmd_dsw_event -Wl,-lrte_pmd_octeontx_ssovf -Wl,-lrte_pmd_dpaa_event -Wl,-lrte_pmd_dpaa2_event -Wl,-lrte_mempool_octeontx -Wl,-lrte_pmd_octeontx -Wl,-lrte_pmd_opdl_event -Wl,-lrte_pmd_skeleton_rawdev -Wl,-lrte_pmd_dpaa2_cmdif -Wl,-lrte_pmd_dpaa2_qdma -Wl,-lrte_bus_ifpga -Wl,-lrte_pmd_ifpga_rawdev -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-lnuma -Wl,-ldl -Wl,-export-dynamic -Wl,-export-dynamic -L/home/wq/dpdk-stable-18.11.11/examples/helloworld/build/lib -L/home/wq/dpdk-stable-18.11.11//build/lib -Wl,--as-needed -Wl,-Map=helloworld.map -Wl,--cref
helloworld代码解析
helloworld示例代码用到的函数与之对应的链接库为
# ldd helloworld
linux-vdso.so.1 => (0x00007ffe319d4000)
libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007fc8a3e39000)
librt.so.1 => /lib64/librt.so.1 (0x00007fc8a3c31000)
libm.so.6 => /lib64/libm.so.6 (0x00007fc8a392f000)
libnuma.so.1 => /lib64/libnuma.so.1 (0x00007fc8a3723000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fc8a351f000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fc8a3303000)
libc.so.6 => /lib64/libc.so.6 (0x00007fc8a2f35000)
libz.so.1 => /lib64/libz.so.1 (0x00007fc8a2d1f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc8a429c000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fc8a2b09000)
上述ldd helloworld没找到与rte相关的动态链接库,那么helloworld示例程序用到DPDK相关的库都是静态库链接成的,根据调用的函数接口找到对应的静态链接库如下
rte_eal_init —— build/lib/librte_eal.a —— librte_eal/bsdapp/eal/eal.c
rte_eal_remote_launch —— build/lib/librte_eal.a —— lib/librte_eal/bsdapp/eal/eal_thread.c
rte_eal_mp_wait_lcore —— build/lib/librte_eal.a —— lib/librte_eal/common/eal_common_launch.c
代码运行关键流程解析:
如上图所示,helloworld示例程序所做的内容如下:
1、rte_eal_init EAL环境初始化,包括系统资源初始化和创建线程等
2、rte_eal_remote_launch调度执行各线程的入口函数
3、rte_eal_mp_wait_lcore等待各线程执行完毕