[dpdk] dpdk编译成动态库使用 -- PCI port自动发现与pmd动态加载
1. 修改配置文件 .conf, 设置如下变量的值.
[root@D129 x86_64-native-linuxapp-gcc]# cat dpdk/x86_64-native-linuxapp-gcc/.config |grep SHARE
CONFIG_RTE_BUILD_SHARED_LIB=y
2. 这个时候, 再编译的 dpdk app就会自动链接dpdk的动态库. 如下:
[root@D129 app]# ldd testpmd
linux-vdso.so. => (0x00007ffed89fd000)
librte_kni.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_kni.so. (0x00007fe9c983f000)
librte_pipeline.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_pipeline.so. (0x00007fe9c962b000)
librte_table.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_table.so. (0x00007fe9c93ed000)
librte_port.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_port.so. (0x00007fe9c9191000)
librte_pdump.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_pdump.so. (0x00007fe9c8d77000)
librte_distributor.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_distributor.so. (0x00007fe9c8b74000)
librte_reorder.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_reorder.so. (0x00007fe9c8965000)
librte_ip_frag.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_ip_frag.so. (0x00007fe9c8724000)
librte_meter.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_meter.so. (0x00007fe9c8521000)
librte_sched.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_sched.so. (0x00007fe9c830d000)
librte_lpm.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_lpm.so. (0x00007fe9c80ff000)
librte_acl.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_acl.so. (0x00007fe9c7ee5000)
librte_jobstats.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_jobstats.so. (0x00007fe9c7ce2000)
librte_power.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_power.so. (0x00007fe9c7acd000)
librte_timer.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_timer.so. (0x00007fe9c78c3000)
librte_hash.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_hash.so. (0x00007fe9c76af000)
librte_vhost.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_vhost.so. (0x00007fe9c7477000)
librte_kvargs.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_kvargs.so. (0x00007fe9c7274000)
librte_mbuf.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_mbuf.so. (0x00007fe9c7071000)
libethdev.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/libethdev.so. (0x00007fe9c6dd6000)
librte_cryptodev.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_cryptodev.so. (0x00007fe9c6bc1000)
librte_mempool.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_mempool.so. (0x00007fe9c69b9000)
librte_ring.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_ring.so. (0x00007fe9c67b5000)
librte_eal.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_eal.so. (0x00007fe9c6546000)
librte_cmdline.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_cmdline.so. (0x00007fe9c633b000)
librte_cfgfile.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_cfgfile.so. (0x00007fe9c6137000)
librte_pmd_bond.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_pmd_bond.so. (0x00007fe9c5efa000)
libgcc_s.so. => /lib64/libgcc_s.so. (0x00007fe9c5cd9000)
libdl.so. => /lib64/libdl.so. (0x00007fe9c5ad4000)
libpthread.so. => /lib64/libpthread.so. (0x00007fe9c58b8000)
libc.so. => /lib64/libc.so. (0x00007fe9c54f5000)
/lib64/ld-linux-x86-.so. (0x00007fe9c9a51000)
libm.so. => /lib64/libm.so. (0x00007fe9c51f2000)
librt.so. => /lib64/librt.so. (0x00007fe9c4fea000)
[root@D129 app]#
3. 但是与static的时候对比, 你会发现有如下的问题:
用static链接的时候, rte_init的时候,会扫描所有的PCI设备,找到所有可用的port, 如下:
[root@D129 app]# ./testpmd
EAL: Detected lcore(s)
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: PCI device 0000:00:03.0 on NUMA socket -1
EAL: probe driver: 1af4:1000 rte_virtio_pmd
EAL: PCI device 0000:00:04.0 on NUMA socket -1
EAL: probe driver: 1af4:1000 rte_virtio_pmd
USER1: create a new mbuf pool <mbuf_pool_socket_0>: n=, size=, socket=
RING: Cannot reserve memory
EAL: Error - exiting with code:
Cause: Creation of mbuf pool for socket failed: Cannot allocate memory
[root@D129 app]#
在使用shared so库的时候, 会发现,dpdk app扫描不到任何 PCI 设备了. 如下:
[root@D129 app]# ./testpmd
EAL: Detected lcore(s)
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: No probed ethernet devices
USER1: create a new mbuf pool <mbuf_pool_socket_0>: n=, size=, socket=
RING: Cannot reserve memory
EAL: Error - exiting with code:
Cause: Creation of mbuf pool for socket failed: Cannot allocate memory
这个时候,我们ldd app,会发现, 它并没有ld到pmd的so,
[root@D129 app]# ldd testpmd |grep pmd
librte_pmd_bond.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_pmd_bond.so. (0x00007fa25689a000)
[root@D129 app]#
猜测, dpdk在shared的情况下, pmd的库,是需要动态加载的. 并找到如下参数:
[root@D129 app]# ./testpmd -h |grep -A1 LIB.so
-d LIB.so|DIR Add a driver or driver directory
(can be used multiple times)
使用 -d 参数制定 virtio的so, (我的虚拟机是virtio的网络设备), 果然生效了
[root@D129 app]# ./testpmd -d ../lib/librte_pmd_virtio.so
EAL: Detected lcore(s)
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: PCI device ::03.0 on NUMA socket -
EAL: probe driver: 1af4: rte_virtio_pmd
EAL: PCI device ::04.0 on NUMA socket -
EAL: probe driver: 1af4: rte_virtio_pmd
USER1: create a new mbuf pool <mbuf_pool_socket_0>: n=, size=, socket=
RING: Cannot reserve memory
EAL: Error - exiting with code:
Cause: Creation of mbuf pool for socket failed: Cannot allocate memory
[root@D129 app]#
4. 问题分析
参考 dpdk 的源码 ../dpdk/lib/librte_eal/common/eal_common_options.c::eal_plugins_init()
在读取 -d 参数的同时, dpdk在 rte_init函数中还会读取 RTE_EAL_PMD_PATH 目录下的文件, 所有读到的文件会使用 dlopen() 打开. 详细逻辑参见代码.
变量RTE_EAL_PMD_PATH的值由CONFIG_RTE_EAL_PMD_PATH在编译的时候决定.
5. 参考redhat的rpm spec, 最终的解决方案是这样的.
5.1 生成一个编译与运行时都存在的目录: /lib64/tong-dpdk-pmds/,
5.2 将所以pmd软链接到这个目录下
[root@D129 app]# ll /lib64/tong-dpdk-pmds/
total
lrwxrwxrwx root root Jul : librte_pmd_af_packet.so. -> ../librte_pmd_af_packet.so.
lrwxrwxrwx root root Jul : librte_pmd_bnxt.so. -> ../librte_pmd_bnxt.so.
lrwxrwxrwx root root Jul : librte_pmd_bond.so. -> ../librte_pmd_bond.so.
lrwxrwxrwx root root Jul : librte_pmd_cxgbe.so. -> ../librte_pmd_cxgbe.so.
lrwxrwxrwx root root Jul : librte_pmd_e1000.so. -> ../librte_pmd_e1000.so.
lrwxrwxrwx root root Jul : librte_pmd_ena.so. -> ../librte_pmd_ena.so.
lrwxrwxrwx root root Jul : librte_pmd_enic.so. -> ../librte_pmd_enic.so.
lrwxrwxrwx root root Jul : librte_pmd_fm10k.so. -> ../librte_pmd_fm10k.so.
lrwxrwxrwx root root Jul : librte_pmd_i40e.so. -> ../librte_pmd_i40e.so.
lrwxrwxrwx root root Jul : librte_pmd_ixgbe.so. -> ../librte_pmd_ixgbe.so.
lrwxrwxrwx root root Jul : librte_pmd_null_crypto.so. -> ../librte_pmd_null_crypto.so.
lrwxrwxrwx root root Jul : librte_pmd_null.so. -> ../librte_pmd_null.so.
lrwxrwxrwx root root Jul : librte_pmd_ring.so. -> ../librte_pmd_ring.so.
lrwxrwxrwx root root Jul : librte_pmd_vhost.so. -> ../librte_pmd_vhost.so.
lrwxrwxrwx root root Jul : librte_pmd_virtio.so. -> ../librte_pmd_virtio.so.
lrwxrwxrwx root root Jul : librte_pmd_vmxnet3_uio.so. -> ../librte_pmd_vmxnet3_uio.so.
5.2 在编译前, 设置变量CONFIG_RTE_EAL_PMD_PATH
[root@D129 app]# cat ../.config |grep PATH
CONFIG_RTE_EAL_PMD_PATH="/lib64/tong-dpdk-pmds/"
以上, dpdk app便可以使用 shared lib 正常运行了.
6. 另一个方案: 使用 -d, 需要神马加神马, 比如:
[root@D129 app]# ./testpmd -d ../lib/librte_pmd_virtio.so -d ../lib/librte_pmd_ixgbe.so
完.
[dpdk] dpdk编译成动态库使用 -- PCI port自动发现与pmd动态加载的更多相关文章
- 动态库连接器–动态库链接信息(Mach-O文件格式和程序从加载到执行过程)
section cmd 说明 举例 __text 主程序代码 __stubs 用于动态库链接的桩 __stub_helper 用于动态库链接的桩 __cstring 常亮字符串符号表描述信 ...
- dlib编译成静态库及被其它程序调用
一.git下载:https://github.com/davisking/dlib 官网:http://dlib.net/ 二.vs中编译成静态库 1.在vs2015中创建静态库工程(vs2015以上 ...
- java编译通过,为什么运行却提示找不到或无法加载主类?
java编译通过,为什么运行却提示找不到或无法加载主类? https://www.zhihu.com/question/36537093 这边提供一个关于程序中含有package关键字,使用“终端”运 ...
- (原)vs2013编译成静态库
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5477664.html 1. 在“属性”-“配置属性”-“常规”-“配置类型”里面设置“静态库(.lib ...
- Aandroid 图片加载库Glide 实战(一),初始,加载进阶到实践
原文: http://blog.csdn.net/sk719887916/article/details/39989293 skay 初识Glide 为何使用 Glide? 有经验的 Android ...
- 今天遇到一件开心事,在eclipse编写的代码在命令窗口中编译后无法运行,提示 “错误: 找不到或无法加载主类”
java中带package和不带package的编译运行方式是不同的. 首先来了解一下package的概念:简单定义为,package是一个为了方便管理组织java文件的目录结构,并防止不同java文 ...
- NDK下 将Platinum SDK 编译成so库 (android - upnp)
Platinum UPnP SDK 是一个跨平台的C++库,利用该库,可以很容易就构建出DLNA/UPnP控制点(DLNA/UPnP Control Point)和DLNA/UPnP设备(DLNA/U ...
- Cmake编译成静态库
To build OpenCV as static library you need to set BUILD_SHARED_LIBS flag to false/off: cmake -DBUILD ...
- 后台返回平铺数据,如何转换成树形json并渲染树形结构,ant tree 异步加载
如何后台返回对象数组(平铺式) 1.根据字段标识(板块)获取根节点 ### initTreeData(dataOrg){ var resultArr=dataOrg[0] var secArr=[]; ...
随机推荐
- AutoMapper,对象映射的简单使用
using AutoMapper; using AutoMapper.Configuration; using System; using System.Collections.Generic; us ...
- TP支持菜单动态生成RBAC权限系统数据库结构设计方案
最简单基于RBAC权限系统数据库结构设计 包括如下几个表 1. 用户表 -- Table "t_user" DDL CREATE TABLE `t_user` ( `id` int ...
- java Filter过滤器例外URL设置
在web.xml声明的一个filter中: <!– session过滤filter –> <filter> <filter-name>SessionFilter&l ...
- PyCharm 2018 最新激活方式总结(最新最全最有效!!!)
PyCharm 2018 最新激活方式总结(最新最全最有效!!!) 欲善其事,必先利其器.这里我为大家提供了三种激活方式: 授权服务器激活:适合小白,一步到位,但服务器容易被封 激活码激活:适合小白, ...
- [Node.js] 01 - How to learn node.js
基本概念 链接:https://www.zhihu.com/question/47244505/answer/105026648 链接:How to decide when to use Node.j ...
- 【GIS】Vue esri-leaflet
1.npm install esri-leaflet --save 2.引入包 import Leaflet from "leaflet"; var esri = require( ...
- Oracle迁移至PostgreSQL工具之Ora2Pg
1. 描述 Ora2Pg是一个免费的工具,用于将Oracle数据库迁移到PostgreSQL兼容的模式.它连接您的Oracle数据库,自动扫描并提取它的结构或数据,然后生成可以装载到PostgreSQ ...
- 浅谈JAVA中HashMap、ArrayList、StringBuilder等的扩容机制
JAVA中的部分需要扩容的内容总结如下:第一部分: HashMap<String, String> hmap=new HashMap<>(); HashSet<Strin ...
- Qt编写echart仪表盘JS交互程序支持webkit和webengine(开源)
Echart是百度研发团队开发的一款报表视图JS插件,功能十分强大,是本人用过的国产作品中最牛逼的,记得四五年前就在qt中使用过,当时用的浏览器控件是webkit,由于5.6以后的版本不再支持webk ...
- css3整理--Animation
animation语法: 1.动画的定义 @keyframes IDENT { from { Properties:Properties value; } Percentage { Propertie ...