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动态加载的更多相关文章

  1. 动态库连接器–动态库链接信息(Mach-O文件格式和程序从加载到执行过程)

    section cmd 说明 举例 __text 主程序代码   __stubs 用于动态库链接的桩   __stub_helper 用于动态库链接的桩   __cstring 常亮字符串符号表描述信 ...

  2. dlib编译成静态库及被其它程序调用

    一.git下载:https://github.com/davisking/dlib 官网:http://dlib.net/ 二.vs中编译成静态库 1.在vs2015中创建静态库工程(vs2015以上 ...

  3. java编译通过,为什么运行却提示找不到或无法加载主类?

    java编译通过,为什么运行却提示找不到或无法加载主类? https://www.zhihu.com/question/36537093 这边提供一个关于程序中含有package关键字,使用“终端”运 ...

  4. (原)vs2013编译成静态库

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5477664.html 1. 在“属性”-“配置属性”-“常规”-“配置类型”里面设置“静态库(.lib ...

  5. Aandroid 图片加载库Glide 实战(一),初始,加载进阶到实践

    原文: http://blog.csdn.net/sk719887916/article/details/39989293 skay 初识Glide 为何使用 Glide? 有经验的 Android ...

  6. 今天遇到一件开心事,在eclipse编写的代码在命令窗口中编译后无法运行,提示 “错误: 找不到或无法加载主类”

    java中带package和不带package的编译运行方式是不同的. 首先来了解一下package的概念:简单定义为,package是一个为了方便管理组织java文件的目录结构,并防止不同java文 ...

  7. NDK下 将Platinum SDK 编译成so库 (android - upnp)

    Platinum UPnP SDK 是一个跨平台的C++库,利用该库,可以很容易就构建出DLNA/UPnP控制点(DLNA/UPnP Control Point)和DLNA/UPnP设备(DLNA/U ...

  8. Cmake编译成静态库

    To build OpenCV as static library you need to set BUILD_SHARED_LIBS flag to false/off: cmake -DBUILD ...

  9. 后台返回平铺数据,如何转换成树形json并渲染树形结构,ant tree 异步加载

    如何后台返回对象数组(平铺式) 1.根据字段标识(板块)获取根节点 ### initTreeData(dataOrg){ var resultArr=dataOrg[0] var secArr=[]; ...

随机推荐

  1. AutoMapper,对象映射的简单使用

    using AutoMapper; using AutoMapper.Configuration; using System; using System.Collections.Generic; us ...

  2. TP支持菜单动态生成RBAC权限系统数据库结构设计方案

    最简单基于RBAC权限系统数据库结构设计 包括如下几个表 1. 用户表 -- Table "t_user" DDL CREATE TABLE `t_user` ( `id` int ...

  3. java Filter过滤器例外URL设置

    在web.xml声明的一个filter中: <!– session过滤filter –> <filter> <filter-name>SessionFilter&l ...

  4. PyCharm 2018 最新激活方式总结(最新最全最有效!!!)

    PyCharm 2018 最新激活方式总结(最新最全最有效!!!) 欲善其事,必先利其器.这里我为大家提供了三种激活方式: 授权服务器激活:适合小白,一步到位,但服务器容易被封 激活码激活:适合小白, ...

  5. [Node.js] 01 - How to learn node.js

    基本概念 链接:https://www.zhihu.com/question/47244505/answer/105026648 链接:How to decide when to use Node.j ...

  6. 【GIS】Vue esri-leaflet

    1.npm install esri-leaflet --save 2.引入包 import Leaflet from "leaflet"; var esri = require( ...

  7. Oracle迁移至PostgreSQL工具之Ora2Pg

    1. 描述 Ora2Pg是一个免费的工具,用于将Oracle数据库迁移到PostgreSQL兼容的模式.它连接您的Oracle数据库,自动扫描并提取它的结构或数据,然后生成可以装载到PostgreSQ ...

  8. 浅谈JAVA中HashMap、ArrayList、StringBuilder等的扩容机制

    JAVA中的部分需要扩容的内容总结如下:第一部分: HashMap<String, String> hmap=new HashMap<>(); HashSet<Strin ...

  9. Qt编写echart仪表盘JS交互程序支持webkit和webengine(开源)

    Echart是百度研发团队开发的一款报表视图JS插件,功能十分强大,是本人用过的国产作品中最牛逼的,记得四五年前就在qt中使用过,当时用的浏览器控件是webkit,由于5.6以后的版本不再支持webk ...

  10. css3整理--Animation

    animation语法: 1.动画的定义 @keyframes IDENT { from { Properties:Properties value; } Percentage { Propertie ...